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.pm.PackageManager.CERT_INPUT_RAW_X509;
28 import static android.content.pm.PackageManager.CERT_INPUT_SHA256;
29 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
30 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
31 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
32 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
33 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
34 import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
35 import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
36 import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
37 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
38 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
39 import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
40 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
41 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
42 import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
43 import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
44 import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
45 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
46 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
47 import static android.content.pm.PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID;
48 import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
49 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
50 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
51 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
52 import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
53 import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
54 import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
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.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
62 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
63 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
64 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
65 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
66 import static android.content.pm.PackageManager.MATCH_ALL;
67 import static android.content.pm.PackageManager.MATCH_ANY_USER;
68 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
69 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
70 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
71 import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
72 import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
73 import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES;
74 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
75 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
76 import static android.content.pm.PackageManager.MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL;
77 import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN;
78 import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
79 import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
80 import static android.content.pm.PackageManager.MOVE_FAILED_LOCKED_USER;
81 import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
82 import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
83 import static android.content.pm.PackageManager.PERMISSION_DENIED;
84 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
85 import static android.content.pm.PackageParser.isApkFile;
86 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
87 import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
88 import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
89 import static android.system.OsConstants.O_CREAT;
90 import static android.system.OsConstants.O_RDWR;
92 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
93 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
94 import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
95 import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
96 import static com.android.internal.util.ArrayUtils.appendInt;
97 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
98 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
99 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
100 import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
101 import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
102 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
103 import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures;
104 import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists;
105 import static com.android.server.pm.PackageManagerServiceUtils.decompressFile;
106 import static com.android.server.pm.PackageManagerServiceUtils.deriveAbiOverride;
107 import static com.android.server.pm.PackageManagerServiceUtils.dumpCriticalInfo;
108 import static com.android.server.pm.PackageManagerServiceUtils.getCompressedFiles;
109 import static com.android.server.pm.PackageManagerServiceUtils.getLastModifiedTime;
110 import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
111 import static com.android.server.pm.PackageManagerServiceUtils.verifySignatures;
112 import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_FAILURE;
113 import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_SUCCESS;
114 import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
116 import android.Manifest;
117 import android.annotation.IntDef;
118 import android.annotation.NonNull;
119 import android.annotation.Nullable;
120 import android.annotation.UserIdInt;
121 import android.app.ActivityManager;
122 import android.app.ActivityManagerInternal;
123 import android.app.AppOpsManager;
124 import android.app.BroadcastOptions;
125 import android.app.IActivityManager;
126 import android.app.ResourcesManager;
127 import android.app.admin.IDevicePolicyManager;
128 import android.app.admin.SecurityLog;
129 import android.app.backup.IBackupManager;
130 import android.content.BroadcastReceiver;
131 import android.content.ComponentName;
132 import android.content.ContentResolver;
133 import android.content.Context;
134 import android.content.IIntentReceiver;
135 import android.content.Intent;
136 import android.content.IntentFilter;
137 import android.content.IntentSender;
138 import android.content.IntentSender.SendIntentException;
139 import android.content.ServiceConnection;
140 import android.content.pm.ActivityInfo;
141 import android.content.pm.ApplicationInfo;
142 import android.content.pm.AppsQueryHelper;
143 import android.content.pm.AuxiliaryResolveInfo;
144 import android.content.pm.ChangedPackages;
145 import android.content.pm.ComponentInfo;
146 import android.content.pm.FallbackCategoryProvider;
147 import android.content.pm.FeatureInfo;
148 import android.content.pm.IDexModuleRegisterCallback;
149 import android.content.pm.IOnPermissionsChangeListener;
150 import android.content.pm.IPackageDataObserver;
151 import android.content.pm.IPackageDeleteObserver;
152 import android.content.pm.IPackageDeleteObserver2;
153 import android.content.pm.IPackageInstallObserver2;
154 import android.content.pm.IPackageInstaller;
155 import android.content.pm.IPackageManager;
156 import android.content.pm.IPackageManagerNative;
157 import android.content.pm.IPackageMoveObserver;
158 import android.content.pm.IPackageStatsObserver;
159 import android.content.pm.InstantAppInfo;
160 import android.content.pm.InstantAppRequest;
161 import android.content.pm.InstantAppResolveInfo;
162 import android.content.pm.InstrumentationInfo;
163 import android.content.pm.IntentFilterVerificationInfo;
164 import android.content.pm.KeySet;
165 import android.content.pm.PackageCleanItem;
166 import android.content.pm.PackageInfo;
167 import android.content.pm.PackageInfoLite;
168 import android.content.pm.PackageInstaller;
169 import android.content.pm.PackageList;
170 import android.content.pm.PackageManager;
171 import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
172 import android.content.pm.PackageManagerInternal;
173 import android.content.pm.PackageManagerInternal.PackageListObserver;
174 import android.content.pm.PackageParser;
175 import android.content.pm.PackageParser.ActivityIntentInfo;
176 import android.content.pm.PackageParser.Package;
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.ServiceIntentInfo;
181 import android.content.pm.PackageParser.SigningDetails;
182 import android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion;
183 import android.content.pm.PackageStats;
184 import android.content.pm.PackageUserState;
185 import android.content.pm.ParceledListSlice;
186 import android.content.pm.PermissionGroupInfo;
187 import android.content.pm.PermissionInfo;
188 import android.content.pm.ProviderInfo;
189 import android.content.pm.ResolveInfo;
190 import android.content.pm.SELinuxUtil;
191 import android.content.pm.ServiceInfo;
192 import android.content.pm.SharedLibraryInfo;
193 import android.content.pm.Signature;
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.database.ContentObserver;
203 import android.graphics.Bitmap;
204 import android.hardware.display.DisplayManager;
205 import android.net.Uri;
206 import android.os.AsyncTask;
207 import android.os.Binder;
208 import android.os.Build;
209 import android.os.Bundle;
210 import android.os.Debug;
211 import android.os.Environment;
212 import android.os.Environment.UserEnvironment;
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.ParcelFileDescriptor;
220 import android.os.PatternMatcher;
221 import android.os.PersistableBundle;
222 import android.os.Process;
223 import android.os.RemoteCallbackList;
224 import android.os.RemoteException;
225 import android.os.ResultReceiver;
226 import android.os.SELinux;
227 import android.os.ServiceManager;
228 import android.os.ShellCallback;
229 import android.os.SystemClock;
230 import android.os.SystemProperties;
231 import android.os.Trace;
232 import android.os.UserHandle;
233 import android.os.UserManager;
234 import android.os.UserManagerInternal;
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.Settings.Global;
242 import android.provider.Settings.Secure;
243 import android.security.KeyStore;
244 import android.security.SystemKeyStore;
245 import android.service.pm.PackageServiceDumpProto;
246 import android.system.ErrnoException;
247 import android.system.Os;
248 import android.text.TextUtils;
249 import android.text.format.DateUtils;
250 import android.util.ArrayMap;
251 import android.util.ArraySet;
252 import android.util.Base64;
253 import android.util.ByteStringUtils;
254 import android.util.DisplayMetrics;
255 import android.util.EventLog;
256 import android.util.ExceptionUtils;
257 import android.util.Log;
258 import android.util.LogPrinter;
259 import android.util.LongSparseArray;
260 import android.util.LongSparseLongArray;
261 import android.util.MathUtils;
262 import android.util.PackageUtils;
263 import android.util.Pair;
264 import android.util.PrintStreamPrinter;
265 import android.util.Slog;
266 import android.util.SparseArray;
267 import android.util.SparseBooleanArray;
268 import android.util.SparseIntArray;
269 import android.util.TimingsTraceLog;
270 import android.util.Xml;
271 import android.util.jar.StrictJarFile;
272 import android.util.proto.ProtoOutputStream;
273 import android.view.Display;
275 import com.android.internal.R;
276 import com.android.internal.annotations.GuardedBy;
277 import com.android.internal.app.IMediaContainerService;
278 import com.android.internal.app.ResolverActivity;
279 import com.android.internal.content.NativeLibraryHelper;
280 import com.android.internal.content.PackageHelper;
281 import com.android.internal.logging.MetricsLogger;
282 import com.android.internal.os.IParcelFileDescriptorFactory;
283 import com.android.internal.os.SomeArgs;
284 import com.android.internal.os.Zygote;
285 import com.android.internal.telephony.CarrierAppUtils;
286 import com.android.internal.util.ArrayUtils;
287 import com.android.internal.util.ConcurrentUtils;
288 import com.android.internal.util.DumpUtils;
289 import com.android.internal.util.FastXmlSerializer;
290 import com.android.internal.util.IndentingPrintWriter;
291 import com.android.internal.util.Preconditions;
292 import com.android.internal.util.XmlUtils;
293 import com.android.server.AttributeCache;
294 import com.android.server.DeviceIdleController;
295 import com.android.server.EventLogTags;
296 import com.android.server.FgThread;
297 import com.android.server.IntentResolver;
298 import com.android.server.LocalServices;
299 import com.android.server.LockGuard;
300 import com.android.server.ServiceThread;
301 import com.android.server.SystemConfig;
302 import com.android.server.SystemServerInitThreadPool;
303 import com.android.server.Watchdog;
304 import com.android.server.net.NetworkPolicyManagerInternal;
305 import com.android.server.pm.Installer.InstallerException;
306 import com.android.server.pm.Settings.DatabaseVersion;
307 import com.android.server.pm.Settings.VersionInfo;
308 import com.android.server.pm.dex.ArtManagerService;
309 import com.android.server.pm.dex.DexLogger;
310 import com.android.server.pm.dex.DexManager;
311 import com.android.server.pm.dex.DexoptOptions;
312 import com.android.server.pm.dex.PackageDexUsage;
313 import com.android.server.pm.permission.BasePermission;
314 import com.android.server.pm.permission.DefaultPermissionGrantPolicy;
315 import com.android.server.pm.permission.DefaultPermissionGrantPolicy.DefaultPermissionGrantedCallback;
316 import com.android.server.pm.permission.PermissionManagerInternal;
317 import com.android.server.pm.permission.PermissionManagerInternal.PermissionCallback;
318 import com.android.server.pm.permission.PermissionManagerService;
319 import com.android.server.pm.permission.PermissionsState;
320 import com.android.server.pm.permission.PermissionsState.PermissionState;
321 import com.android.server.security.VerityUtils;
322 import com.android.server.storage.DeviceStorageMonitorInternal;
324 import dalvik.system.CloseGuard;
325 import dalvik.system.VMRuntime;
327 import libcore.io.IoUtils;
329 import org.xmlpull.v1.XmlPullParser;
330 import org.xmlpull.v1.XmlPullParserException;
331 import org.xmlpull.v1.XmlSerializer;
333 import java.io.BufferedOutputStream;
334 import java.io.ByteArrayInputStream;
335 import java.io.ByteArrayOutputStream;
337 import java.io.FileDescriptor;
338 import java.io.FileInputStream;
339 import java.io.FileOutputStream;
340 import java.io.FilenameFilter;
341 import java.io.IOException;
342 import java.io.PrintWriter;
343 import java.lang.annotation.Retention;
344 import java.lang.annotation.RetentionPolicy;
345 import java.nio.charset.StandardCharsets;
346 import java.security.DigestException;
347 import java.security.DigestInputStream;
348 import java.security.MessageDigest;
349 import java.security.NoSuchAlgorithmException;
350 import java.security.PublicKey;
351 import java.security.SecureRandom;
352 import java.security.cert.CertificateException;
353 import java.util.ArrayList;
354 import java.util.Arrays;
355 import java.util.Collection;
356 import java.util.Collections;
357 import java.util.Comparator;
358 import java.util.HashMap;
359 import java.util.HashSet;
360 import java.util.Iterator;
361 import java.util.LinkedHashSet;
362 import java.util.List;
363 import java.util.Map;
364 import java.util.Objects;
365 import java.util.Set;
366 import java.util.concurrent.CountDownLatch;
367 import java.util.concurrent.Future;
368 import java.util.concurrent.TimeUnit;
369 import java.util.concurrent.atomic.AtomicBoolean;
370 import java.util.concurrent.atomic.AtomicInteger;
371 import java.util.function.Predicate;
374 * Keep track of all those APKs everywhere.
376 * Internally there are two important locks:
378 * <li>{@link #mPackages} is used to guard all in-memory parsed package details
379 * and other related state. It is a fine-grained lock that should only be held
380 * momentarily, as it's one of the most contended locks in the system.
381 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
382 * operations typically involve heavy lifting of application data on disk. Since
383 * {@code installd} is single-threaded, and it's operations can often be slow,
384 * this lock should never be acquired while already holding {@link #mPackages}.
385 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
386 * holding {@link #mInstallLock}.
388 * Many internal methods rely on the caller to hold the appropriate locks, and
389 * this contract is expressed through method name suffixes:
391 * <li>fooLI(): the caller must hold {@link #mInstallLock}
392 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
393 * being modified must be frozen
394 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
395 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
398 * Because this class is very central to the platform's security; please run all
399 * CTS and unit tests whenever making modifications:
402 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
403 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
406 public class PackageManagerService extends IPackageManager.Stub
407 implements PackageSender {
408 static final String TAG = "PackageManager";
409 public static final boolean DEBUG_SETTINGS = false;
410 static final boolean DEBUG_PREFERRED = false;
411 static final boolean DEBUG_UPGRADE = false;
412 static final boolean DEBUG_DOMAIN_VERIFICATION = false;
413 private static final boolean DEBUG_BACKUP = false;
414 public static final boolean DEBUG_INSTALL = false;
415 public static final boolean DEBUG_REMOVE = false;
416 private static final boolean DEBUG_BROADCASTS = false;
417 private static final boolean DEBUG_SHOW_INFO = false;
418 private static final boolean DEBUG_PACKAGE_INFO = false;
419 private static final boolean DEBUG_INTENT_MATCHING = false;
420 public static final boolean DEBUG_PACKAGE_SCANNING = false;
421 private static final boolean DEBUG_VERIFY = false;
422 private static final boolean DEBUG_FILTERS = false;
423 public static final boolean DEBUG_PERMISSIONS = false;
424 private static final boolean DEBUG_SHARED_LIBRARIES = false;
425 public static final boolean DEBUG_COMPRESSION = Build.IS_DEBUGGABLE;
427 // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
428 // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
429 // user, but by default initialize to this.
430 public static final boolean DEBUG_DEXOPT = false;
432 private static final boolean DEBUG_ABI_SELECTION = false;
433 private static final boolean DEBUG_INSTANT = Build.IS_DEBUGGABLE;
434 private static final boolean DEBUG_TRIAGED_MISSING = false;
435 private static final boolean DEBUG_APP_DATA = false;
437 /** REMOVE. According to Svet, this was only used to reset permissions during development. */
438 static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
440 private static final boolean HIDE_EPHEMERAL_APIS = false;
442 private static final boolean ENABLE_FREE_CACHE_V2 =
443 SystemProperties.getBoolean("fw.free_cache_v2", true);
445 private static final int RADIO_UID = Process.PHONE_UID;
446 private static final int LOG_UID = Process.LOG_UID;
447 private static final int NFC_UID = Process.NFC_UID;
448 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
449 private static final int SHELL_UID = Process.SHELL_UID;
450 private static final int SE_UID = Process.SE_UID;
452 // Suffix used during package installation when copying/moving
453 // package apks to install directory.
454 private static final String INSTALL_PACKAGE_SUFFIX = "-";
456 static final int SCAN_NO_DEX = 1<<0;
457 static final int SCAN_UPDATE_SIGNATURE = 1<<1;
458 static final int SCAN_NEW_INSTALL = 1<<2;
459 static final int SCAN_UPDATE_TIME = 1<<3;
460 static final int SCAN_BOOTING = 1<<4;
461 static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<6;
462 static final int SCAN_REQUIRE_KNOWN = 1<<7;
463 static final int SCAN_MOVE = 1<<8;
464 static final int SCAN_INITIAL = 1<<9;
465 static final int SCAN_CHECK_ONLY = 1<<10;
466 static final int SCAN_DONT_KILL_APP = 1<<11;
467 static final int SCAN_IGNORE_FROZEN = 1<<12;
468 static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<13;
469 static final int SCAN_AS_INSTANT_APP = 1<<14;
470 static final int SCAN_AS_FULL_APP = 1<<15;
471 static final int SCAN_AS_VIRTUAL_PRELOAD = 1<<16;
472 static final int SCAN_AS_SYSTEM = 1<<17;
473 static final int SCAN_AS_PRIVILEGED = 1<<18;
474 static final int SCAN_AS_OEM = 1<<19;
475 static final int SCAN_AS_VENDOR = 1<<20;
476 static final int SCAN_AS_PRODUCT = 1<<21;
478 @IntDef(flag = true, prefix = { "SCAN_" }, value = {
480 SCAN_UPDATE_SIGNATURE,
484 SCAN_DELETE_DATA_ON_FAILURES,
491 SCAN_FIRST_BOOT_OR_UPGRADE,
494 SCAN_AS_VIRTUAL_PRELOAD,
496 @Retention(RetentionPolicy.SOURCE)
497 public @interface ScanFlags {}
499 private static final String STATIC_SHARED_LIB_DELIMITER = "_";
500 /** Extension of the compressed packages */
501 public final static String COMPRESSED_EXTENSION = ".gz";
502 /** Suffix of stub packages on the system partition */
503 public final static String STUB_SUFFIX = "-Stub";
505 private static final int[] EMPTY_INT_ARRAY = new int[0];
507 private static final int TYPE_UNKNOWN = 0;
508 private static final int TYPE_ACTIVITY = 1;
509 private static final int TYPE_RECEIVER = 2;
510 private static final int TYPE_SERVICE = 3;
511 private static final int TYPE_PROVIDER = 4;
512 @IntDef(prefix = { "TYPE_" }, value = {
519 @Retention(RetentionPolicy.SOURCE)
520 public @interface ComponentType {}
523 * Timeout (in milliseconds) after which the watchdog should declare that
524 * our handler thread is wedged. The usual default for such things is one
525 * minute but we sometimes do very lengthy I/O operations on this thread,
526 * such as installing multi-gigabyte applications, so ours needs to be longer.
528 static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes
531 * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
532 * be run on this device. We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
533 * settings entry if available, otherwise we use the hardcoded default. If it's been
534 * more than this long since the last fstrim, we force one during the boot sequence.
536 * This backstops other fstrim scheduling: if the device is alive at midnight+idle,
537 * one gets run at the next available charging+idle time. This final mandatory
538 * no-fstrim check kicks in only of the other scheduling criteria is never met.
540 private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
543 * Whether verification is enabled by default.
545 private static final boolean DEFAULT_VERIFY_ENABLE = true;
548 * The default maximum time to wait for the verification agent to return in
551 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
554 * The default response for package verification timeout.
556 * This can be either PackageManager.VERIFICATION_ALLOW or
557 * PackageManager.VERIFICATION_REJECT.
559 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
561 public static final String PLATFORM_PACKAGE_NAME = "android";
563 public static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
565 public static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
566 DEFAULT_CONTAINER_PACKAGE,
567 "com.android.defcontainer.DefaultContainerService");
569 private static final String KILL_APP_REASON_GIDS_CHANGED =
570 "permission grant or revoke changed gids";
572 private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
573 "permissions revoked";
575 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
577 private static final String PACKAGE_SCHEME = "package";
579 private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
581 private static final String PRODUCT_OVERLAY_DIR = "/product/overlay";
583 /** Canonical intent used to identify what counts as a "web browser" app */
584 private static final Intent sBrowserIntent;
586 sBrowserIntent = new Intent();
587 sBrowserIntent.setAction(Intent.ACTION_VIEW);
588 sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
589 sBrowserIntent.setData(Uri.parse("http:"));
590 sBrowserIntent.addFlags(Intent.FLAG_IGNORE_EPHEMERAL);
594 * The set of all protected actions [i.e. those actions for which a high priority
595 * intent filter is disallowed].
597 private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
599 PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
600 PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
601 PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
602 PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
605 // Compilation reasons.
606 public static final int REASON_UNKNOWN = -1;
607 public static final int REASON_FIRST_BOOT = 0;
608 public static final int REASON_BOOT = 1;
609 public static final int REASON_INSTALL = 2;
610 public static final int REASON_BACKGROUND_DEXOPT = 3;
611 public static final int REASON_AB_OTA = 4;
612 public static final int REASON_INACTIVE_PACKAGE_DOWNGRADE = 5;
613 public static final int REASON_SHARED = 6;
615 public static final int REASON_LAST = REASON_SHARED;
618 * Version number for the package parser cache. Increment this whenever the format or
619 * extent of cached data changes. See {@code PackageParser#setCacheDir}.
621 private static final String PACKAGE_PARSER_CACHE_VERSION = "1";
624 * Whether the package parser cache is enabled.
626 private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
629 * Permissions required in order to receive instant application lifecycle broadcasts.
631 private static final String[] INSTANT_APP_BROADCAST_PERMISSION =
632 new String[] { android.Manifest.permission.ACCESS_INSTANT_APPS };
634 final ServiceThread mHandlerThread;
636 final PackageHandler mHandler;
638 private final ProcessLoggingHandler mProcessLoggingHandler;
641 * Messages for {@link #mHandler} that need to wait for system ready before
644 private ArrayList<Message> mPostSystemReadyMessages;
646 final int mSdkVersion = Build.VERSION.SDK_INT;
648 final Context mContext;
649 final boolean mFactoryTest;
650 final boolean mOnlyCore;
651 final DisplayMetrics mMetrics;
652 final int mDefParseFlags;
653 final String[] mSeparateProcesses;
654 final boolean mIsUpgrade;
655 final boolean mIsPreNUpgrade;
656 final boolean mIsPreNMR1Upgrade;
658 // Have we told the Activity Manager to whitelist the default container service by uid yet?
659 @GuardedBy("mPackages")
660 boolean mDefaultContainerWhitelisted = false;
662 @GuardedBy("mPackages")
663 private boolean mDexOptDialogShown;
665 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
666 // LOCK HELD. Can be called with mInstallLock held.
667 @GuardedBy("mInstallLock")
668 final Installer mInstaller;
670 /** Directory where installed applications are stored */
671 private static final File sAppInstallDir =
672 new File(Environment.getDataDirectory(), "app");
673 /** Directory where installed application's 32-bit native libraries are copied. */
674 private static final File sAppLib32InstallDir =
675 new File(Environment.getDataDirectory(), "app-lib");
676 /** Directory where code and non-resource assets of forward-locked applications are stored */
677 private static final File sDrmAppPrivateInstallDir =
678 new File(Environment.getDataDirectory(), "app-private");
680 // ----------------------------------------------------------------
682 // Lock for state used when installing and doing other long running
683 // operations. Methods that must be called with this lock held have
685 final Object mInstallLock = new Object();
687 // ----------------------------------------------------------------
689 // Keys are String (package name), values are Package. This also serves
690 // as the lock for the global state. Methods that must be called with
691 // this lock held have the prefix "LP".
692 @GuardedBy("mPackages")
693 final ArrayMap<String, PackageParser.Package> mPackages =
694 new ArrayMap<String, PackageParser.Package>();
696 final ArrayMap<String, Set<String>> mKnownCodebase =
697 new ArrayMap<String, Set<String>>();
699 // Keys are isolated uids and values are the uid of the application
700 // that created the isolated proccess.
701 @GuardedBy("mPackages")
702 final SparseIntArray mIsolatedOwners = new SparseIntArray();
705 * Tracks new system packages [received in an OTA] that we expect to
706 * find updated user-installed versions. Keys are package name, values
707 * are package location.
709 final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
711 * Tracks high priority intent filters for protected actions. During boot, certain
712 * filter actions are protected and should never be allowed to have a high priority
713 * intent filter for them. However, there is one, and only one exception -- the
714 * setup wizard. It must be able to define a high priority intent filter for these
715 * actions to ensure there are no escapes from the wizard. We need to delay processing
716 * of these during boot as we need to look at all of the system packages in order
717 * to know which component is the setup wizard.
719 private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
721 * Whether or not processing protected filters should be deferred.
723 private boolean mDeferProtectedFilters = true;
726 * Tracks existing system packages prior to receiving an OTA. Keys are package name.
728 final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
730 * Whether or not system app permissions should be promoted from install to runtime.
732 boolean mPromoteSystemApps;
734 @GuardedBy("mPackages")
735 final Settings mSettings;
738 * Set of package names that are currently "frozen", which means active
739 * surgery is being done on the code/data for that package. The platform
740 * will refuse to launch frozen packages to avoid race conditions.
742 * @see PackageFreezer
744 @GuardedBy("mPackages")
745 final ArraySet<String> mFrozenPackages = new ArraySet<>();
747 final ProtectedPackages mProtectedPackages;
749 @GuardedBy("mLoadedVolumes")
750 final ArraySet<String> mLoadedVolumes = new ArraySet<>();
754 PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
756 @GuardedBy("mAvailableFeatures")
757 final ArrayMap<String, FeatureInfo> mAvailableFeatures;
759 private final InstantAppRegistry mInstantAppRegistry;
761 @GuardedBy("mPackages")
762 int mChangedPackagesSequenceNumber;
764 * List of changed [installed, removed or updated] packages.
765 * mapping from user id -> sequence number -> package name
767 @GuardedBy("mPackages")
768 final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>();
770 * The sequence number of the last change to a package.
771 * mapping from user id -> package name -> sequence number
773 @GuardedBy("mPackages")
774 final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
776 @GuardedBy("mPackages")
777 final private ArraySet<PackageListObserver> mPackageListObservers = new ArraySet<>();
779 class PackageParserCallback implements PackageParser.Callback {
780 @Override public final boolean hasFeature(String feature) {
781 return PackageManagerService.this.hasSystemFeature(feature, 0);
784 final List<PackageParser.Package> getStaticOverlayPackages(
785 Collection<PackageParser.Package> allPackages, String targetPackageName) {
786 if ("android".equals(targetPackageName)) {
787 // Static RROs targeting to "android", ie framework-res.apk, are already applied by
788 // native AssetManager.
792 List<PackageParser.Package> overlayPackages = null;
793 for (PackageParser.Package p : allPackages) {
794 if (targetPackageName.equals(p.mOverlayTarget) && p.mOverlayIsStatic) {
795 if (overlayPackages == null) {
796 overlayPackages = new ArrayList<PackageParser.Package>();
798 overlayPackages.add(p);
801 if (overlayPackages != null) {
802 Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
803 public int compare(PackageParser.Package p1, PackageParser.Package p2) {
804 return p1.mOverlayPriority - p2.mOverlayPriority;
807 Collections.sort(overlayPackages, cmp);
809 return overlayPackages;
812 final String[] getStaticOverlayPaths(List<PackageParser.Package> overlayPackages,
814 if (overlayPackages == null || overlayPackages.isEmpty()) {
817 List<String> overlayPathList = null;
818 for (PackageParser.Package overlayPackage : overlayPackages) {
819 if (targetPath == null) {
820 if (overlayPathList == null) {
821 overlayPathList = new ArrayList<String>();
823 overlayPathList.add(overlayPackage.baseCodePath);
828 // Creates idmaps for system to parse correctly the Android manifest of the
831 // OverlayManagerService will update each of them with a correct gid from its
832 // target package app id.
833 mInstaller.idmap(targetPath, overlayPackage.baseCodePath,
834 UserHandle.getSharedAppGid(
835 UserHandle.getUserGid(UserHandle.USER_SYSTEM)));
836 if (overlayPathList == null) {
837 overlayPathList = new ArrayList<String>();
839 overlayPathList.add(overlayPackage.baseCodePath);
840 } catch (InstallerException e) {
841 Slog.e(TAG, "Failed to generate idmap for " + targetPath + " and " +
842 overlayPackage.baseCodePath);
845 return overlayPathList == null ? null : overlayPathList.toArray(new String[0]);
848 String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
849 List<PackageParser.Package> overlayPackages;
850 synchronized (mInstallLock) {
851 synchronized (mPackages) {
852 overlayPackages = getStaticOverlayPackages(
853 mPackages.values(), targetPackageName);
855 // It is safe to keep overlayPackages without holding mPackages because static overlay
856 // packages can't be uninstalled or disabled.
857 return getStaticOverlayPaths(overlayPackages, targetPath);
861 @Override public final String[] getOverlayApks(String targetPackageName) {
862 return getStaticOverlayPaths(targetPackageName, null);
865 @Override public final String[] getOverlayPaths(String targetPackageName,
867 return getStaticOverlayPaths(targetPackageName, targetPath);
871 class ParallelPackageParserCallback extends PackageParserCallback {
872 List<PackageParser.Package> mOverlayPackages = null;
874 void findStaticOverlayPackages() {
875 synchronized (mPackages) {
876 for (PackageParser.Package p : mPackages.values()) {
877 if (p.mOverlayIsStatic) {
878 if (mOverlayPackages == null) {
879 mOverlayPackages = new ArrayList<PackageParser.Package>();
881 mOverlayPackages.add(p);
888 synchronized String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
889 // We can trust mOverlayPackages without holding mPackages because package uninstall
890 // can't happen while running parallel parsing.
891 // And we can call mInstaller inside getStaticOverlayPaths without holding mInstallLock
892 // because mInstallLock is held before running parallel parsing.
893 // Moreover holding mPackages or mInstallLock on each parsing thread causes dead-lock.
894 return mOverlayPackages == null ? null :
895 getStaticOverlayPaths(
896 getStaticOverlayPackages(mOverlayPackages, targetPackageName),
901 final PackageParser.Callback mPackageParserCallback = new PackageParserCallback();
902 final ParallelPackageParserCallback mParallelPackageParserCallback =
903 new ParallelPackageParserCallback();
905 public static final class SharedLibraryEntry {
906 public final @Nullable String path;
907 public final @Nullable String apk;
908 public final @NonNull SharedLibraryInfo info;
910 SharedLibraryEntry(String _path, String _apk, String name, long version, int type,
911 String declaringPackageName, long declaringPackageVersionCode) {
914 info = new SharedLibraryInfo(name, version, type, new VersionedPackage(
915 declaringPackageName, declaringPackageVersionCode), null);
919 // Currently known shared libraries.
920 final ArrayMap<String, LongSparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>();
921 final ArrayMap<String, LongSparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage =
924 // All available activities, for your resolving pleasure.
925 final ActivityIntentResolver mActivities =
926 new ActivityIntentResolver();
928 // All available receivers, for your resolving pleasure.
929 final ActivityIntentResolver mReceivers =
930 new ActivityIntentResolver();
932 // All available services, for your resolving pleasure.
933 final ServiceIntentResolver mServices = new ServiceIntentResolver();
935 // All available providers, for your resolving pleasure.
936 final ProviderIntentResolver mProviders = new ProviderIntentResolver();
938 // Mapping from provider base names (first directory in content URI codePath)
939 // to the provider information.
940 final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
941 new ArrayMap<String, PackageParser.Provider>();
943 // Mapping from instrumentation class names to info about them.
944 final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
945 new ArrayMap<ComponentName, PackageParser.Instrumentation>();
947 // Packages whose data we have transfered into another package, thus
948 // should no longer exist.
949 final ArraySet<String> mTransferedPackages = new ArraySet<String>();
951 // Broadcast actions that are only available to the system.
952 @GuardedBy("mProtectedBroadcasts")
953 final ArraySet<String> mProtectedBroadcasts = new ArraySet<>();
955 /** List of packages waiting for verification. */
956 final SparseArray<PackageVerificationState> mPendingVerification
957 = new SparseArray<PackageVerificationState>();
959 final PackageInstallerService mInstallerService;
961 final ArtManagerService mArtManagerService;
963 private final PackageDexOptimizer mPackageDexOptimizer;
964 // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
965 // is used by other apps).
966 private final DexManager mDexManager;
968 private AtomicInteger mNextMoveId = new AtomicInteger();
969 private final MoveCallbacks mMoveCallbacks;
971 private final OnPermissionChangeListeners mOnPermissionChangeListeners;
973 // Cache of users who need badging.
974 SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
976 /** Token for keys in mPendingVerification. */
977 private int mPendingVerificationToken = 0;
979 volatile boolean mSystemReady;
980 volatile boolean mSafeMode;
981 volatile boolean mHasSystemUidErrors;
982 private volatile boolean mWebInstantAppsDisabled;
984 ApplicationInfo mAndroidApplication;
985 final ActivityInfo mResolveActivity = new ActivityInfo();
986 final ResolveInfo mResolveInfo = new ResolveInfo();
987 ComponentName mResolveComponentName;
988 PackageParser.Package mPlatformPackage;
989 ComponentName mCustomResolverComponentName;
991 boolean mResolverReplaced = false;
993 private final @Nullable ComponentName mIntentFilterVerifierComponent;
994 private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
996 private int mIntentFilterVerificationToken = 0;
998 /** The service connection to the ephemeral resolver */
999 final InstantAppResolverConnection mInstantAppResolverConnection;
1000 /** Component used to show resolver settings for Instant Apps */
1001 final ComponentName mInstantAppResolverSettingsComponent;
1003 /** Activity used to install instant applications */
1004 ActivityInfo mInstantAppInstallerActivity;
1005 final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
1007 final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
1008 = new SparseArray<IntentFilterVerificationState>();
1010 // TODO remove this and go through mPermissonManager directly
1011 final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
1012 private final PermissionManagerInternal mPermissionManager;
1014 // List of packages names to keep cached, even if they are uninstalled for all users
1015 private List<String> mKeepUninstalledPackages;
1017 private UserManagerInternal mUserManagerInternal;
1018 private ActivityManagerInternal mActivityManagerInternal;
1020 private DeviceIdleController.LocalService mDeviceIdleController;
1022 private File mCacheDir;
1024 private Future<?> mPrepareAppDataFuture;
1026 private static class IFVerificationParams {
1027 PackageParser.Package pkg;
1032 public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
1033 int _userId, int _verifierUid) {
1035 replacing = _replacing;
1037 replacing = _replacing;
1038 verifierUid = _verifierUid;
1042 private interface IntentFilterVerifier<T extends IntentFilter> {
1043 boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
1044 T filter, String packageName);
1045 void startVerifications(int userId);
1046 void receiveVerificationResponse(int verificationId);
1049 private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
1050 private Context mContext;
1051 private ComponentName mIntentFilterVerifierComponent;
1052 private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
1054 public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
1056 mIntentFilterVerifierComponent = verifierComponent;
1059 private String getDefaultScheme() {
1060 return IntentFilter.SCHEME_HTTPS;
1064 public void startVerifications(int userId) {
1065 // Launch verifications requests
1066 int count = mCurrentIntentFilterVerifications.size();
1067 for (int n=0; n<count; n++) {
1068 int verificationId = mCurrentIntentFilterVerifications.get(n);
1069 final IntentFilterVerificationState ivs =
1070 mIntentFilterVerificationStates.get(verificationId);
1072 String packageName = ivs.getPackageName();
1074 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1075 final int filterCount = filters.size();
1076 ArraySet<String> domainsSet = new ArraySet<>();
1077 for (int m=0; m<filterCount; m++) {
1078 PackageParser.ActivityIntentInfo filter = filters.get(m);
1079 domainsSet.addAll(filter.getHostsList());
1081 synchronized (mPackages) {
1082 if (mSettings.createIntentFilterVerificationIfNeededLPw(
1083 packageName, domainsSet) != null) {
1084 scheduleWriteSettingsLocked();
1087 sendVerificationRequest(verificationId, ivs);
1089 mCurrentIntentFilterVerifications.clear();
1092 private void sendVerificationRequest(int verificationId, IntentFilterVerificationState ivs) {
1093 Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
1094 verificationIntent.putExtra(
1095 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
1097 verificationIntent.putExtra(
1098 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
1099 getDefaultScheme());
1100 verificationIntent.putExtra(
1101 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
1102 ivs.getHostsString());
1103 verificationIntent.putExtra(
1104 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
1105 ivs.getPackageName());
1106 verificationIntent.setComponent(mIntentFilterVerifierComponent);
1107 verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
1109 final long whitelistTimeout = getVerificationTimeout();
1110 final BroadcastOptions options = BroadcastOptions.makeBasic();
1111 options.setTemporaryAppWhitelistDuration(whitelistTimeout);
1113 DeviceIdleController.LocalService idleController = getDeviceIdleController();
1114 idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
1115 mIntentFilterVerifierComponent.getPackageName(), whitelistTimeout,
1116 UserHandle.USER_SYSTEM, true, "intent filter verifier");
1118 mContext.sendBroadcastAsUser(verificationIntent, UserHandle.SYSTEM);
1119 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1120 "Sending IntentFilter verification broadcast");
1123 public void receiveVerificationResponse(int verificationId) {
1124 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1126 final boolean verified = ivs.isVerified();
1128 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1129 final int count = filters.size();
1130 if (DEBUG_DOMAIN_VERIFICATION) {
1131 Slog.i(TAG, "Received verification response " + verificationId
1132 + " for " + count + " filters, verified=" + verified);
1134 for (int n=0; n<count; n++) {
1135 PackageParser.ActivityIntentInfo filter = filters.get(n);
1136 filter.setVerified(verified);
1138 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
1139 + " verified with result:" + verified + " and hosts:"
1140 + ivs.getHostsString());
1143 mIntentFilterVerificationStates.remove(verificationId);
1145 final String packageName = ivs.getPackageName();
1146 IntentFilterVerificationInfo ivi = null;
1148 synchronized (mPackages) {
1149 ivi = mSettings.getIntentFilterVerificationLPr(packageName);
1152 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
1153 + verificationId + " packageName:" + packageName);
1157 synchronized (mPackages) {
1159 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
1161 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
1163 scheduleWriteSettingsLocked();
1165 final int userId = ivs.getUserId();
1166 if (userId != UserHandle.USER_ALL) {
1167 final int userStatus =
1168 mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
1170 int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1171 boolean needUpdate = false;
1173 // In a success case, we promote from undefined or ASK to ALWAYS. This
1174 // supports a flow where the app fails validation but then ships an updated
1175 // APK that passes, and therefore deserves to be in ALWAYS.
1177 // If validation failed, the undefined state winds up in the basic ASK behavior,
1178 // but apps that previously passed and became ALWAYS are *demoted* out of
1179 // that state, since they would not deserve the ALWAYS behavior in case of a
1181 switch (userStatus) {
1182 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS:
1184 // Don't demote if sysconfig says 'always'
1185 SystemConfig systemConfig = SystemConfig.getInstance();
1186 ArraySet<String> packages = systemConfig.getLinkedApps();
1187 if (!packages.contains(packageName)) {
1188 // updatedStatus is already UNDEFINED
1191 if (DEBUG_DOMAIN_VERIFICATION) {
1192 Slog.d(TAG, "Formerly validated but now failing; demoting");
1195 if (DEBUG_DOMAIN_VERIFICATION) {
1196 Slog.d(TAG, "Updating bundled package " + packageName
1197 + " failed autoVerify, but sysconfig supersedes");
1199 // leave needUpdate == false here intentionally
1204 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
1205 // Stay in 'undefined' on verification failure
1207 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1210 if (DEBUG_DOMAIN_VERIFICATION) {
1211 Slog.d(TAG, "Applying update; old=" + userStatus
1212 + " new=" + updatedStatus);
1216 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
1217 // Keep in 'ask' on failure
1219 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1229 mSettings.updateIntentFilterVerificationStatusLPw(
1230 packageName, updatedStatus, userId);
1231 scheduleWritePackageRestrictionsLocked(userId);
1234 Slog.i(TAG, "autoVerify ignored when installing for all users");
1240 public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
1241 ActivityIntentInfo filter, String packageName) {
1242 if (!hasValidDomains(filter)) {
1245 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1247 ivs = createDomainVerificationState(verifierUid, userId, verificationId,
1250 if (DEBUG_DOMAIN_VERIFICATION) {
1251 Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
1253 ivs.addFilter(filter);
1257 private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
1258 int userId, int verificationId, String packageName) {
1259 IntentFilterVerificationState ivs = new IntentFilterVerificationState(
1260 verifierUid, userId, packageName);
1261 ivs.setPendingState();
1262 synchronized (mPackages) {
1263 mIntentFilterVerificationStates.append(verificationId, ivs);
1264 mCurrentIntentFilterVerifications.add(verificationId);
1270 private static boolean hasValidDomains(ActivityIntentInfo filter) {
1271 return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
1272 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
1273 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
1276 // Set of pending broadcasts for aggregating enable/disable of components.
1277 static class PendingPackageBroadcasts {
1278 // for each user id, a map of <package name -> components within that package>
1279 final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
1281 public PendingPackageBroadcasts() {
1282 mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
1285 public ArrayList<String> get(int userId, String packageName) {
1286 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1287 return packages.get(packageName);
1290 public void put(int userId, String packageName, ArrayList<String> components) {
1291 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1292 packages.put(packageName, components);
1295 public void remove(int userId, String packageName) {
1296 ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1297 if (packages != null) {
1298 packages.remove(packageName);
1302 public void remove(int userId) {
1303 mUidMap.remove(userId);
1306 public int userIdCount() {
1307 return mUidMap.size();
1310 public int userIdAt(int n) {
1311 return mUidMap.keyAt(n);
1314 public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1315 return mUidMap.get(userId);
1319 // total number of pending broadcast entries across all userIds
1321 for (int i = 0; i< mUidMap.size(); i++) {
1322 num += mUidMap.valueAt(i).size();
1327 public void clear() {
1331 private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1332 ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1334 map = new ArrayMap<String, ArrayList<String>>();
1335 mUidMap.put(userId, map);
1340 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1342 // Service Connection to remote media container service to copy
1343 // package uri's from external media onto secure containers
1344 // or internal storage.
1345 private IMediaContainerService mContainerService = null;
1347 static final int SEND_PENDING_BROADCAST = 1;
1348 static final int MCS_BOUND = 3;
1349 static final int END_COPY = 4;
1350 static final int INIT_COPY = 5;
1351 static final int MCS_UNBIND = 6;
1352 static final int START_CLEANING_PACKAGE = 7;
1353 static final int FIND_INSTALL_LOC = 8;
1354 static final int POST_INSTALL = 9;
1355 static final int MCS_RECONNECT = 10;
1356 static final int MCS_GIVE_UP = 11;
1357 static final int WRITE_SETTINGS = 13;
1358 static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1359 static final int PACKAGE_VERIFIED = 15;
1360 static final int CHECK_PENDING_VERIFICATION = 16;
1361 static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1362 static final int INTENT_FILTER_VERIFIED = 18;
1363 static final int WRITE_PACKAGE_LIST = 19;
1364 static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
1365 static final int DEF_CONTAINER_BIND = 21;
1367 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds
1369 // Delay time in millisecs
1370 static final int BROADCAST_DELAY = 10 * 1000;
1372 private static final long DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
1373 2 * 60 * 60 * 1000L; /* two hours */
1375 static UserManagerService sUserManager;
1377 // Stores a list of users whose package restrictions file needs to be updated
1378 private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1380 final private DefaultContainerConnection mDefContainerConn =
1381 new DefaultContainerConnection();
1382 class DefaultContainerConnection implements ServiceConnection {
1383 public void onServiceConnected(ComponentName name, IBinder service) {
1384 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1385 final IMediaContainerService imcs = IMediaContainerService.Stub
1386 .asInterface(Binder.allowBlocking(service));
1387 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1390 public void onServiceDisconnected(ComponentName name) {
1391 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1395 // Recordkeeping of restore-after-install operations that are currently in flight
1396 // between the Package Manager and the Backup Manager
1397 static class PostInstallData {
1398 public InstallArgs args;
1399 public PackageInstalledInfo res;
1401 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1407 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1408 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows
1410 // XML tags for backup/restore of various bits of state
1411 private static final String TAG_PREFERRED_BACKUP = "pa";
1412 private static final String TAG_DEFAULT_APPS = "da";
1413 private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1415 private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1416 private static final String TAG_ALL_GRANTS = "rt-grants";
1417 private static final String TAG_GRANT = "grant";
1418 private static final String ATTR_PACKAGE_NAME = "pkg";
1420 private static final String TAG_PERMISSION = "perm";
1421 private static final String ATTR_PERMISSION_NAME = "name";
1422 private static final String ATTR_IS_GRANTED = "g";
1423 private static final String ATTR_USER_SET = "set";
1424 private static final String ATTR_USER_FIXED = "fixed";
1425 private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1427 // System/policy permission grants are not backed up
1428 private static final int SYSTEM_RUNTIME_GRANT_MASK =
1429 FLAG_PERMISSION_POLICY_FIXED
1430 | FLAG_PERMISSION_SYSTEM_FIXED
1431 | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1433 // And we back up these user-adjusted states
1434 private static final int USER_RUNTIME_GRANT_MASK =
1435 FLAG_PERMISSION_USER_SET
1436 | FLAG_PERMISSION_USER_FIXED
1437 | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1439 final @Nullable String mRequiredVerifierPackage;
1440 final @NonNull String mRequiredInstallerPackage;
1441 final @NonNull String mRequiredUninstallerPackage;
1442 final @Nullable String mSetupWizardPackage;
1443 final @Nullable String mStorageManagerPackage;
1444 final @Nullable String mSystemTextClassifierPackage;
1445 final @NonNull String mServicesSystemSharedLibraryPackageName;
1446 final @NonNull String mSharedSystemSharedLibraryPackageName;
1448 private final PackageUsage mPackageUsage = new PackageUsage();
1449 private final CompilerStats mCompilerStats = new CompilerStats();
1451 class PackageHandler extends Handler {
1452 private boolean mBound = false;
1453 final ArrayList<HandlerParams> mPendingInstalls =
1454 new ArrayList<HandlerParams>();
1456 private boolean connectToService() {
1457 if (DEBUG_INSTALL) Log.i(TAG, "Trying to bind to DefaultContainerService");
1458 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1459 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1460 if (mContext.bindServiceAsUser(service, mDefContainerConn,
1461 Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1462 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1466 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1470 private void disconnectService() {
1471 mContainerService = null;
1473 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1474 mContext.unbindService(mDefContainerConn);
1475 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1478 PackageHandler(Looper looper) {
1482 public void handleMessage(Message msg) {
1484 doHandleMessage(msg);
1486 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1490 void doHandleMessage(Message msg) {
1492 case DEF_CONTAINER_BIND:
1494 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "earlyBindingMCS",
1495 System.identityHashCode(mHandler));
1496 if (!connectToService()) {
1497 Slog.e(TAG, "Failed to bind to media container service");
1499 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "earlyBindingMCS",
1500 System.identityHashCode(mHandler));
1504 HandlerParams params = (HandlerParams) msg.obj;
1505 int idx = mPendingInstalls.size();
1506 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1507 // If a bind was already initiated we dont really
1508 // need to do anything. The pending install
1509 // will be processed later on.
1511 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1512 System.identityHashCode(mHandler));
1513 // If this is the only one pending we might
1514 // have to bind to the service again.
1515 if (!connectToService()) {
1516 Slog.e(TAG, "Failed to bind to media container service");
1517 params.serviceError();
1518 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1519 System.identityHashCode(mHandler));
1520 if (params.traceMethod != null) {
1521 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1522 params.traceCookie);
1526 // Once we bind to the service, the first
1527 // pending request will be processed.
1528 mPendingInstalls.add(idx, params);
1531 mPendingInstalls.add(idx, params);
1532 // Already bound to the service. Just make
1533 // sure we trigger off processing the first request.
1535 mHandler.sendEmptyMessage(MCS_BOUND);
1541 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1542 if (msg.obj != null) {
1543 mContainerService = (IMediaContainerService) msg.obj;
1544 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1545 System.identityHashCode(mHandler));
1547 if (mContainerService == null) {
1549 // Something seriously wrong since we are not bound and we are not
1550 // waiting for connection. Bail out.
1551 Slog.e(TAG, "Cannot bind to media container service");
1552 for (HandlerParams params : mPendingInstalls) {
1553 // Indicate service bind error
1554 params.serviceError();
1555 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1556 System.identityHashCode(params));
1557 if (params.traceMethod != null) {
1558 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1559 params.traceMethod, params.traceCookie);
1562 mPendingInstalls.clear();
1564 Slog.w(TAG, "Waiting to connect to media container service");
1566 } else if (mPendingInstalls.size() > 0) {
1567 HandlerParams params = mPendingInstalls.get(0);
1568 if (params != null) {
1569 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1570 System.identityHashCode(params));
1571 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1572 if (params.startCopy()) {
1573 // We are done... look for more work or to
1575 if (DEBUG_SD_INSTALL) Log.i(TAG,
1576 "Checking for more work or unbind...");
1577 // Delete pending install
1578 if (mPendingInstalls.size() > 0) {
1579 mPendingInstalls.remove(0);
1581 if (mPendingInstalls.size() == 0) {
1583 if (DEBUG_SD_INSTALL) Log.i(TAG,
1584 "Posting delayed MCS_UNBIND");
1585 removeMessages(MCS_UNBIND);
1586 Message ubmsg = obtainMessage(MCS_UNBIND);
1587 // Unbind after a little delay, to avoid
1588 // continual thrashing.
1589 sendMessageDelayed(ubmsg, 10000);
1592 // There are more pending requests in queue.
1593 // Just post MCS_BOUND message to trigger processing
1594 // of next pending install.
1595 if (DEBUG_SD_INSTALL) Log.i(TAG,
1596 "Posting MCS_BOUND for next work");
1597 mHandler.sendEmptyMessage(MCS_BOUND);
1600 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1603 // Should never happen ideally.
1604 Slog.w(TAG, "Empty queue");
1608 case MCS_RECONNECT: {
1609 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1610 if (mPendingInstalls.size() > 0) {
1612 disconnectService();
1614 if (!connectToService()) {
1615 Slog.e(TAG, "Failed to bind to media container service");
1616 for (HandlerParams params : mPendingInstalls) {
1617 // Indicate service bind error
1618 params.serviceError();
1619 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1620 System.identityHashCode(params));
1622 mPendingInstalls.clear();
1628 // If there is no actual work left, then time to unbind.
1629 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1631 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1633 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1635 disconnectService();
1637 } else if (mPendingInstalls.size() > 0) {
1638 // There are more pending requests in queue.
1639 // Just post MCS_BOUND message to trigger processing
1640 // of next pending install.
1641 mHandler.sendEmptyMessage(MCS_BOUND);
1647 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1648 HandlerParams params = mPendingInstalls.remove(0);
1649 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1650 System.identityHashCode(params));
1653 case SEND_PENDING_BROADCAST: {
1655 ArrayList<String> components[];
1658 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1659 synchronized (mPackages) {
1660 if (mPendingBroadcasts == null) {
1663 size = mPendingBroadcasts.size();
1665 // Nothing to be done. Just return
1668 packages = new String[size];
1669 components = new ArrayList[size];
1670 uids = new int[size];
1671 int i = 0; // filling out the above arrays
1673 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1674 int packageUserId = mPendingBroadcasts.userIdAt(n);
1675 Iterator<Map.Entry<String, ArrayList<String>>> it
1676 = mPendingBroadcasts.packagesForUserId(packageUserId)
1677 .entrySet().iterator();
1678 while (it.hasNext() && i < size) {
1679 Map.Entry<String, ArrayList<String>> ent = it.next();
1680 packages[i] = ent.getKey();
1681 components[i] = ent.getValue();
1682 PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1683 uids[i] = (ps != null)
1684 ? UserHandle.getUid(packageUserId, ps.appId)
1690 mPendingBroadcasts.clear();
1693 for (int i = 0; i < size; i++) {
1694 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1696 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1699 case START_CLEANING_PACKAGE: {
1700 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1701 final String packageName = (String)msg.obj;
1702 final int userId = msg.arg1;
1703 final boolean andCode = msg.arg2 != 0;
1704 synchronized (mPackages) {
1705 if (userId == UserHandle.USER_ALL) {
1706 int[] users = sUserManager.getUserIds();
1707 for (int user : users) {
1708 mSettings.addPackageToCleanLPw(
1709 new PackageCleanItem(user, packageName, andCode));
1712 mSettings.addPackageToCleanLPw(
1713 new PackageCleanItem(userId, packageName, andCode));
1716 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1717 startCleaningPackages();
1719 case POST_INSTALL: {
1720 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1722 PostInstallData data = mRunningInstalls.get(msg.arg1);
1723 final boolean didRestore = (msg.arg2 != 0);
1724 mRunningInstalls.delete(msg.arg1);
1727 InstallArgs args = data.args;
1728 PackageInstalledInfo parentRes = data.res;
1730 final boolean grantPermissions = (args.installFlags
1731 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1732 final boolean killApp = (args.installFlags
1733 & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1734 final boolean virtualPreload = ((args.installFlags
1735 & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
1736 final String[] grantedPermissions = args.installGrantPermissions;
1738 // Handle the parent package
1739 handlePackagePostInstall(parentRes, grantPermissions, killApp,
1740 virtualPreload, grantedPermissions, didRestore,
1741 args.installerPackageName, args.observer);
1743 // Handle the child packages
1744 final int childCount = (parentRes.addedChildPackages != null)
1745 ? parentRes.addedChildPackages.size() : 0;
1746 for (int i = 0; i < childCount; i++) {
1747 PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1748 handlePackagePostInstall(childRes, grantPermissions, killApp,
1749 virtualPreload, grantedPermissions, false /*didRestore*/,
1750 args.installerPackageName, args.observer);
1753 // Log tracing if needed
1754 if (args.traceMethod != null) {
1755 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1759 Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1762 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1764 case WRITE_SETTINGS: {
1765 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1766 synchronized (mPackages) {
1767 removeMessages(WRITE_SETTINGS);
1768 removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1769 mSettings.writeLPr();
1770 mDirtyUsers.clear();
1772 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1774 case WRITE_PACKAGE_RESTRICTIONS: {
1775 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1776 synchronized (mPackages) {
1777 removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1778 for (int userId : mDirtyUsers) {
1779 mSettings.writePackageRestrictionsLPr(userId);
1781 mDirtyUsers.clear();
1783 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1785 case WRITE_PACKAGE_LIST: {
1786 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1787 synchronized (mPackages) {
1788 removeMessages(WRITE_PACKAGE_LIST);
1789 mSettings.writePackageListLPr(msg.arg1);
1791 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1793 case CHECK_PENDING_VERIFICATION: {
1794 final int verificationId = msg.arg1;
1795 final PackageVerificationState state = mPendingVerification.get(verificationId);
1797 if ((state != null) && !state.timeoutExtended()) {
1798 final InstallArgs args = state.getInstallArgs();
1799 final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1801 Slog.i(TAG, "Verification timed out for " + originUri);
1802 mPendingVerification.remove(verificationId);
1804 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1806 final UserHandle user = args.getUser();
1807 if (getDefaultVerificationResponse(user)
1808 == PackageManager.VERIFICATION_ALLOW) {
1809 Slog.i(TAG, "Continuing with installation of " + originUri);
1810 state.setVerifierResponse(Binder.getCallingUid(),
1811 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1812 broadcastPackageVerified(verificationId, originUri,
1813 PackageManager.VERIFICATION_ALLOW, user);
1815 ret = args.copyApk(mContainerService, true);
1816 } catch (RemoteException e) {
1817 Slog.e(TAG, "Could not contact the ContainerService");
1820 broadcastPackageVerified(verificationId, originUri,
1821 PackageManager.VERIFICATION_REJECT, user);
1824 Trace.asyncTraceEnd(
1825 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1827 processPendingInstall(args, ret);
1828 mHandler.sendEmptyMessage(MCS_UNBIND);
1832 case PACKAGE_VERIFIED: {
1833 final int verificationId = msg.arg1;
1835 final PackageVerificationState state = mPendingVerification.get(verificationId);
1836 if (state == null) {
1837 Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1841 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1843 state.setVerifierResponse(response.callerUid, response.code);
1845 if (state.isVerificationComplete()) {
1846 mPendingVerification.remove(verificationId);
1848 final InstallArgs args = state.getInstallArgs();
1849 final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1852 if (state.isInstallAllowed()) {
1853 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1854 broadcastPackageVerified(verificationId, originUri,
1855 response.code, state.getInstallArgs().getUser());
1857 ret = args.copyApk(mContainerService, true);
1858 } catch (RemoteException e) {
1859 Slog.e(TAG, "Could not contact the ContainerService");
1862 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1865 Trace.asyncTraceEnd(
1866 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1868 processPendingInstall(args, ret);
1869 mHandler.sendEmptyMessage(MCS_UNBIND);
1874 case START_INTENT_FILTER_VERIFICATIONS: {
1875 IFVerificationParams params = (IFVerificationParams) msg.obj;
1876 verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1877 params.replacing, params.pkg);
1880 case INTENT_FILTER_VERIFIED: {
1881 final int verificationId = msg.arg1;
1883 final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1885 if (state == null) {
1886 Slog.w(TAG, "Invalid IntentFilter verification token "
1887 + verificationId + " received");
1891 final int userId = state.getUserId();
1893 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1894 "Processing IntentFilter verification with token:"
1895 + verificationId + " and userId:" + userId);
1897 final IntentFilterVerificationResponse response =
1898 (IntentFilterVerificationResponse) msg.obj;
1900 state.setVerifierResponse(response.callerUid, response.code);
1902 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1903 "IntentFilter verification with token:" + verificationId
1904 + " and userId:" + userId
1905 + " is settings verifier response with response code:"
1908 if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1909 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1910 + response.getFailedDomainsString());
1913 if (state.isVerificationComplete()) {
1914 mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1916 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1917 "IntentFilter verification with token:" + verificationId
1918 + " was not said to be complete");
1923 case INSTANT_APP_RESOLUTION_PHASE_TWO: {
1924 InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
1925 mInstantAppResolverConnection,
1926 (InstantAppRequest) msg.obj,
1927 mInstantAppInstallerActivity,
1934 private PermissionCallback mPermissionCallback = new PermissionCallback() {
1936 public void onGidsChanged(int appId, int userId) {
1937 mHandler.post(new Runnable() {
1940 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
1945 public void onPermissionGranted(int uid, int userId) {
1946 mOnPermissionChangeListeners.onPermissionsChanged(uid);
1948 // Not critical; if this is lost, the application has to request again.
1949 synchronized (mPackages) {
1950 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
1954 public void onInstallPermissionGranted() {
1955 synchronized (mPackages) {
1956 scheduleWriteSettingsLocked();
1960 public void onPermissionRevoked(int uid, int userId) {
1961 mOnPermissionChangeListeners.onPermissionsChanged(uid);
1963 synchronized (mPackages) {
1964 // Critical; after this call the application should never have the permission
1965 mSettings.writeRuntimePermissionsForUserLPr(userId, true);
1968 final int appId = UserHandle.getAppId(uid);
1969 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
1972 public void onInstallPermissionRevoked() {
1973 synchronized (mPackages) {
1974 scheduleWriteSettingsLocked();
1978 public void onPermissionUpdated(int[] updatedUserIds, boolean sync) {
1979 synchronized (mPackages) {
1980 for (int userId : updatedUserIds) {
1981 mSettings.writeRuntimePermissionsForUserLPr(userId, sync);
1986 public void onInstallPermissionUpdated() {
1987 synchronized (mPackages) {
1988 scheduleWriteSettingsLocked();
1992 public void onPermissionRemoved() {
1993 synchronized (mPackages) {
1994 mSettings.writeLPr();
1999 private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
2000 boolean killApp, boolean virtualPreload, String[] grantedPermissions,
2001 boolean launchedForRestore, String installerPackage,
2002 IPackageInstallObserver2 installObserver) {
2003 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
2004 // Send the removed broadcasts
2005 if (res.removedInfo != null) {
2006 res.removedInfo.sendPackageRemovedBroadcasts(killApp);
2009 // Now that we successfully installed the package, grant runtime
2010 // permissions if requested before broadcasting the install. Also
2011 // for legacy apps in permission review mode we clear the permission
2012 // review flag which is used to emulate runtime permissions for
2014 if (grantPermissions) {
2015 final int callingUid = Binder.getCallingUid();
2016 mPermissionManager.grantRequestedRuntimePermissions(
2017 res.pkg, res.newUsers, grantedPermissions, callingUid,
2018 mPermissionCallback);
2021 final boolean update = res.removedInfo != null
2022 && res.removedInfo.removedPackage != null;
2023 final String installerPackageName =
2024 res.installerPackageName != null
2025 ? res.installerPackageName
2026 : res.removedInfo != null
2027 ? res.removedInfo.installerPackageName
2030 // If this is the first time we have child packages for a disabled privileged
2031 // app that had no children, we grant requested runtime permissions to the new
2032 // children if the parent on the system image had them already granted.
2033 if (res.pkg.parentPackage != null) {
2034 final int callingUid = Binder.getCallingUid();
2035 mPermissionManager.grantRuntimePermissionsGrantedToDisabledPackage(
2036 res.pkg, callingUid, mPermissionCallback);
2039 synchronized (mPackages) {
2040 mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
2043 final String packageName = res.pkg.applicationInfo.packageName;
2045 // Determine the set of users who are adding this package for
2046 // the first time vs. those who are seeing an update.
2047 int[] firstUserIds = EMPTY_INT_ARRAY;
2048 int[] firstInstantUserIds = EMPTY_INT_ARRAY;
2049 int[] updateUserIds = EMPTY_INT_ARRAY;
2050 int[] instantUserIds = EMPTY_INT_ARRAY;
2051 final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
2052 final PackageSetting ps = (PackageSetting) res.pkg.mExtras;
2053 for (int newUser : res.newUsers) {
2054 final boolean isInstantApp = ps.getInstantApp(newUser);
2057 firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
2059 firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
2063 boolean isNew = true;
2064 for (int origUser : res.origUsers) {
2065 if (origUser == newUser) {
2072 firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
2074 firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
2078 instantUserIds = ArrayUtils.appendInt(instantUserIds, newUser);
2080 updateUserIds = ArrayUtils.appendInt(updateUserIds, newUser);
2085 // Send installed broadcasts if the package is not a static shared lib.
2086 if (res.pkg.staticSharedLibName == null) {
2087 mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
2089 // Send added for users that see the package for the first time
2090 // sendPackageAddedForNewUsers also deals with system apps
2091 int appId = UserHandle.getAppId(res.uid);
2092 boolean isSystem = res.pkg.applicationInfo.isSystemApp();
2093 sendPackageAddedForNewUsers(packageName, isSystem || virtualPreload,
2094 virtualPreload /*startReceiver*/, appId, firstUserIds, firstInstantUserIds);
2096 // Send added for users that don't see the package for the first time
2097 Bundle extras = new Bundle(1);
2098 extras.putInt(Intent.EXTRA_UID, res.uid);
2100 extras.putBoolean(Intent.EXTRA_REPLACING, true);
2102 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2103 extras, 0 /*flags*/,
2104 null /*targetPackage*/, null /*finishedReceiver*/,
2105 updateUserIds, instantUserIds);
2106 if (installerPackageName != null) {
2107 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2108 extras, 0 /*flags*/,
2109 installerPackageName, null /*finishedReceiver*/,
2110 updateUserIds, instantUserIds);
2112 // if the required verifier is defined, but, is not the installer of record
2113 // for the package, it gets notified
2114 final boolean notifyVerifier = mRequiredVerifierPackage != null
2115 && !mRequiredVerifierPackage.equals(installerPackageName);
2116 if (notifyVerifier) {
2117 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2118 extras, 0 /*flags*/,
2119 mRequiredVerifierPackage, null /*finishedReceiver*/,
2120 updateUserIds, instantUserIds);
2123 // Send replaced for users that don't see the package for the first time
2125 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
2126 packageName, extras, 0 /*flags*/,
2127 null /*targetPackage*/, null /*finishedReceiver*/,
2128 updateUserIds, instantUserIds);
2129 if (installerPackageName != null) {
2130 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
2131 extras, 0 /*flags*/,
2132 installerPackageName, null /*finishedReceiver*/,
2133 updateUserIds, instantUserIds);
2135 if (notifyVerifier) {
2136 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
2137 extras, 0 /*flags*/,
2138 mRequiredVerifierPackage, null /*finishedReceiver*/,
2139 updateUserIds, instantUserIds);
2141 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
2142 null /*package*/, null /*extras*/, 0 /*flags*/,
2143 packageName /*targetPackage*/,
2144 null /*finishedReceiver*/, updateUserIds, instantUserIds);
2145 } else if (launchedForRestore && !isSystemApp(res.pkg)) {
2146 // First-install and we did a restore, so we're responsible for the
2147 // first-launch broadcast.
2149 Slog.i(TAG, "Post-restore of " + packageName
2150 + " sending FIRST_LAUNCH in " + Arrays.toString(firstUserIds));
2152 sendFirstLaunchBroadcast(packageName, installerPackage,
2153 firstUserIds, firstInstantUserIds);
2156 // Send broadcast package appeared if forward locked/external for all users
2157 // treat asec-hosted packages like removable media on upgrade
2158 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
2159 if (DEBUG_INSTALL) {
2160 Slog.i(TAG, "upgrading pkg " + res.pkg
2161 + " is ASEC-hosted -> AVAILABLE");
2163 final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
2164 ArrayList<String> pkgList = new ArrayList<>(1);
2165 pkgList.add(packageName);
2166 sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
2170 // Work that needs to happen on first install within each user
2171 if (firstUserIds != null && firstUserIds.length > 0) {
2172 synchronized (mPackages) {
2173 for (int userId : firstUserIds) {
2174 // If this app is a browser and it's newly-installed for some
2175 // users, clear any default-browser state in those users. The
2176 // app's nature doesn't depend on the user, so we can just check
2177 // its browser nature in any user and generalize.
2178 if (packageIsBrowser(packageName, userId)) {
2179 mSettings.setDefaultBrowserPackageNameLPw(null, userId);
2182 // We may also need to apply pending (restored) runtime
2183 // permission grants within these users.
2184 mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
2189 if (allNewUsers && !update) {
2190 notifyPackageAdded(packageName);
2193 // Log current value of "unknown sources" setting
2194 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
2195 getUnknownSourcesSettings());
2197 // Remove the replaced package's older resources safely now
2198 // We delete after a gc for applications on sdcard.
2199 if (res.removedInfo != null && res.removedInfo.args != null) {
2200 Runtime.getRuntime().gc();
2201 synchronized (mInstallLock) {
2202 res.removedInfo.args.doPostDeleteLI(true);
2205 // Force a gc to clear up things. Ask for a background one, it's fine to go on
2206 // and not block here.
2207 VMRuntime.getRuntime().requestConcurrentGC();
2210 // Notify DexManager that the package was installed for new users.
2211 // The updated users should already be indexed and the package code paths
2212 // should not change.
2213 // Don't notify the manager for ephemeral apps as they are not expected to
2214 // survive long enough to benefit of background optimizations.
2215 for (int userId : firstUserIds) {
2216 PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
2217 // There's a race currently where some install events may interleave with an uninstall.
2218 // This can lead to package info being null (b/36642664).
2220 mDexManager.notifyPackageInstalled(info, userId);
2225 // If someone is watching installs - notify them
2226 if (installObserver != null) {
2228 Bundle extras = extrasForInstallResult(res);
2229 installObserver.onPackageInstalled(res.name, res.returnCode,
2230 res.returnMsg, extras);
2231 } catch (RemoteException e) {
2232 Slog.i(TAG, "Observer no longer exists.");
2237 private StorageEventListener mStorageListener = new StorageEventListener() {
2239 public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
2240 if (vol.type == VolumeInfo.TYPE_PRIVATE) {
2241 if (vol.state == VolumeInfo.STATE_MOUNTED) {
2242 final String volumeUuid = vol.getFsUuid();
2244 // Clean up any users or apps that were removed or recreated
2245 // while this volume was missing
2246 sUserManager.reconcileUsers(volumeUuid);
2247 reconcileApps(volumeUuid);
2249 // Clean up any install sessions that expired or were
2250 // cancelled while this volume was missing
2251 mInstallerService.onPrivateVolumeMounted(volumeUuid);
2253 loadPrivatePackages(vol);
2255 } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2256 unloadPrivatePackages(vol);
2262 public void onVolumeForgotten(String fsUuid) {
2263 if (TextUtils.isEmpty(fsUuid)) {
2264 Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
2268 // Remove any apps installed on the forgotten volume
2269 synchronized (mPackages) {
2270 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
2271 for (PackageSetting ps : packages) {
2272 Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
2273 deletePackageVersioned(new VersionedPackage(ps.name,
2274 PackageManager.VERSION_CODE_HIGHEST),
2275 new LegacyPackageDeleteObserver(null).getBinder(),
2276 UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
2277 // Try very hard to release any references to this package
2278 // so we don't risk the system server being killed due to
2280 AttributeCache.instance().removePackage(ps.name);
2283 mSettings.onVolumeForgotten(fsUuid);
2284 mSettings.writeLPr();
2289 Bundle extrasForInstallResult(PackageInstalledInfo res) {
2290 Bundle extras = null;
2291 switch (res.returnCode) {
2292 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2293 extras = new Bundle();
2294 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2295 res.origPermission);
2296 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2300 case PackageManager.INSTALL_SUCCEEDED: {
2301 extras = new Bundle();
2302 extras.putBoolean(Intent.EXTRA_REPLACING,
2303 res.removedInfo != null && res.removedInfo.removedPackage != null);
2310 void scheduleWriteSettingsLocked() {
2311 if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2312 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2316 void scheduleWritePackageListLocked(int userId) {
2317 if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2318 Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2320 mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2324 void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2325 final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2326 scheduleWritePackageRestrictionsLocked(userId);
2329 void scheduleWritePackageRestrictionsLocked(int userId) {
2330 final int[] userIds = (userId == UserHandle.USER_ALL)
2331 ? sUserManager.getUserIds() : new int[]{userId};
2332 for (int nextUserId : userIds) {
2333 if (!sUserManager.exists(nextUserId)) return;
2334 mDirtyUsers.add(nextUserId);
2335 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2336 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2341 public static PackageManagerService main(Context context, Installer installer,
2342 boolean factoryTest, boolean onlyCore) {
2343 // Self-check for initial settings.
2344 PackageManagerServiceCompilerMapping.checkProperties();
2346 PackageManagerService m = new PackageManagerService(context, installer,
2347 factoryTest, onlyCore);
2348 m.enableSystemUserPackages();
2349 ServiceManager.addService("package", m);
2350 final PackageManagerNative pmn = m.new PackageManagerNative();
2351 ServiceManager.addService("package_native", pmn);
2355 private void enableSystemUserPackages() {
2356 if (!UserManager.isSplitSystemUser()) {
2359 // For system user, enable apps based on the following conditions:
2360 // - app is whitelisted or belong to one of these groups:
2361 // -- system app which has no launcher icons
2362 // -- system app which has INTERACT_ACROSS_USERS permission
2363 // -- system IME app
2364 // - app is not in the blacklist
2365 AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2366 Set<String> enableApps = new ArraySet<>();
2367 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2368 | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2369 | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2370 ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2371 enableApps.addAll(wlApps);
2372 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2373 /* systemAppsOnly */ false, UserHandle.SYSTEM));
2374 ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2375 enableApps.removeAll(blApps);
2376 Log.i(TAG, "Applications installed for system user: " + enableApps);
2377 List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2379 final int allAppsSize = allAps.size();
2380 synchronized (mPackages) {
2381 for (int i = 0; i < allAppsSize; i++) {
2382 String pName = allAps.get(i);
2383 PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2384 // Should not happen, but we shouldn't be failing if it does
2385 if (pkgSetting == null) {
2388 boolean install = enableApps.contains(pName);
2389 if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2390 Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2391 + " for system user");
2392 pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2395 scheduleWritePackageRestrictionsLocked(UserHandle.USER_SYSTEM);
2399 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2400 DisplayManager displayManager = (DisplayManager) context.getSystemService(
2401 Context.DISPLAY_SERVICE);
2402 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2406 * Requests that files preopted on a secondary system partition be copied to the data partition
2407 * if possible. Note that the actual copying of the files is accomplished by init for security
2408 * reasons. This simply requests that the copy takes place and awaits confirmation of its
2409 * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2411 private static void requestCopyPreoptedFiles() {
2412 final int WAIT_TIME_MS = 100;
2413 final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2414 if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2415 SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2416 // We will wait for up to 100 seconds.
2417 final long timeStart = SystemClock.uptimeMillis();
2418 final long timeEnd = timeStart + 100 * 1000;
2419 long timeNow = timeStart;
2420 while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2422 Thread.sleep(WAIT_TIME_MS);
2423 } catch (InterruptedException e) {
2426 timeNow = SystemClock.uptimeMillis();
2427 if (timeNow > timeEnd) {
2428 SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2429 Slog.wtf(TAG, "cppreopt did not finish!");
2434 Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2438 public PackageManagerService(Context context, Installer installer,
2439 boolean factoryTest, boolean onlyCore) {
2440 LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
2441 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
2442 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2443 SystemClock.uptimeMillis());
2445 if (mSdkVersion <= 0) {
2446 Slog.w(TAG, "**** ro.build.version.sdk not set!");
2451 mFactoryTest = factoryTest;
2452 mOnlyCore = onlyCore;
2453 mMetrics = new DisplayMetrics();
2454 mInstaller = installer;
2456 // Create sub-components that provide services / data. Order here is important.
2457 synchronized (mInstallLock) {
2458 synchronized (mPackages) {
2459 // Expose private service for system components to use.
2460 LocalServices.addService(
2461 PackageManagerInternal.class, new PackageManagerInternalImpl());
2462 sUserManager = new UserManagerService(context, this,
2463 new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
2464 mPermissionManager = PermissionManagerService.create(context,
2465 new DefaultPermissionGrantedCallback() {
2467 public void onDefaultRuntimePermissionsGranted(int userId) {
2468 synchronized(mPackages) {
2469 mSettings.onDefaultRuntimePermissionsGrantedLPr(userId);
2472 }, mPackages /*externalLock*/);
2473 mDefaultPermissionPolicy = mPermissionManager.getDefaultPermissionGrantPolicy();
2474 mSettings = new Settings(mPermissionManager.getPermissionSettings(), mPackages);
2477 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2478 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2479 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2480 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2481 mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2482 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2483 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2484 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2485 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2486 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2487 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2488 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2489 mSettings.addSharedUserLPw("android.uid.se", SE_UID,
2490 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2492 String separateProcesses = SystemProperties.get("debug.separate_processes");
2493 if (separateProcesses != null && separateProcesses.length() > 0) {
2494 if ("*".equals(separateProcesses)) {
2495 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2496 mSeparateProcesses = null;
2497 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2500 mSeparateProcesses = separateProcesses.split(",");
2501 Slog.w(TAG, "Running with debug.separate_processes: "
2502 + separateProcesses);
2506 mSeparateProcesses = null;
2509 mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2511 DexManager.Listener dexManagerListener = DexLogger.getListener(this,
2512 installer, mInstallLock);
2513 mDexManager = new DexManager(mContext, this, mPackageDexOptimizer, installer, mInstallLock,
2514 dexManagerListener);
2515 mArtManagerService = new ArtManagerService(mContext, this, installer, mInstallLock);
2516 mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2518 mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2519 FgThread.get().getLooper());
2521 getDefaultDisplayMetrics(context, mMetrics);
2523 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
2524 SystemConfig systemConfig = SystemConfig.getInstance();
2525 mAvailableFeatures = systemConfig.getAvailableFeatures();
2526 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2528 mProtectedPackages = new ProtectedPackages(mContext);
2530 synchronized (mInstallLock) {
2532 synchronized (mPackages) {
2533 mHandlerThread = new ServiceThread(TAG,
2534 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2535 mHandlerThread.start();
2536 mHandler = new PackageHandler(mHandlerThread.getLooper());
2537 mProcessLoggingHandler = new ProcessLoggingHandler();
2538 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2539 mInstantAppRegistry = new InstantAppRegistry(this);
2541 ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2542 final int builtInLibCount = libConfig.size();
2543 for (int i = 0; i < builtInLibCount; i++) {
2544 String name = libConfig.keyAt(i);
2545 String path = libConfig.valueAt(i);
2546 addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
2547 SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
2550 SELinuxMMAC.readInstallPolicy();
2552 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
2553 FallbackCategoryProvider.loadFallbacks();
2554 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2556 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
2557 mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2558 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2560 // Clean up orphaned packages for which the code path doesn't exist
2561 // and they are an update to a system app - caused by bug/32321269
2562 final int packageSettingCount = mSettings.mPackages.size();
2563 for (int i = packageSettingCount - 1; i >= 0; i--) {
2564 PackageSetting ps = mSettings.mPackages.valueAt(i);
2565 if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2566 && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2567 mSettings.mPackages.removeAt(i);
2568 mSettings.enableSystemPackageLPw(ps.name);
2573 requestCopyPreoptedFiles();
2576 String customResolverActivity = Resources.getSystem().getString(
2577 R.string.config_customResolverActivity);
2578 if (TextUtils.isEmpty(customResolverActivity)) {
2579 customResolverActivity = null;
2581 mCustomResolverComponentName = ComponentName.unflattenFromString(
2582 customResolverActivity);
2585 long startTime = SystemClock.uptimeMillis();
2587 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2590 final String bootClassPath = System.getenv("BOOTCLASSPATH");
2591 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2593 if (bootClassPath == null) {
2594 Slog.w(TAG, "No BOOTCLASSPATH found!");
2597 if (systemServerClassPath == null) {
2598 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2601 File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2603 final VersionInfo ver = mSettings.getInternalVersion();
2604 mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2606 logCriticalInfo(Log.INFO,
2607 "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
2610 // when upgrading from pre-M, promote system app permissions from install to runtime
2611 mPromoteSystemApps =
2612 mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2614 // When upgrading from pre-N, we need to handle package extraction like first boot,
2615 // as there is no profiling data available.
2616 mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2618 mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2620 // save off the names of pre-existing system packages prior to scanning; we don't
2621 // want to automatically grant runtime permissions for new system apps
2622 if (mPromoteSystemApps) {
2623 Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2624 while (pkgSettingIter.hasNext()) {
2625 PackageSetting ps = pkgSettingIter.next();
2626 if (isSystemApp(ps)) {
2627 mExistingSystemPackages.add(ps.name);
2632 mCacheDir = preparePackageParserCache(mIsUpgrade);
2634 // Set flag to monitor and not change apk file paths when
2635 // scanning install directories.
2636 int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2638 if (mIsUpgrade || mFirstBoot) {
2639 scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2642 // Collect vendor/product overlay packages. (Do this before scanning any apps.)
2643 // For security and version matching reason, only consider
2644 // overlay packages if they reside in the right directory.
2645 scanDirTracedLI(new File(VENDOR_OVERLAY_DIR),
2647 | PackageParser.PARSE_IS_SYSTEM_DIR,
2652 scanDirTracedLI(new File(PRODUCT_OVERLAY_DIR),
2654 | PackageParser.PARSE_IS_SYSTEM_DIR,
2660 mParallelPackageParserCallback.findStaticOverlayPackages();
2662 // Find base frameworks (resource packages without code).
2663 scanDirTracedLI(frameworkDir,
2665 | PackageParser.PARSE_IS_SYSTEM_DIR,
2669 | SCAN_AS_PRIVILEGED,
2672 // Collect privileged system packages.
2673 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2674 scanDirTracedLI(privilegedAppDir,
2676 | PackageParser.PARSE_IS_SYSTEM_DIR,
2679 | SCAN_AS_PRIVILEGED,
2682 // Collect ordinary system packages.
2683 final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2684 scanDirTracedLI(systemAppDir,
2686 | PackageParser.PARSE_IS_SYSTEM_DIR,
2691 // Collect privileged vendor packages.
2692 File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
2694 privilegedVendorAppDir = privilegedVendorAppDir.getCanonicalFile();
2695 } catch (IOException e) {
2696 // failed to look up canonical path, continue with original one
2698 scanDirTracedLI(privilegedVendorAppDir,
2700 | PackageParser.PARSE_IS_SYSTEM_DIR,
2704 | SCAN_AS_PRIVILEGED,
2707 // Collect ordinary vendor packages.
2708 File vendorAppDir = new File(Environment.getVendorDirectory(), "app");
2710 vendorAppDir = vendorAppDir.getCanonicalFile();
2711 } catch (IOException e) {
2712 // failed to look up canonical path, continue with original one
2714 scanDirTracedLI(vendorAppDir,
2716 | PackageParser.PARSE_IS_SYSTEM_DIR,
2722 // Collect privileged odm packages. /odm is another vendor partition
2723 // other than /vendor.
2724 File privilegedOdmAppDir = new File(Environment.getOdmDirectory(),
2727 privilegedOdmAppDir = privilegedOdmAppDir.getCanonicalFile();
2728 } catch (IOException e) {
2729 // failed to look up canonical path, continue with original one
2731 scanDirTracedLI(privilegedOdmAppDir,
2733 | PackageParser.PARSE_IS_SYSTEM_DIR,
2737 | SCAN_AS_PRIVILEGED,
2740 // Collect ordinary odm packages. /odm is another vendor partition
2741 // other than /vendor.
2742 File odmAppDir = new File(Environment.getOdmDirectory(), "app");
2744 odmAppDir = odmAppDir.getCanonicalFile();
2745 } catch (IOException e) {
2746 // failed to look up canonical path, continue with original one
2748 scanDirTracedLI(odmAppDir,
2750 | PackageParser.PARSE_IS_SYSTEM_DIR,
2756 // Collect all OEM packages.
2757 final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2758 scanDirTracedLI(oemAppDir,
2760 | PackageParser.PARSE_IS_SYSTEM_DIR,
2766 // Collected privileged product packages.
2767 File privilegedProductAppDir = new File(Environment.getProductDirectory(), "priv-app");
2769 privilegedProductAppDir = privilegedProductAppDir.getCanonicalFile();
2770 } catch (IOException e) {
2771 // failed to look up canonical path, continue with original one
2773 scanDirTracedLI(privilegedProductAppDir,
2775 | PackageParser.PARSE_IS_SYSTEM_DIR,
2779 | SCAN_AS_PRIVILEGED,
2782 // Collect ordinary product packages.
2783 File productAppDir = new File(Environment.getProductDirectory(), "app");
2785 productAppDir = productAppDir.getCanonicalFile();
2786 } catch (IOException e) {
2787 // failed to look up canonical path, continue with original one
2789 scanDirTracedLI(productAppDir,
2791 | PackageParser.PARSE_IS_SYSTEM_DIR,
2797 // Prune any system packages that no longer exist.
2798 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
2799 // Stub packages must either be replaced with full versions in the /data
2800 // partition or be disabled.
2801 final List<String> stubSystemApps = new ArrayList<>();
2803 // do this first before mucking with mPackages for the "expecting better" case
2804 final Iterator<PackageParser.Package> pkgIterator = mPackages.values().iterator();
2805 while (pkgIterator.hasNext()) {
2806 final PackageParser.Package pkg = pkgIterator.next();
2808 stubSystemApps.add(pkg.packageName);
2812 final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2813 while (psit.hasNext()) {
2814 PackageSetting ps = psit.next();
2817 * If this is not a system app, it can't be a
2818 * disable system app.
2820 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2825 * If the package is scanned, it's not erased.
2827 final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2828 if (scannedPkg != null) {
2830 * If the system app is both scanned and in the
2831 * disabled packages list, then it must have been
2832 * added via OTA. Remove it from the currently
2833 * scanned package so the previously user-installed
2834 * application can be scanned.
2836 if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2837 logCriticalInfo(Log.WARN,
2838 "Expecting better updated system app for " + ps.name
2839 + "; removing system app. Last known"
2840 + " codePath=" + ps.codePathString
2841 + ", versionCode=" + ps.versionCode
2842 + "; scanned versionCode=" + scannedPkg.getLongVersionCode());
2843 removePackageLI(scannedPkg, true);
2844 mExpectingBetter.put(ps.name, ps.codePath);
2850 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2852 logCriticalInfo(Log.WARN, "System package " + ps.name
2853 + " no longer exists; it's data will be wiped");
2854 // Actual deletion of code and data will be handled by later
2855 // reconciliation step
2857 // we still have a disabled system package, but, it still might have
2858 // been removed. check the code path still exists and check there's
2859 // still a package. the latter can happen if an OTA keeps the same
2860 // code path, but, changes the package name.
2861 final PackageSetting disabledPs =
2862 mSettings.getDisabledSystemPkgLPr(ps.name);
2863 if (disabledPs.codePath == null || !disabledPs.codePath.exists()
2864 || disabledPs.pkg == null) {
2865 possiblyDeletedUpdatedSystemApps.add(ps.name);
2872 deleteTempPackageFiles();
2874 final int cachedSystemApps = PackageParser.sCachedPackageReadCount.get();
2876 // Remove any shared userIDs that have no associated packages
2877 mSettings.pruneSharedUsersLPw();
2878 final long systemScanTime = SystemClock.uptimeMillis() - startTime;
2879 final int systemPackagesCount = mPackages.size();
2880 Slog.i(TAG, "Finished scanning system apps. Time: " + systemScanTime
2881 + " ms, packageCount: " + systemPackagesCount
2882 + " , timePerPackage: "
2883 + (systemPackagesCount == 0 ? 0 : systemScanTime / systemPackagesCount)
2884 + " , cached: " + cachedSystemApps);
2885 if (mIsUpgrade && systemPackagesCount > 0) {
2886 MetricsLogger.histogram(null, "ota_package_manager_system_app_avg_scan_time",
2887 ((int) systemScanTime) / systemPackagesCount);
2890 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2891 SystemClock.uptimeMillis());
2892 scanDirTracedLI(sAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2894 scanDirTracedLI(sDrmAppPrivateInstallDir, mDefParseFlags
2895 | PackageParser.PARSE_FORWARD_LOCK,
2896 scanFlags | SCAN_REQUIRE_KNOWN, 0);
2898 // Remove disable package settings for updated system apps that were
2899 // removed via an OTA. If the update is no longer present, remove the
2900 // app completely. Otherwise, revoke their system privileges.
2901 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2902 PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2903 mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2905 if (deletedPkg == null) {
2906 // should have found an update, but, we didn't; remove everything
2907 msg = "Updated system package " + deletedAppName
2908 + " no longer exists; removing its data";
2909 // Actual deletion of code and data will be handled by later
2910 // reconciliation step
2912 // found an update; revoke system privileges
2913 msg = "Updated system package + " + deletedAppName
2914 + " no longer exists; revoking system privileges";
2916 // Don't do anything if a stub is removed from the system image. If
2917 // we were to remove the uncompressed version from the /data partition,
2918 // this is where it'd be done.
2920 final PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2921 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2922 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2924 logCriticalInfo(Log.WARN, msg);
2928 * Make sure all system apps that we expected to appear on
2929 * the userdata partition actually showed up. If they never
2930 * appeared, crawl back and revive the system version.
2932 for (int i = 0; i < mExpectingBetter.size(); i++) {
2933 final String packageName = mExpectingBetter.keyAt(i);
2934 if (!mPackages.containsKey(packageName)) {
2935 final File scanFile = mExpectingBetter.valueAt(i);
2937 logCriticalInfo(Log.WARN, "Expected better " + packageName
2938 + " but never showed up; reverting to system");
2940 final @ParseFlags int reparseFlags;
2941 final @ScanFlags int rescanFlags;
2942 if (FileUtils.contains(privilegedAppDir, scanFile)) {
2945 PackageParser.PARSE_IS_SYSTEM_DIR;
2949 | SCAN_AS_PRIVILEGED;
2950 } else if (FileUtils.contains(systemAppDir, scanFile)) {
2953 PackageParser.PARSE_IS_SYSTEM_DIR;
2957 } else if (FileUtils.contains(privilegedVendorAppDir, scanFile)
2958 || FileUtils.contains(privilegedOdmAppDir, scanFile)) {
2961 PackageParser.PARSE_IS_SYSTEM_DIR;
2966 | SCAN_AS_PRIVILEGED;
2967 } else if (FileUtils.contains(vendorAppDir, scanFile)
2968 || FileUtils.contains(odmAppDir, scanFile)) {
2971 PackageParser.PARSE_IS_SYSTEM_DIR;
2976 } else if (FileUtils.contains(oemAppDir, scanFile)) {
2979 PackageParser.PARSE_IS_SYSTEM_DIR;
2984 } else if (FileUtils.contains(privilegedProductAppDir, scanFile)) {
2987 PackageParser.PARSE_IS_SYSTEM_DIR;
2992 | SCAN_AS_PRIVILEGED;
2993 } else if (FileUtils.contains(productAppDir, scanFile)) {
2996 PackageParser.PARSE_IS_SYSTEM_DIR;
3002 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
3006 mSettings.enableSystemPackageLPw(packageName);
3009 scanPackageTracedLI(scanFile, reparseFlags, rescanFlags, 0, null);
3010 } catch (PackageManagerException e) {
3011 Slog.e(TAG, "Failed to parse original system package: "
3017 // Uncompress and install any stubbed system applications.
3018 // This must be done last to ensure all stubs are replaced or disabled.
3019 decompressSystemApplications(stubSystemApps, scanFlags);
3021 final int cachedNonSystemApps = PackageParser.sCachedPackageReadCount.get()
3024 final long dataScanTime = SystemClock.uptimeMillis() - systemScanTime - startTime;
3025 final int dataPackagesCount = mPackages.size() - systemPackagesCount;
3026 Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime
3027 + " ms, packageCount: " + dataPackagesCount
3028 + " , timePerPackage: "
3029 + (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount)
3030 + " , cached: " + cachedNonSystemApps);
3031 if (mIsUpgrade && dataPackagesCount > 0) {
3032 MetricsLogger.histogram(null, "ota_package_manager_data_app_avg_scan_time",
3033 ((int) dataScanTime) / dataPackagesCount);
3036 mExpectingBetter.clear();
3038 // Resolve the storage manager.
3039 mStorageManagerPackage = getStorageManagerPackageName();
3041 // Resolve protected action filters. Only the setup wizard is allowed to
3042 // have a high priority filter for these actions.
3043 mSetupWizardPackage = getSetupWizardPackageName();
3044 if (mProtectedFilters.size() > 0) {
3045 if (DEBUG_FILTERS && mSetupWizardPackage == null) {
3046 Slog.i(TAG, "No setup wizard;"
3047 + " All protected intents capped to priority 0");
3049 for (ActivityIntentInfo filter : mProtectedFilters) {
3050 if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
3051 if (DEBUG_FILTERS) {
3052 Slog.i(TAG, "Found setup wizard;"
3053 + " allow priority " + filter.getPriority() + ";"
3054 + " package: " + filter.activity.info.packageName
3055 + " activity: " + filter.activity.className
3056 + " priority: " + filter.getPriority());
3058 // skip setup wizard; allow it to keep the high priority filter
3061 if (DEBUG_FILTERS) {
3062 Slog.i(TAG, "Protected action; cap priority to 0;"
3063 + " package: " + filter.activity.info.packageName
3064 + " activity: " + filter.activity.className
3065 + " origPrio: " + filter.getPriority());
3067 filter.setPriority(0);
3071 mSystemTextClassifierPackage = getSystemTextClassifierPackageName();
3073 mDeferProtectedFilters = false;
3074 mProtectedFilters.clear();
3076 // Now that we know all of the shared libraries, update all clients to have
3077 // the correct library paths.
3078 updateAllSharedLibrariesLPw(null);
3080 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
3081 // NOTE: We ignore potential failures here during a system scan (like
3082 // the rest of the commands above) because there's precious little we
3083 // can do about it. A settings error is reported, though.
3084 final List<String> changedAbiCodePath =
3085 adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
3086 if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
3087 for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
3088 final String codePathString = changedAbiCodePath.get(i);
3090 mInstaller.rmdex(codePathString,
3091 getDexCodeInstructionSet(getPreferredInstructionSet()));
3092 } catch (InstallerException ignored) {
3096 // Adjust seInfo to ensure apps which share a sharedUserId are placed in the same
3098 setting.fixSeInfoLocked();
3101 // Now that we know all the packages we are keeping,
3102 // read and update their last usage times.
3103 mPackageUsage.read(mPackages);
3104 mCompilerStats.read();
3106 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
3107 SystemClock.uptimeMillis());
3108 Slog.i(TAG, "Time to scan packages: "
3109 + ((SystemClock.uptimeMillis()-startTime)/1000f)
3112 // If the platform SDK has changed since the last time we booted,
3113 // we need to re-grant app permission to catch any new ones that
3114 // appear. This is really a hack, and means that apps can in some
3115 // cases get permissions that the user didn't initially explicitly
3116 // allow... it would be nice to have some better way to handle
3118 final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
3120 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
3121 + mSdkVersion + "; regranting permissions for internal storage");
3123 mPermissionManager.updateAllPermissions(
3124 StorageManager.UUID_PRIVATE_INTERNAL, sdkUpdated, mPackages.values(),
3125 mPermissionCallback);
3126 ver.sdkVersion = mSdkVersion;
3128 // If this is the first boot or an update from pre-M, and it is a normal
3129 // boot, then we need to initialize the default preferred apps across
3130 // all defined users.
3131 if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
3132 for (UserInfo user : sUserManager.getUsers(true)) {
3133 mSettings.applyDefaultPreferredAppsLPw(this, user.id);
3134 applyFactoryDefaultBrowserLPw(user.id);
3135 primeDomainVerificationsLPw(user.id);
3139 // Prepare storage for system user really early during boot,
3140 // since core system apps like SettingsProvider and SystemUI
3141 // can't wait for user to start
3142 final int storageFlags;
3143 if (StorageManager.isFileEncryptedNativeOrEmulated()) {
3144 storageFlags = StorageManager.FLAG_STORAGE_DE;
3146 storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
3148 List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
3149 UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
3150 true /* onlyCoreApps */);
3151 mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
3152 TimingsTraceLog traceLog = new TimingsTraceLog("SystemServerTimingAsync",
3153 Trace.TRACE_TAG_PACKAGE_MANAGER);
3154 traceLog.traceBegin("AppDataFixup");
3156 mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
3157 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
3158 } catch (InstallerException e) {
3159 Slog.w(TAG, "Trouble fixing GIDs", e);
3161 traceLog.traceEnd();
3163 traceLog.traceBegin("AppDataPrepare");
3164 if (deferPackages == null || deferPackages.isEmpty()) {
3168 for (String pkgName : deferPackages) {
3169 PackageParser.Package pkg = null;
3170 synchronized (mPackages) {
3171 PackageSetting ps = mSettings.getPackageLPr(pkgName);
3172 if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
3177 synchronized (mInstallLock) {
3178 prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
3179 true /* maybeMigrateAppData */);
3184 traceLog.traceEnd();
3185 Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
3186 }, "prepareAppData");
3188 // If this is first boot after an OTA, and a normal boot, then
3189 // we need to clear code cache directories.
3190 // Note that we do *not* clear the application profiles. These remain valid
3191 // across OTAs and are used to drive profile verification (post OTA) and
3192 // profile compilation (without waiting to collect a fresh set of profiles).
3193 if (mIsUpgrade && !onlyCore) {
3194 Slog.i(TAG, "Build fingerprint changed; clearing code caches");
3195 for (int i = 0; i < mSettings.mPackages.size(); i++) {
3196 final PackageSetting ps = mSettings.mPackages.valueAt(i);
3197 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
3198 // No apps are running this early, so no need to freeze
3199 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
3200 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
3201 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
3204 ver.fingerprint = Build.FINGERPRINT;
3207 checkDefaultBrowser();
3209 // clear only after permissions and other defaults have been updated
3210 mExistingSystemPackages.clear();
3211 mPromoteSystemApps = false;
3213 // All the changes are done during package scanning.
3214 ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
3216 // can downgrade to reader
3217 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
3218 mSettings.writeLPr();
3219 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3220 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
3221 SystemClock.uptimeMillis());
3224 mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
3225 mRequiredInstallerPackage = getRequiredInstallerLPr();
3226 mRequiredUninstallerPackage = getRequiredUninstallerLPr();
3227 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
3228 if (mIntentFilterVerifierComponent != null) {
3229 mIntentFilterVerifier = new IntentVerifierProxy(mContext,
3230 mIntentFilterVerifierComponent);
3232 mIntentFilterVerifier = null;
3234 mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3235 PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
3236 SharedLibraryInfo.VERSION_UNDEFINED);
3237 mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3238 PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
3239 SharedLibraryInfo.VERSION_UNDEFINED);
3241 mRequiredVerifierPackage = null;
3242 mRequiredInstallerPackage = null;
3243 mRequiredUninstallerPackage = null;
3244 mIntentFilterVerifierComponent = null;
3245 mIntentFilterVerifier = null;
3246 mServicesSystemSharedLibraryPackageName = null;
3247 mSharedSystemSharedLibraryPackageName = null;
3250 mInstallerService = new PackageInstallerService(context, this);
3251 final Pair<ComponentName, String> instantAppResolverComponent =
3252 getInstantAppResolverLPr();
3253 if (instantAppResolverComponent != null) {
3254 if (DEBUG_INSTANT) {
3255 Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
3257 mInstantAppResolverConnection = new InstantAppResolverConnection(
3258 mContext, instantAppResolverComponent.first,
3259 instantAppResolverComponent.second);
3260 mInstantAppResolverSettingsComponent =
3261 getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
3263 mInstantAppResolverConnection = null;
3264 mInstantAppResolverSettingsComponent = null;
3266 updateInstantAppInstallerLocked(null);
3268 // Read and update the usage of dex files.
3269 // Do this at the end of PM init so that all the packages have their
3270 // data directory reconciled.
3271 // At this point we know the code paths of the packages, so we can validate
3272 // the disk file and build the internal cache.
3273 // The usage file is expected to be small so loading and verifying it
3274 // should take a fairly small time compare to the other activities (e.g. package
3276 final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
3277 final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
3278 for (int userId : currentUserIds) {
3279 userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
3281 mDexManager.load(userPackages);
3283 MetricsLogger.histogram(null, "ota_package_manager_init_time",
3284 (int) (SystemClock.uptimeMillis() - startTime));
3286 } // synchronized (mPackages)
3287 } // synchronized (mInstallLock)
3289 // Now after opening every single application zip, make sure they
3290 // are all flushed. Not really needed, but keeps things nice and
3292 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
3293 Runtime.getRuntime().gc();
3294 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3296 // The initial scanning above does many calls into installd while
3297 // holding the mPackages lock, but we're mostly interested in yelling
3298 // once we have a booted system.
3299 mInstaller.setWarnIfHeld(mPackages);
3301 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3305 * Uncompress and install stub applications.
3306 * <p>In order to save space on the system partition, some applications are shipped in a
3307 * compressed form. In addition the compressed bits for the full application, the
3308 * system image contains a tiny stub comprised of only the Android manifest.
3309 * <p>During the first boot, attempt to uncompress and install the full application. If
3310 * the application can't be installed for any reason, disable the stub and prevent
3311 * uncompressing the full application during future boots.
3312 * <p>In order to forcefully attempt an installation of a full application, go to app
3313 * settings and enable the application.
3315 private void decompressSystemApplications(@NonNull List<String> stubSystemApps, int scanFlags) {
3316 for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3317 final String pkgName = stubSystemApps.get(i);
3318 // skip if the system package is already disabled
3319 if (mSettings.isDisabledSystemPackageLPr(pkgName)) {
3320 stubSystemApps.remove(i);
3323 // skip if the package isn't installed (?!); this should never happen
3324 final PackageParser.Package pkg = mPackages.get(pkgName);
3326 stubSystemApps.remove(i);
3329 // skip if the package has been disabled by the user
3330 final PackageSetting ps = mSettings.mPackages.get(pkgName);
3332 final int enabledState = ps.getEnabled(UserHandle.USER_SYSTEM);
3333 if (enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
3334 stubSystemApps.remove(i);
3339 if (DEBUG_COMPRESSION) {
3340 Slog.i(TAG, "Uncompressing system stub; pkg: " + pkgName);
3343 // uncompress the binary to its eventual destination on /data
3344 final File scanFile = decompressPackage(pkg);
3345 if (scanFile == null) {
3349 // install the package to replace the stub on /system
3351 mSettings.disableSystemPackageLPw(pkgName, true /*replaced*/);
3352 removePackageLI(pkg, true /*chatty*/);
3353 scanPackageTracedLI(scanFile, 0 /*reparseFlags*/, scanFlags, 0, null);
3354 ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
3355 UserHandle.USER_SYSTEM, "android");
3356 stubSystemApps.remove(i);
3358 } catch (PackageManagerException e) {
3359 Slog.e(TAG, "Failed to parse uncompressed system package: " + e.getMessage());
3362 // any failed attempt to install the package will be cleaned up later
3365 // disable any stub still left; these failed to install the full application
3366 for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3367 final String pkgName = stubSystemApps.get(i);
3368 final PackageSetting ps = mSettings.mPackages.get(pkgName);
3369 ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
3370 UserHandle.USER_SYSTEM, "android");
3371 logCriticalInfo(Log.ERROR, "Stub disabled; pkg: " + pkgName);
3376 * Decompresses the given package on the system image onto
3377 * the /data partition.
3378 * @return The directory the package was decompressed into. Otherwise, {@code null}.
3380 private File decompressPackage(PackageParser.Package pkg) {
3381 final File[] compressedFiles = getCompressedFiles(pkg.codePath);
3382 if (compressedFiles == null || compressedFiles.length == 0) {
3383 if (DEBUG_COMPRESSION) {
3384 Slog.i(TAG, "No files to decompress: " + pkg.baseCodePath);
3388 final File dstCodePath =
3389 getNextCodePath(Environment.getDataAppDirectory(null), pkg.packageName);
3390 int ret = PackageManager.INSTALL_SUCCEEDED;
3392 Os.mkdir(dstCodePath.getAbsolutePath(), 0755);
3393 Os.chmod(dstCodePath.getAbsolutePath(), 0755);
3394 for (File srcFile : compressedFiles) {
3395 final String srcFileName = srcFile.getName();
3396 final String dstFileName = srcFileName.substring(
3397 0, srcFileName.length() - COMPRESSED_EXTENSION.length());
3398 final File dstFile = new File(dstCodePath, dstFileName);
3399 ret = decompressFile(srcFile, dstFile);
3400 if (ret != PackageManager.INSTALL_SUCCEEDED) {
3401 logCriticalInfo(Log.ERROR, "Failed to decompress"
3402 + "; pkg: " + pkg.packageName
3403 + ", file: " + dstFileName);
3407 } catch (ErrnoException e) {
3408 logCriticalInfo(Log.ERROR, "Failed to decompress"
3409 + "; pkg: " + pkg.packageName
3410 + ", err: " + e.errno);
3412 if (ret == PackageManager.INSTALL_SUCCEEDED) {
3413 final File libraryRoot = new File(dstCodePath, LIB_DIR_NAME);
3414 NativeLibraryHelper.Handle handle = null;
3416 handle = NativeLibraryHelper.Handle.create(dstCodePath);
3417 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
3418 null /*abiOverride*/);
3419 } catch (IOException e) {
3420 logCriticalInfo(Log.ERROR, "Failed to extract native libraries"
3421 + "; pkg: " + pkg.packageName);
3422 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
3424 IoUtils.closeQuietly(handle);
3427 if (ret != PackageManager.INSTALL_SUCCEEDED) {
3428 if (dstCodePath == null || !dstCodePath.exists()) {
3431 removeCodePathLI(dstCodePath);
3438 private void updateInstantAppInstallerLocked(String modifiedPackage) {
3439 // we're only interested in updating the installer appliction when 1) it's not
3440 // already set or 2) the modified package is the installer
3441 if (mInstantAppInstallerActivity != null
3442 && !mInstantAppInstallerActivity.getComponentName().getPackageName()
3443 .equals(modifiedPackage)) {
3446 setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
3449 private static File preparePackageParserCache(boolean isUpgrade) {
3450 if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
3454 // Disable package parsing on eng builds to allow for faster incremental development.
3459 if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
3460 Slog.i(TAG, "Disabling package parser cache due to system property.");
3464 // The base directory for the package parser cache lives under /data/system/.
3465 final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(),
3467 if (cacheBaseDir == null) {
3471 // If this is a system upgrade scenario, delete the contents of the package cache dir.
3472 // This also serves to "GC" unused entries when the package cache version changes (which
3473 // can only happen during upgrades).
3475 FileUtils.deleteContents(cacheBaseDir);
3479 // Return the versioned package cache directory. This is something like
3480 // "/data/system/package_cache/1"
3481 File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3483 if (cacheDir == null) {
3484 // Something went wrong. Attempt to delete everything and return.
3485 Slog.wtf(TAG, "Cache directory cannot be created - wiping base dir " + cacheBaseDir);
3486 FileUtils.deleteContentsAndDir(cacheBaseDir);
3490 // The following is a workaround to aid development on non-numbered userdebug
3491 // builds or cases where "adb sync" is used on userdebug builds. If we detect that
3492 // the system partition is newer.
3494 // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
3495 // that starts with "eng." to signify that this is an engineering build and not
3496 // destined for release.
3497 if (Build.IS_USERDEBUG && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
3498 Slog.w(TAG, "Wiping cache directory because the system partition changed.");
3500 // Heuristic: If the /system directory has been modified recently due to an "adb sync"
3501 // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
3502 // in general and should not be used for production changes. In this specific case,
3503 // we know that they will work.
3504 File frameworkDir = new File(Environment.getRootDirectory(), "framework");
3505 if (cacheDir.lastModified() < frameworkDir.lastModified()) {
3506 FileUtils.deleteContents(cacheBaseDir);
3507 cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3515 public boolean isFirstBoot() {
3516 // allow instant applications
3521 public boolean isOnlyCoreApps() {
3522 // allow instant applications
3527 public boolean isUpgrade() {
3528 // allow instant applications
3529 // The system property allows testing ota flow when upgraded to the same image.
3530 return mIsUpgrade || SystemProperties.getBoolean(
3531 "persist.pm.mock-upgrade", false /* default */);
3534 private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
3535 final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
3537 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3538 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3539 UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3540 if (matches.size() == 1) {
3541 return matches.get(0).getComponentInfo().packageName;
3542 } else if (matches.size() == 0) {
3543 Log.e(TAG, "There should probably be a verifier, but, none were found");
3546 throw new RuntimeException("There must be exactly one verifier; found " + matches);
3549 private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
3550 synchronized (mPackages) {
3551 SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version);
3552 if (libraryEntry == null) {
3553 throw new IllegalStateException("Missing required shared library:" + name);
3555 return libraryEntry.apk;
3559 private @NonNull String getRequiredInstallerLPr() {
3560 final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
3561 intent.addCategory(Intent.CATEGORY_DEFAULT);
3562 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3564 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3565 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3566 UserHandle.USER_SYSTEM);
3567 if (matches.size() == 1) {
3568 ResolveInfo resolveInfo = matches.get(0);
3569 if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3570 throw new RuntimeException("The installer must be a privileged app");
3572 return matches.get(0).getComponentInfo().packageName;
3574 throw new RuntimeException("There must be exactly one installer; found " + matches);
3578 private @NonNull String getRequiredUninstallerLPr() {
3579 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
3580 intent.addCategory(Intent.CATEGORY_DEFAULT);
3581 intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
3583 final ResolveInfo resolveInfo = resolveIntent(intent, null,
3584 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3585 UserHandle.USER_SYSTEM);
3586 if (resolveInfo == null ||
3587 mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
3588 throw new RuntimeException("There must be exactly one uninstaller; found "
3591 return resolveInfo.getComponentInfo().packageName;
3594 private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3595 final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3597 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3598 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3599 UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3600 ResolveInfo best = null;
3601 final int N = matches.size();
3602 for (int i = 0; i < N; i++) {
3603 final ResolveInfo cur = matches.get(i);
3604 final String packageName = cur.getComponentInfo().packageName;
3605 if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3606 packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3610 if (best == null || cur.priority > best.priority) {
3616 return best.getComponentInfo().getComponentName();
3618 Slog.w(TAG, "Intent filter verifier not found");
3623 public @Nullable ComponentName getInstantAppResolverComponent() {
3624 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3627 synchronized (mPackages) {
3628 final Pair<ComponentName, String> instantAppResolver = getInstantAppResolverLPr();
3629 if (instantAppResolver == null) {
3632 return instantAppResolver.first;
3636 private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
3637 final String[] packageArray =
3638 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3639 if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3640 if (DEBUG_INSTANT) {
3641 Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3646 final int callingUid = Binder.getCallingUid();
3647 final int resolveFlags =
3648 MATCH_DIRECT_BOOT_AWARE
3649 | MATCH_DIRECT_BOOT_UNAWARE
3650 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3651 String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
3652 final Intent resolverIntent = new Intent(actionName);
3653 List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3654 resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3655 final int N = resolvers.size();
3657 if (DEBUG_INSTANT) {
3658 Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3663 final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3664 for (int i = 0; i < N; i++) {
3665 final ResolveInfo info = resolvers.get(i);
3667 if (info.serviceInfo == null) {
3671 final String packageName = info.serviceInfo.packageName;
3672 if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3673 if (DEBUG_INSTANT) {
3674 Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3675 + " pkg: " + packageName + ", info:" + info);
3680 if (DEBUG_INSTANT) {
3681 Slog.v(TAG, "Ephemeral resolver found;"
3682 + " pkg: " + packageName + ", info:" + info);
3684 return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
3686 if (DEBUG_INSTANT) {
3687 Slog.v(TAG, "Ephemeral resolver NOT found");
3692 private @Nullable ActivityInfo getInstantAppInstallerLPr() {
3693 String[] orderedActions = Build.IS_ENG
3695 Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE + "_TEST",
3696 Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE}
3698 Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE};
3700 final int resolveFlags =
3701 MATCH_DIRECT_BOOT_AWARE
3702 | MATCH_DIRECT_BOOT_UNAWARE
3703 | Intent.FLAG_IGNORE_EPHEMERAL
3704 | (!Build.IS_ENG ? MATCH_SYSTEM_ONLY : 0);
3705 final Intent intent = new Intent();
3706 intent.addCategory(Intent.CATEGORY_DEFAULT);
3707 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3708 List<ResolveInfo> matches = null;
3709 for (String action : orderedActions) {
3710 intent.setAction(action);
3711 matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3712 resolveFlags, UserHandle.USER_SYSTEM);
3713 if (matches.isEmpty()) {
3714 if (DEBUG_INSTANT) {
3715 Slog.d(TAG, "Instant App installer not found with " + action);
3721 Iterator<ResolveInfo> iter = matches.iterator();
3722 while (iter.hasNext()) {
3723 final ResolveInfo rInfo = iter.next();
3724 final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3726 final PermissionsState permissionsState = ps.getPermissionsState();
3727 if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)
3734 if (matches.size() == 0) {
3736 } else if (matches.size() == 1) {
3737 return (ActivityInfo) matches.get(0).getComponentInfo();
3739 throw new RuntimeException(
3740 "There must be at most one ephemeral installer; found " + matches);
3744 private @Nullable ComponentName getInstantAppResolverSettingsLPr(
3745 @NonNull ComponentName resolver) {
3746 final Intent intent = new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
3747 .addCategory(Intent.CATEGORY_DEFAULT)
3748 .setPackage(resolver.getPackageName());
3749 final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3750 List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3751 UserHandle.USER_SYSTEM);
3752 if (matches.isEmpty()) {
3755 return matches.get(0).getComponentInfo().getComponentName();
3758 private void primeDomainVerificationsLPw(int userId) {
3759 if (DEBUG_DOMAIN_VERIFICATION) {
3760 Slog.d(TAG, "Priming domain verifications in user " + userId);
3763 SystemConfig systemConfig = SystemConfig.getInstance();
3764 ArraySet<String> packages = systemConfig.getLinkedApps();
3766 for (String packageName : packages) {
3767 PackageParser.Package pkg = mPackages.get(packageName);
3769 if (!pkg.isSystem()) {
3770 Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
3774 ArraySet<String> domains = null;
3775 for (PackageParser.Activity a : pkg.activities) {
3776 for (ActivityIntentInfo filter : a.intents) {
3777 if (hasValidDomains(filter)) {
3778 if (domains == null) {
3779 domains = new ArraySet<String>();
3781 domains.addAll(filter.getHostsList());
3786 if (domains != null && domains.size() > 0) {
3787 if (DEBUG_DOMAIN_VERIFICATION) {
3788 Slog.v(TAG, " + " + packageName);
3790 // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
3791 // state w.r.t. the formal app-linkage "no verification attempted" state;
3792 // and then 'always' in the per-user state actually used for intent resolution.
3793 final IntentFilterVerificationInfo ivi;
3794 ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
3795 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
3796 mSettings.updateIntentFilterVerificationStatusLPw(packageName,
3797 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
3799 Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
3800 + "' does not handle web links");
3803 Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
3807 scheduleWritePackageRestrictionsLocked(userId);
3808 scheduleWriteSettingsLocked();
3811 private void applyFactoryDefaultBrowserLPw(int userId) {
3812 // The default browser app's package name is stored in a string resource,
3813 // with a product-specific overlay used for vendor customization.
3814 String browserPkg = mContext.getResources().getString(
3815 com.android.internal.R.string.default_browser);
3816 if (!TextUtils.isEmpty(browserPkg)) {
3817 // non-empty string => required to be a known package
3818 PackageSetting ps = mSettings.mPackages.get(browserPkg);
3820 Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
3823 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3827 // Nothing valid explicitly set? Make the factory-installed browser the explicit
3828 // default. If there's more than one, just leave everything alone.
3829 if (browserPkg == null) {
3830 calculateDefaultBrowserLPw(userId);
3834 private void calculateDefaultBrowserLPw(int userId) {
3835 List<String> allBrowsers = resolveAllBrowserApps(userId);
3836 final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
3837 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3840 private List<String> resolveAllBrowserApps(int userId) {
3841 // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
3842 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3843 PackageManager.MATCH_ALL, userId);
3845 final int count = list.size();
3846 List<String> result = new ArrayList<String>(count);
3847 for (int i=0; i<count; i++) {
3848 ResolveInfo info = list.get(i);
3849 if (info.activityInfo == null
3850 || !info.handleAllWebDataURI
3851 || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
3852 || result.contains(info.activityInfo.packageName)) {
3855 result.add(info.activityInfo.packageName);
3861 private boolean packageIsBrowser(String packageName, int userId) {
3862 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3863 PackageManager.MATCH_ALL, userId);
3864 final int N = list.size();
3865 for (int i = 0; i < N; i++) {
3866 ResolveInfo info = list.get(i);
3867 if (info.priority >= 0 && packageName.equals(info.activityInfo.packageName)) {
3874 private void checkDefaultBrowser() {
3875 final int myUserId = UserHandle.myUserId();
3876 final String packageName = getDefaultBrowserPackageName(myUserId);
3877 if (packageName != null) {
3878 PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3880 Slog.w(TAG, "Default browser no longer installed: " + packageName);
3881 synchronized (mPackages) {
3882 applyFactoryDefaultBrowserLPw(myUserId); // leaves ambiguous when > 1
3889 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3890 throws RemoteException {
3892 return super.onTransact(code, data, reply, flags);
3893 } catch (RuntimeException e) {
3894 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3895 Slog.wtf(TAG, "Package Manager Crash", e);
3901 static int[] appendInts(int[] cur, int[] add) {
3902 if (add == null) return cur;
3903 if (cur == null) return add;
3904 final int N = add.length;
3905 for (int i=0; i<N; i++) {
3906 cur = appendInt(cur, add[i]);
3912 * Returns whether or not a full application can see an instant application.
3914 * Currently, there are three cases in which this can occur:
3916 * <li>The calling application is a "special" process. Special processes
3917 * are those with a UID < {@link Process#FIRST_APPLICATION_UID}.</li>
3918 * <li>The calling application has the permission
3919 * {@link android.Manifest.permission#ACCESS_INSTANT_APPS}.</li>
3920 * <li>The calling application is the default launcher on the
3921 * system partition.</li>
3924 private boolean canViewInstantApps(int callingUid, int userId) {
3925 if (callingUid < Process.FIRST_APPLICATION_UID) {
3928 if (mContext.checkCallingOrSelfPermission(
3929 android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED) {
3932 if (mContext.checkCallingOrSelfPermission(
3933 android.Manifest.permission.VIEW_INSTANT_APPS) == PERMISSION_GRANTED) {
3934 final ComponentName homeComponent = getDefaultHomeActivity(userId);
3935 if (homeComponent != null
3936 && isCallerSameApp(homeComponent.getPackageName(), callingUid)) {
3943 private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3944 if (!sUserManager.exists(userId)) return null;
3948 final int callingUid = Binder.getCallingUid();
3949 // Filter out ephemeral app metadata:
3950 // * The system/shell/root can see metadata for any app
3951 // * An installed app can see metadata for 1) other installed apps
3952 // and 2) ephemeral apps that have explicitly interacted with it
3953 // * Ephemeral apps can only see their own data and exposed installed apps
3954 // * Holding a signature permission allows seeing instant apps
3955 if (filterAppAccessLPr(ps, callingUid, userId)) {
3959 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
3961 flags |= MATCH_ANY_USER;
3964 final PackageUserState state = ps.readUserState(userId);
3965 PackageParser.Package p = ps.pkg;
3967 final PermissionsState permissionsState = ps.getPermissionsState();
3969 // Compute GIDs only if requested
3970 final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3971 ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3972 // Compute granted permissions only if package has requested permissions
3973 final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3974 ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3976 PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags,
3977 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3979 if (packageInfo == null) {
3983 packageInfo.packageName = packageInfo.applicationInfo.packageName =
3984 resolveExternalPackageNameLPr(p);
3987 } else if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0 && state.isAvailable(flags)) {
3988 PackageInfo pi = new PackageInfo();
3989 pi.packageName = ps.name;
3990 pi.setLongVersionCode(ps.versionCode);
3991 pi.sharedUserId = (ps.sharedUser != null) ? ps.sharedUser.name : null;
3992 pi.firstInstallTime = ps.firstInstallTime;
3993 pi.lastUpdateTime = ps.lastUpdateTime;
3995 ApplicationInfo ai = new ApplicationInfo();
3996 ai.packageName = ps.name;
3997 ai.uid = UserHandle.getUid(userId, ps.appId);
3998 ai.primaryCpuAbi = ps.primaryCpuAbiString;
3999 ai.secondaryCpuAbi = ps.secondaryCpuAbiString;
4000 ai.setVersionCode(ps.versionCode);
4001 ai.flags = ps.pkgFlags;
4002 ai.privateFlags = ps.pkgPrivateFlags;
4003 pi.applicationInfo = PackageParser.generateApplicationInfo(ai, flags, state, userId);
4005 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "ps.pkg is n/a for ["
4006 + ps.name + "]. Provides a minimum info.");
4014 public void checkPackageStartable(String packageName, int userId) {
4015 final int callingUid = Binder.getCallingUid();
4016 if (getInstantAppPackageName(callingUid) != null) {
4017 throw new SecurityException("Instant applications don't have access to this method");
4019 final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
4020 synchronized (mPackages) {
4021 final PackageSetting ps = mSettings.mPackages.get(packageName);
4022 if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
4023 throw new SecurityException("Package " + packageName + " was not found!");
4026 if (!ps.getInstalled(userId)) {
4027 throw new SecurityException(
4028 "Package " + packageName + " was not installed for user " + userId + "!");
4031 if (mSafeMode && !ps.isSystem()) {
4032 throw new SecurityException("Package " + packageName + " not a system app!");
4035 if (mFrozenPackages.contains(packageName)) {
4036 throw new SecurityException("Package " + packageName + " is currently frozen!");
4039 if (!userKeyUnlocked && !ps.pkg.applicationInfo.isEncryptionAware()) {
4040 throw new SecurityException("Package " + packageName + " is not encryption aware!");
4046 public boolean isPackageAvailable(String packageName, int userId) {
4047 if (!sUserManager.exists(userId)) return false;
4048 final int callingUid = Binder.getCallingUid();
4049 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4050 false /*requireFullPermission*/, false /*checkShell*/, "is package available");
4051 synchronized (mPackages) {
4052 PackageParser.Package p = mPackages.get(packageName);
4054 final PackageSetting ps = (PackageSetting) p.mExtras;
4055 if (filterAppAccessLPr(ps, callingUid, userId)) {
4059 final PackageUserState state = ps.readUserState(userId);
4060 if (state != null) {
4061 return PackageParser.isAvailable(state);
4070 public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
4071 return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
4072 flags, Binder.getCallingUid(), userId);
4076 public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
4077 int flags, int userId) {
4078 return getPackageInfoInternal(versionedPackage.getPackageName(),
4079 versionedPackage.getLongVersionCode(), flags, Binder.getCallingUid(), userId);
4083 * Important: The provided filterCallingUid is used exclusively to filter out packages
4084 * that can be seen based on user state. It's typically the original caller uid prior
4085 * to clearing. Because it can only be provided by trusted code, it's value can be
4086 * trusted and will be used as-is; unlike userId which will be validated by this method.
4088 private PackageInfo getPackageInfoInternal(String packageName, long versionCode,
4089 int flags, int filterCallingUid, int userId) {
4090 if (!sUserManager.exists(userId)) return null;
4091 flags = updateFlagsForPackage(flags, userId, packageName);
4092 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
4093 false /* requireFullPermission */, false /* checkShell */, "get package info");
4096 synchronized (mPackages) {
4097 // Normalize package name to handle renamed packages and static libs
4098 packageName = resolveInternalPackageNameLPr(packageName, versionCode);
4100 final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
4101 if (matchFactoryOnly) {
4102 final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
4104 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4107 if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4110 return generatePackageInfo(ps, flags, userId);
4114 PackageParser.Package p = mPackages.get(packageName);
4115 if (matchFactoryOnly && p != null && !isSystemApp(p)) {
4118 if (DEBUG_PACKAGE_INFO)
4119 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
4121 final PackageSetting ps = (PackageSetting) p.mExtras;
4122 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4125 if (ps != null && filterAppAccessLPr(ps, filterCallingUid, userId)) {
4128 return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
4130 if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
4131 final PackageSetting ps = mSettings.mPackages.get(packageName);
4132 if (ps == null) return null;
4133 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4136 if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4139 return generatePackageInfo(ps, flags, userId);
4145 private boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
4146 if (isComponentVisibleToInstantApp(component, TYPE_ACTIVITY)) {
4149 if (isComponentVisibleToInstantApp(component, TYPE_SERVICE)) {
4152 if (isComponentVisibleToInstantApp(component, TYPE_PROVIDER)) {
4158 private boolean isComponentVisibleToInstantApp(
4159 @Nullable ComponentName component, @ComponentType int type) {
4160 if (type == TYPE_ACTIVITY) {
4161 final PackageParser.Activity activity = mActivities.mActivities.get(component);
4162 if (activity == null) {
4165 final boolean visibleToInstantApp =
4166 (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4167 final boolean explicitlyVisibleToInstantApp =
4168 (activity.info.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
4169 return visibleToInstantApp && explicitlyVisibleToInstantApp;
4170 } else if (type == TYPE_RECEIVER) {
4171 final PackageParser.Activity activity = mReceivers.mActivities.get(component);
4172 if (activity == null) {
4175 final boolean visibleToInstantApp =
4176 (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4177 final boolean explicitlyVisibleToInstantApp =
4178 (activity.info.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
4179 return visibleToInstantApp && !explicitlyVisibleToInstantApp;
4180 } else if (type == TYPE_SERVICE) {
4181 final PackageParser.Service service = mServices.mServices.get(component);
4182 return service != null
4183 ? (service.info.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4185 } else if (type == TYPE_PROVIDER) {
4186 final PackageParser.Provider provider = mProviders.mProviders.get(component);
4187 return provider != null
4188 ? (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4190 } else if (type == TYPE_UNKNOWN) {
4191 return isComponentVisibleToInstantApp(component);
4197 * Returns whether or not access to the application should be filtered.
4199 * Access may be limited based upon whether the calling or target applications
4200 * are instant applications.
4202 * @see #canAccessInstantApps(int)
4204 private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid,
4205 @Nullable ComponentName component, @ComponentType int componentType, int userId) {
4206 // if we're in an isolated process, get the real calling UID
4207 if (Process.isIsolated(callingUid)) {
4208 callingUid = mIsolatedOwners.get(callingUid);
4210 final String instantAppPkgName = getInstantAppPackageName(callingUid);
4211 final boolean callerIsInstantApp = instantAppPkgName != null;
4213 if (callerIsInstantApp) {
4214 // pretend the application exists, but, needs to be filtered
4219 // if the target and caller are the same application, don't filter
4220 if (isCallerSameApp(ps.name, callingUid)) {
4223 if (callerIsInstantApp) {
4224 // both caller and target are both instant, but, different applications, filter
4225 if (ps.getInstantApp(userId)) {
4228 // request for a specific component; if it hasn't been explicitly exposed through
4229 // property or instrumentation target, filter
4230 if (component != null) {
4231 final PackageParser.Instrumentation instrumentation =
4232 mInstrumentation.get(component);
4233 if (instrumentation != null
4234 && isCallerSameApp(instrumentation.info.targetPackage, callingUid)) {
4237 return !isComponentVisibleToInstantApp(component, componentType);
4239 // request for application; if no components have been explicitly exposed, filter
4240 return !ps.pkg.visibleToInstantApps;
4242 if (ps.getInstantApp(userId)) {
4243 // caller can see all components of all instant applications, don't filter
4244 if (canViewInstantApps(callingUid, userId)) {
4247 // request for a specific instant application component, filter
4248 if (component != null) {
4251 // request for an instant application; if the caller hasn't been granted access, filter
4252 return !mInstantAppRegistry.isInstantAccessGranted(
4253 userId, UserHandle.getAppId(callingUid), ps.appId);
4259 * @see #filterAppAccessLPr(PackageSetting, int, ComponentName, boolean, int)
4261 private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid, int userId) {
4262 return filterAppAccessLPr(ps, callingUid, null, TYPE_UNKNOWN, userId);
4265 private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
4267 // Callers can access only the libs they depend on, otherwise they need to explicitly
4268 // ask for the shared libraries given the caller is allowed to access all static libs.
4269 if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
4270 // System/shell/root get to see all static libs
4271 final int appId = UserHandle.getAppId(uid);
4272 if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
4273 || appId == Process.ROOT_UID) {
4276 // Installer gets to see all static libs.
4277 if (PackageManager.PERMISSION_GRANTED
4278 == checkUidPermission(Manifest.permission.INSTALL_PACKAGES, uid)) {
4283 // No package means no static lib as it is always on internal storage
4284 if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4288 final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName,
4289 ps.pkg.staticSharedLibVersion);
4290 if (libEntry == null) {
4294 final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
4295 final String[] uidPackageNames = getPackagesForUid(resolvedUid);
4296 if (uidPackageNames == null) {
4300 for (String uidPackageName : uidPackageNames) {
4301 if (ps.name.equals(uidPackageName)) {
4304 PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
4305 if (uidPs != null) {
4306 final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
4307 libEntry.info.getName());
4311 if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getLongVersion()) {
4320 public String[] currentToCanonicalPackageNames(String[] names) {
4321 final int callingUid = Binder.getCallingUid();
4322 if (getInstantAppPackageName(callingUid) != null) {
4325 final String[] out = new String[names.length];
4327 synchronized (mPackages) {
4328 final int callingUserId = UserHandle.getUserId(callingUid);
4329 final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4330 for (int i=names.length-1; i>=0; i--) {
4331 final PackageSetting ps = mSettings.mPackages.get(names[i]);
4332 boolean translateName = false;
4333 if (ps != null && ps.realName != null) {
4334 final boolean targetIsInstantApp = ps.getInstantApp(callingUserId);
4335 translateName = !targetIsInstantApp
4336 || canViewInstantApps
4337 || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4338 UserHandle.getAppId(callingUid), ps.appId);
4340 out[i] = translateName ? ps.realName : names[i];
4347 public String[] canonicalToCurrentPackageNames(String[] names) {
4348 final int callingUid = Binder.getCallingUid();
4349 if (getInstantAppPackageName(callingUid) != null) {
4352 final String[] out = new String[names.length];
4354 synchronized (mPackages) {
4355 final int callingUserId = UserHandle.getUserId(callingUid);
4356 final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4357 for (int i=names.length-1; i>=0; i--) {
4358 final String cur = mSettings.getRenamedPackageLPr(names[i]);
4359 boolean translateName = false;
4361 final PackageSetting ps = mSettings.mPackages.get(names[i]);
4362 final boolean targetIsInstantApp =
4363 ps != null && ps.getInstantApp(callingUserId);
4364 translateName = !targetIsInstantApp
4365 || canViewInstantApps
4366 || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4367 UserHandle.getAppId(callingUid), ps.appId);
4369 out[i] = translateName ? cur : names[i];
4376 public int getPackageUid(String packageName, int flags, int userId) {
4377 if (!sUserManager.exists(userId)) return -1;
4378 final int callingUid = Binder.getCallingUid();
4379 flags = updateFlagsForPackage(flags, userId, packageName);
4380 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4381 false /*requireFullPermission*/, false /*checkShell*/, "getPackageUid");
4384 synchronized (mPackages) {
4385 final PackageParser.Package p = mPackages.get(packageName);
4386 if (p != null && p.isMatch(flags)) {
4387 PackageSetting ps = (PackageSetting) p.mExtras;
4388 if (filterAppAccessLPr(ps, callingUid, userId)) {
4391 return UserHandle.getUid(userId, p.applicationInfo.uid);
4393 if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4394 final PackageSetting ps = mSettings.mPackages.get(packageName);
4395 if (ps != null && ps.isMatch(flags)
4396 && !filterAppAccessLPr(ps, callingUid, userId)) {
4397 return UserHandle.getUid(userId, ps.appId);
4406 public int[] getPackageGids(String packageName, int flags, int userId) {
4407 if (!sUserManager.exists(userId)) return null;
4408 final int callingUid = Binder.getCallingUid();
4409 flags = updateFlagsForPackage(flags, userId, packageName);
4410 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4411 false /*requireFullPermission*/, false /*checkShell*/, "getPackageGids");
4414 synchronized (mPackages) {
4415 final PackageParser.Package p = mPackages.get(packageName);
4416 if (p != null && p.isMatch(flags)) {
4417 PackageSetting ps = (PackageSetting) p.mExtras;
4418 if (filterAppAccessLPr(ps, callingUid, userId)) {
4421 // TODO: Shouldn't this be checking for package installed state for userId and
4423 return ps.getPermissionsState().computeGids(userId);
4425 if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4426 final PackageSetting ps = mSettings.mPackages.get(packageName);
4427 if (ps != null && ps.isMatch(flags)
4428 && !filterAppAccessLPr(ps, callingUid, userId)) {
4429 return ps.getPermissionsState().computeGids(userId);
4438 public PermissionInfo getPermissionInfo(String name, String packageName, int flags) {
4439 return mPermissionManager.getPermissionInfo(name, packageName, flags, getCallingUid());
4443 public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String groupName,
4445 final List<PermissionInfo> permissionList =
4446 mPermissionManager.getPermissionInfoByGroup(groupName, flags, getCallingUid());
4447 return (permissionList == null) ? null : new ParceledListSlice<>(permissionList);
4451 public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags) {
4452 return mPermissionManager.getPermissionGroupInfo(groupName, flags, getCallingUid());
4456 public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
4457 final List<PermissionGroupInfo> permissionList =
4458 mPermissionManager.getAllPermissionGroups(flags, getCallingUid());
4459 return (permissionList == null)
4460 ? ParceledListSlice.emptyList() : new ParceledListSlice<>(permissionList);
4463 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
4464 int filterCallingUid, int userId) {
4465 if (!sUserManager.exists(userId)) return null;
4466 PackageSetting ps = mSettings.mPackages.get(packageName);
4468 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4471 if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4474 if (ps.pkg == null) {
4475 final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
4476 if (pInfo != null) {
4477 return pInfo.applicationInfo;
4481 ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
4482 ps.readUserState(userId), userId);
4484 ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
4492 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
4493 return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId);
4497 * Important: The provided filterCallingUid is used exclusively to filter out applications
4498 * that can be seen based on user state. It's typically the original caller uid prior
4499 * to clearing. Because it can only be provided by trusted code, it's value can be
4500 * trusted and will be used as-is; unlike userId which will be validated by this method.
4502 private ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
4503 int filterCallingUid, int userId) {
4504 if (!sUserManager.exists(userId)) return null;
4505 flags = updateFlagsForApplication(flags, userId, packageName);
4506 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
4507 false /* requireFullPermission */, false /* checkShell */, "get application info");
4510 synchronized (mPackages) {
4511 // Normalize package name to handle renamed packages and static libs
4512 packageName = resolveInternalPackageNameLPr(packageName,
4513 PackageManager.VERSION_CODE_HIGHEST);
4515 PackageParser.Package p = mPackages.get(packageName);
4516 if (DEBUG_PACKAGE_INFO) Log.v(
4517 TAG, "getApplicationInfo " + packageName
4520 PackageSetting ps = mSettings.mPackages.get(packageName);
4521 if (ps == null) return null;
4522 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4525 if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4528 // Note: isEnabledLP() does not apply here - always return info
4529 ApplicationInfo ai = PackageParser.generateApplicationInfo(
4530 p, flags, ps.readUserState(userId), userId);
4532 ai.packageName = resolveExternalPackageNameLPr(p);
4536 if ("android".equals(packageName)||"system".equals(packageName)) {
4537 return mAndroidApplication;
4539 if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4540 // Already generates the external package name
4541 return generateApplicationInfoFromSettingsLPw(packageName,
4542 flags, filterCallingUid, userId);
4548 private String normalizePackageNameLPr(String packageName) {
4549 String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
4550 return normalizedPackageName != null ? normalizedPackageName : packageName;
4554 public void deletePreloadsFileCache() {
4555 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
4556 throw new SecurityException("Only system or settings may call deletePreloadsFileCache");
4558 File dir = Environment.getDataPreloadsFileCacheDirectory();
4559 Slog.i(TAG, "Deleting preloaded file cache " + dir);
4560 FileUtils.deleteContents(dir);
4564 public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
4565 final int storageFlags, final IPackageDataObserver observer) {
4566 mContext.enforceCallingOrSelfPermission(
4567 android.Manifest.permission.CLEAR_APP_CACHE, null);
4568 mHandler.post(() -> {
4569 boolean success = false;
4571 freeStorage(volumeUuid, freeStorageSize, storageFlags);
4573 } catch (IOException e) {
4576 if (observer != null) {
4578 observer.onRemoveCompleted(null, success);
4579 } catch (RemoteException e) {
4587 public void freeStorage(final String volumeUuid, final long freeStorageSize,
4588 final int storageFlags, final IntentSender pi) {
4589 mContext.enforceCallingOrSelfPermission(
4590 android.Manifest.permission.CLEAR_APP_CACHE, TAG);
4591 mHandler.post(() -> {
4592 boolean success = false;
4594 freeStorage(volumeUuid, freeStorageSize, storageFlags);
4596 } catch (IOException e) {
4601 pi.sendIntent(null, success ? 1 : 0, null, null, null);
4602 } catch (SendIntentException e) {
4610 * Blocking call to clear various types of cached data across the system
4611 * until the requested bytes are available.
4613 public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
4614 final StorageManager storage = mContext.getSystemService(StorageManager.class);
4615 final File file = storage.findPathForUuid(volumeUuid);
4616 if (file.getUsableSpace() >= bytes) return;
4618 if (ENABLE_FREE_CACHE_V2) {
4619 final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
4621 final boolean aggressive = (storageFlags
4622 & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
4623 final long reservedBytes = storage.getStorageCacheBytes(file, storageFlags);
4625 // 1. Pre-flight to determine if we have any chance to succeed
4626 // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
4627 if (internalVolume && (aggressive || SystemProperties
4628 .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
4629 deletePreloadsFileCache();
4630 if (file.getUsableSpace() >= bytes) return;
4633 // 3. Consider parsed APK data (aggressive only)
4634 if (internalVolume && aggressive) {
4635 FileUtils.deleteContents(mCacheDir);
4636 if (file.getUsableSpace() >= bytes) return;
4639 // 4. Consider cached app data (above quotas)
4641 mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4642 Installer.FLAG_FREE_CACHE_V2);
4643 } catch (InstallerException ignored) {
4645 if (file.getUsableSpace() >= bytes) return;
4647 // 5. Consider shared libraries with refcount=0 and age>min cache period
4648 if (internalVolume && pruneUnusedStaticSharedLibraries(bytes,
4649 android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4650 Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
4651 DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD))) {
4655 // 6. Consider dexopt output (aggressive only)
4658 // 7. Consider installed instant apps unused longer than min cache period
4659 if (internalVolume && mInstantAppRegistry.pruneInstalledInstantApps(bytes,
4660 android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4661 Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4662 InstantAppRegistry.DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4666 // 8. Consider cached app data (below quotas)
4668 mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4669 Installer.FLAG_FREE_CACHE_V2 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
4670 } catch (InstallerException ignored) {
4672 if (file.getUsableSpace() >= bytes) return;
4674 // 9. Consider DropBox entries
4677 // 10. Consider instant meta-data (uninstalled apps) older that min cache period
4678 if (internalVolume && mInstantAppRegistry.pruneUninstalledInstantApps(bytes,
4679 android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4680 Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4681 InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4686 mInstaller.freeCache(volumeUuid, bytes, 0, 0);
4687 } catch (InstallerException ignored) {
4689 if (file.getUsableSpace() >= bytes) return;
4692 throw new IOException("Failed to free " + bytes + " on storage device at " + file);
4695 private boolean pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)
4696 throws IOException {
4697 final StorageManager storage = mContext.getSystemService(StorageManager.class);
4698 final File volume = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
4700 List<VersionedPackage> packagesToDelete = null;
4701 final long now = System.currentTimeMillis();
4703 synchronized (mPackages) {
4704 final int[] allUsers = sUserManager.getUserIds();
4705 final int libCount = mSharedLibraries.size();
4706 for (int i = 0; i < libCount; i++) {
4707 final LongSparseArray<SharedLibraryEntry> versionedLib
4708 = mSharedLibraries.valueAt(i);
4709 if (versionedLib == null) {
4712 final int versionCount = versionedLib.size();
4713 for (int j = 0; j < versionCount; j++) {
4714 SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4715 // Skip packages that are not static shared libs.
4716 if (!libInfo.isStatic()) {
4719 // Important: We skip static shared libs used for some user since
4720 // in such a case we need to keep the APK on the device. The check for
4721 // a lib being used for any user is performed by the uninstall call.
4722 final VersionedPackage declaringPackage = libInfo.getDeclaringPackage();
4723 // Resolve the package name - we use synthetic package names internally
4724 final String internalPackageName = resolveInternalPackageNameLPr(
4725 declaringPackage.getPackageName(),
4726 declaringPackage.getLongVersionCode());
4727 final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
4728 // Skip unused static shared libs cached less than the min period
4729 // to prevent pruning a lib needed by a subsequently installed package.
4730 if (ps == null || now - ps.lastUpdateTime < maxCachePeriod) {
4733 if (packagesToDelete == null) {
4734 packagesToDelete = new ArrayList<>();
4736 packagesToDelete.add(new VersionedPackage(internalPackageName,
4737 declaringPackage.getLongVersionCode()));
4742 if (packagesToDelete != null) {
4743 final int packageCount = packagesToDelete.size();
4744 for (int i = 0; i < packageCount; i++) {
4745 final VersionedPackage pkgToDelete = packagesToDelete.get(i);
4746 // Delete the package synchronously (will fail of the lib used for any user).
4747 if (deletePackageX(pkgToDelete.getPackageName(), pkgToDelete.getLongVersionCode(),
4748 UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS)
4749 == PackageManager.DELETE_SUCCEEDED) {
4750 if (volume.getUsableSpace() >= neededSpace) {
4761 * Update given flags based on encryption status of current user.
4763 private int updateFlags(int flags, int userId) {
4764 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4765 | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
4766 // Caller expressed an explicit opinion about what encryption
4767 // aware/unaware components they want to see, so fall through and
4768 // give them what they want
4770 // Caller expressed no opinion, so match based on user state
4771 if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
4772 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
4774 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
4780 private UserManagerInternal getUserManagerInternal() {
4781 if (mUserManagerInternal == null) {
4782 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
4784 return mUserManagerInternal;
4787 private ActivityManagerInternal getActivityManagerInternal() {
4788 if (mActivityManagerInternal == null) {
4789 mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
4791 return mActivityManagerInternal;
4795 private DeviceIdleController.LocalService getDeviceIdleController() {
4796 if (mDeviceIdleController == null) {
4797 mDeviceIdleController =
4798 LocalServices.getService(DeviceIdleController.LocalService.class);
4800 return mDeviceIdleController;
4804 * Update given flags when being used to request {@link PackageInfo}.
4806 private int updateFlagsForPackage(int flags, int userId, Object cookie) {
4807 final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
4808 boolean triaged = true;
4809 if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
4810 | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
4811 // Caller is asking for component details, so they'd better be
4812 // asking for specific encryption matching behavior, or be triaged
4813 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4814 | PackageManager.MATCH_DIRECT_BOOT_AWARE
4815 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4819 if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
4820 | PackageManager.MATCH_SYSTEM_ONLY
4821 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4824 if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
4825 // require the permission to be held; the calling uid and given user id referring
4826 // to the same user is not sufficient
4827 mPermissionManager.enforceCrossUserPermission(
4828 Binder.getCallingUid(), userId, false, false,
4829 !isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId),
4830 "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
4831 + Debug.getCallers(5));
4832 } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
4833 && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
4834 // If the caller wants all packages and has a restricted profile associated with it,
4835 // then match all users. This is to make sure that launchers that need to access work
4836 // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
4837 // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
4838 flags |= PackageManager.MATCH_ANY_USER;
4840 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4841 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4842 + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4844 return updateFlags(flags, userId);
4848 * Update given flags when being used to request {@link ApplicationInfo}.
4850 private int updateFlagsForApplication(int flags, int userId, Object cookie) {
4851 return updateFlagsForPackage(flags, userId, cookie);
4855 * Update given flags when being used to request {@link ComponentInfo}.
4857 private int updateFlagsForComponent(int flags, int userId, Object cookie) {
4858 if (cookie instanceof Intent) {
4859 if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
4860 flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
4864 boolean triaged = true;
4865 // Caller is asking for component details, so they'd better be
4866 // asking for specific encryption matching behavior, or be triaged
4867 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4868 | PackageManager.MATCH_DIRECT_BOOT_AWARE
4869 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4872 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4873 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4874 + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4877 return updateFlags(flags, userId);
4881 * Update given intent when being used to request {@link ResolveInfo}.
4883 private Intent updateIntentForResolve(Intent intent) {
4884 if (intent.getSelector() != null) {
4885 intent = intent.getSelector();
4887 if (DEBUG_PREFERRED) {
4888 intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4894 * Update given flags when being used to request {@link ResolveInfo}.
4895 * <p>Instant apps are resolved specially, depending upon context. Minimally,
4896 * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
4897 * flag set. However, this flag is only honoured in three circumstances:
4899 * <li>when called from a system process</li>
4900 * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
4901 * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
4902 * action and a {@code android.intent.category.BROWSABLE} category</li>
4905 int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid) {
4906 return updateFlagsForResolve(flags, userId, intent, callingUid,
4907 false /*wantInstantApps*/, false /*onlyExposedExplicitly*/);
4909 int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4910 boolean wantInstantApps) {
4911 return updateFlagsForResolve(flags, userId, intent, callingUid,
4912 wantInstantApps, false /*onlyExposedExplicitly*/);
4914 int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4915 boolean wantInstantApps, boolean onlyExposedExplicitly) {
4916 // Safe mode means we shouldn't match any third-party components
4918 flags |= PackageManager.MATCH_SYSTEM_ONLY;
4920 if (getInstantAppPackageName(callingUid) != null) {
4921 // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
4922 if (onlyExposedExplicitly) {
4923 flags |= PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY;
4925 flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4926 flags |= PackageManager.MATCH_INSTANT;
4928 final boolean wantMatchInstant = (flags & PackageManager.MATCH_INSTANT) != 0;
4929 final boolean allowMatchInstant = wantInstantApps
4930 || (wantMatchInstant && canViewInstantApps(callingUid, userId));
4931 flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
4932 | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
4933 if (!allowMatchInstant) {
4934 flags &= ~PackageManager.MATCH_INSTANT;
4937 return updateFlagsForComponent(flags, userId, intent /*cookie*/);
4941 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
4942 return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
4946 * Important: The provided filterCallingUid is used exclusively to filter out activities
4947 * that can be seen based on user state. It's typically the original caller uid prior
4948 * to clearing. Because it can only be provided by trusted code, it's value can be
4949 * trusted and will be used as-is; unlike userId which will be validated by this method.
4951 private ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
4952 int filterCallingUid, int userId) {
4953 if (!sUserManager.exists(userId)) return null;
4954 flags = updateFlagsForComponent(flags, userId, component);
4956 if (!isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId)) {
4957 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
4958 false /* requireFullPermission */, false /* checkShell */, "get activity info");
4961 synchronized (mPackages) {
4962 PackageParser.Activity a = mActivities.mActivities.get(component);
4964 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
4965 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4966 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4967 if (ps == null) return null;
4968 if (filterAppAccessLPr(ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) {
4971 return PackageParser.generateActivityInfo(
4972 a, flags, ps.readUserState(userId), userId);
4974 if (mResolveComponentName.equals(component)) {
4975 return PackageParser.generateActivityInfo(
4976 mResolveActivity, flags, new PackageUserState(), userId);
4982 private boolean isRecentsAccessingChildProfiles(int callingUid, int targetUserId) {
4983 if (!getActivityManagerInternal().isCallerRecents(callingUid)) {
4986 final long token = Binder.clearCallingIdentity();
4988 final int callingUserId = UserHandle.getUserId(callingUid);
4989 if (ActivityManager.getCurrentUser() != callingUserId) {
4992 return sUserManager.isSameProfileGroup(callingUserId, targetUserId);
4994 Binder.restoreCallingIdentity(token);
4999 public boolean activitySupportsIntent(ComponentName component, Intent intent,
5000 String resolvedType) {
5001 synchronized (mPackages) {
5002 if (component.equals(mResolveComponentName)) {
5003 // The resolver supports EVERYTHING!
5006 final int callingUid = Binder.getCallingUid();
5007 final int callingUserId = UserHandle.getUserId(callingUid);
5008 PackageParser.Activity a = mActivities.mActivities.get(component);
5012 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5016 if (filterAppAccessLPr(ps, callingUid, component, TYPE_ACTIVITY, callingUserId)) {
5019 for (int i=0; i<a.intents.size(); i++) {
5020 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
5021 intent.getData(), intent.getCategories(), TAG) >= 0) {
5030 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
5031 if (!sUserManager.exists(userId)) return null;
5032 final int callingUid = Binder.getCallingUid();
5033 flags = updateFlagsForComponent(flags, userId, component);
5034 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
5035 false /* requireFullPermission */, false /* checkShell */, "get receiver info");
5036 synchronized (mPackages) {
5037 PackageParser.Activity a = mReceivers.mActivities.get(component);
5038 if (DEBUG_PACKAGE_INFO) Log.v(
5039 TAG, "getReceiverInfo " + component + ": " + a);
5040 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
5041 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5042 if (ps == null) return null;
5043 if (filterAppAccessLPr(ps, callingUid, component, TYPE_RECEIVER, userId)) {
5046 return PackageParser.generateActivityInfo(
5047 a, flags, ps.readUserState(userId), userId);
5054 public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
5055 int flags, int userId) {
5056 if (!sUserManager.exists(userId)) return null;
5057 Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
5058 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5062 flags = updateFlagsForPackage(flags, userId, null);
5064 final boolean canSeeStaticLibraries =
5065 mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
5066 == PERMISSION_GRANTED
5067 || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
5068 == PERMISSION_GRANTED
5069 || canRequestPackageInstallsInternal(packageName,
5070 PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId,
5071 false /* throwIfPermNotDeclared*/)
5072 || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
5073 == PERMISSION_GRANTED;
5075 synchronized (mPackages) {
5076 List<SharedLibraryInfo> result = null;
5078 final int libCount = mSharedLibraries.size();
5079 for (int i = 0; i < libCount; i++) {
5080 LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
5081 if (versionedLib == null) {
5085 final int versionCount = versionedLib.size();
5086 for (int j = 0; j < versionCount; j++) {
5087 SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
5088 if (!canSeeStaticLibraries && libInfo.isStatic()) {
5091 final long identity = Binder.clearCallingIdentity();
5093 PackageInfo packageInfo = getPackageInfoVersioned(
5094 libInfo.getDeclaringPackage(), flags
5095 | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
5096 if (packageInfo == null) {
5100 Binder.restoreCallingIdentity(identity);
5103 SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(),
5104 libInfo.getLongVersion(), libInfo.getType(),
5105 libInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(libInfo,
5108 if (result == null) {
5109 result = new ArrayList<>();
5111 result.add(resLibInfo);
5115 return result != null ? new ParceledListSlice<>(result) : null;
5119 private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
5120 SharedLibraryInfo libInfo, int flags, int userId) {
5121 List<VersionedPackage> versionedPackages = null;
5122 final int packageCount = mSettings.mPackages.size();
5123 for (int i = 0; i < packageCount; i++) {
5124 PackageSetting ps = mSettings.mPackages.valueAt(i);
5130 if (!ps.getUserState().get(userId).isAvailable(flags)) {
5134 final String libName = libInfo.getName();
5135 if (libInfo.isStatic()) {
5136 final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
5140 if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getLongVersion()) {
5143 if (versionedPackages == null) {
5144 versionedPackages = new ArrayList<>();
5146 // If the dependent is a static shared lib, use the public package name
5147 String dependentPackageName = ps.name;
5148 if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) {
5149 dependentPackageName = ps.pkg.manifestPackageName;
5151 versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
5152 } else if (ps.pkg != null) {
5153 if (ArrayUtils.contains(ps.pkg.usesLibraries, libName)
5154 || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) {
5155 if (versionedPackages == null) {
5156 versionedPackages = new ArrayList<>();
5158 versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
5163 return versionedPackages;
5167 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
5168 if (!sUserManager.exists(userId)) return null;
5169 final int callingUid = Binder.getCallingUid();
5170 flags = updateFlagsForComponent(flags, userId, component);
5171 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
5172 false /* requireFullPermission */, false /* checkShell */, "get service info");
5173 synchronized (mPackages) {
5174 PackageParser.Service s = mServices.mServices.get(component);
5175 if (DEBUG_PACKAGE_INFO) Log.v(
5176 TAG, "getServiceInfo " + component + ": " + s);
5177 if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
5178 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5179 if (ps == null) return null;
5180 if (filterAppAccessLPr(ps, callingUid, component, TYPE_SERVICE, userId)) {
5183 return PackageParser.generateServiceInfo(
5184 s, flags, ps.readUserState(userId), userId);
5191 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
5192 if (!sUserManager.exists(userId)) return null;
5193 final int callingUid = Binder.getCallingUid();
5194 flags = updateFlagsForComponent(flags, userId, component);
5195 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
5196 false /* requireFullPermission */, false /* checkShell */, "get provider info");
5197 synchronized (mPackages) {
5198 PackageParser.Provider p = mProviders.mProviders.get(component);
5199 if (DEBUG_PACKAGE_INFO) Log.v(
5200 TAG, "getProviderInfo " + component + ": " + p);
5201 if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
5202 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5203 if (ps == null) return null;
5204 if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
5207 return PackageParser.generateProviderInfo(
5208 p, flags, ps.readUserState(userId), userId);
5215 public String[] getSystemSharedLibraryNames() {
5216 // allow instant applications
5217 synchronized (mPackages) {
5218 Set<String> libs = null;
5219 final int libCount = mSharedLibraries.size();
5220 for (int i = 0; i < libCount; i++) {
5221 LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
5222 if (versionedLib == null) {
5225 final int versionCount = versionedLib.size();
5226 for (int j = 0; j < versionCount; j++) {
5227 SharedLibraryEntry libEntry = versionedLib.valueAt(j);
5228 if (!libEntry.info.isStatic()) {
5230 libs = new ArraySet<>();
5232 libs.add(libEntry.info.getName());
5235 PackageSetting ps = mSettings.getPackageLPr(libEntry.apk);
5236 if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
5237 UserHandle.getUserId(Binder.getCallingUid()),
5238 PackageManager.MATCH_STATIC_SHARED_LIBRARIES)) {
5240 libs = new ArraySet<>();
5242 libs.add(libEntry.info.getName());
5249 String[] libsArray = new String[libs.size()];
5250 libs.toArray(libsArray);
5259 public @NonNull String getServicesSystemSharedLibraryPackageName() {
5260 // allow instant applications
5261 synchronized (mPackages) {
5262 return mServicesSystemSharedLibraryPackageName;
5267 public @NonNull String getSharedSystemSharedLibraryPackageName() {
5268 // allow instant applications
5269 synchronized (mPackages) {
5270 return mSharedSystemSharedLibraryPackageName;
5274 private void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
5275 for (int i = userList.length - 1; i >= 0; --i) {
5276 final int userId = userList[i];
5277 // don't add instant app to the list of updates
5278 if (pkgSetting.getInstantApp(userId)) {
5281 SparseArray<String> changedPackages = mChangedPackages.get(userId);
5282 if (changedPackages == null) {
5283 changedPackages = new SparseArray<>();
5284 mChangedPackages.put(userId, changedPackages);
5286 Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
5287 if (sequenceNumbers == null) {
5288 sequenceNumbers = new HashMap<>();
5289 mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
5291 final Integer sequenceNumber = sequenceNumbers.get(pkgSetting.name);
5292 if (sequenceNumber != null) {
5293 changedPackages.remove(sequenceNumber);
5295 changedPackages.put(mChangedPackagesSequenceNumber, pkgSetting.name);
5296 sequenceNumbers.put(pkgSetting.name, mChangedPackagesSequenceNumber);
5298 mChangedPackagesSequenceNumber++;
5302 public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
5303 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5306 synchronized (mPackages) {
5307 if (sequenceNumber >= mChangedPackagesSequenceNumber) {
5310 final SparseArray<String> changedPackages = mChangedPackages.get(userId);
5311 if (changedPackages == null) {
5314 final List<String> packageNames =
5315 new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
5316 for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
5317 final String packageName = changedPackages.get(i);
5318 if (packageName != null) {
5319 packageNames.add(packageName);
5322 return packageNames.isEmpty()
5323 ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
5328 public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
5329 // allow instant applications
5330 ArrayList<FeatureInfo> res;
5331 synchronized (mAvailableFeatures) {
5332 res = new ArrayList<>(mAvailableFeatures.size() + 1);
5333 res.addAll(mAvailableFeatures.values());
5335 final FeatureInfo fi = new FeatureInfo();
5336 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
5337 FeatureInfo.GL_ES_VERSION_UNDEFINED);
5340 return new ParceledListSlice<>(res);
5344 public boolean hasSystemFeature(String name, int version) {
5345 // allow instant applications
5346 synchronized (mAvailableFeatures) {
5347 final FeatureInfo feat = mAvailableFeatures.get(name);
5351 return feat.version >= version;
5357 public int checkPermission(String permName, String pkgName, int userId) {
5358 return mPermissionManager.checkPermission(permName, pkgName, getCallingUid(), userId);
5362 public int checkUidPermission(String permName, int uid) {
5363 synchronized (mPackages) {
5364 final String[] packageNames = getPackagesForUid(uid);
5365 final PackageParser.Package pkg = (packageNames != null && packageNames.length > 0)
5366 ? mPackages.get(packageNames[0])
5368 return mPermissionManager.checkUidPermission(permName, pkg, uid, getCallingUid());
5373 public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
5374 if (UserHandle.getCallingUserId() != userId) {
5375 mContext.enforceCallingPermission(
5376 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5377 "isPermissionRevokedByPolicy for user " + userId);
5380 if (checkPermission(permission, packageName, userId)
5381 == PackageManager.PERMISSION_GRANTED) {
5385 final int callingUid = Binder.getCallingUid();
5386 if (getInstantAppPackageName(callingUid) != null) {
5387 if (!isCallerSameApp(packageName, callingUid)) {
5391 if (isInstantApp(packageName, userId)) {
5396 final long identity = Binder.clearCallingIdentity();
5398 final int flags = getPermissionFlags(permission, packageName, userId);
5399 return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
5401 Binder.restoreCallingIdentity(identity);
5406 public String getPermissionControllerPackageName() {
5407 synchronized (mPackages) {
5408 return mRequiredInstallerPackage;
5412 private boolean addDynamicPermission(PermissionInfo info, final boolean async) {
5413 return mPermissionManager.addDynamicPermission(
5414 info, async, getCallingUid(), new PermissionCallback() {
5416 public void onPermissionChanged() {
5418 mSettings.writeLPr();
5420 scheduleWriteSettingsLocked();
5427 public boolean addPermission(PermissionInfo info) {
5428 synchronized (mPackages) {
5429 return addDynamicPermission(info, false);
5434 public boolean addPermissionAsync(PermissionInfo info) {
5435 synchronized (mPackages) {
5436 return addDynamicPermission(info, true);
5441 public void removePermission(String permName) {
5442 mPermissionManager.removeDynamicPermission(permName, getCallingUid(), mPermissionCallback);
5446 public void grantRuntimePermission(String packageName, String permName, final int userId) {
5447 mPermissionManager.grantRuntimePermission(permName, packageName, false /*overridePolicy*/,
5448 getCallingUid(), userId, mPermissionCallback);
5452 public void revokeRuntimePermission(String packageName, String permName, int userId) {
5453 mPermissionManager.revokeRuntimePermission(permName, packageName, false /*overridePolicy*/,
5454 getCallingUid(), userId, mPermissionCallback);
5458 public void resetRuntimePermissions() {
5459 mContext.enforceCallingOrSelfPermission(
5460 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5461 "revokeRuntimePermission");
5463 int callingUid = Binder.getCallingUid();
5464 if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5465 mContext.enforceCallingOrSelfPermission(
5466 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5467 "resetRuntimePermissions");
5470 synchronized (mPackages) {
5471 mPermissionManager.updateAllPermissions(
5472 StorageManager.UUID_PRIVATE_INTERNAL, false, mPackages.values(),
5473 mPermissionCallback);
5474 for (int userId : UserManagerService.getInstance().getUserIds()) {
5475 final int packageCount = mPackages.size();
5476 for (int i = 0; i < packageCount; i++) {
5477 PackageParser.Package pkg = mPackages.valueAt(i);
5478 if (!(pkg.mExtras instanceof PackageSetting)) {
5481 PackageSetting ps = (PackageSetting) pkg.mExtras;
5482 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
5489 public int getPermissionFlags(String permName, String packageName, int userId) {
5490 return mPermissionManager.getPermissionFlags(
5491 permName, packageName, getCallingUid(), userId);
5495 public void updatePermissionFlags(String permName, String packageName, int flagMask,
5496 int flagValues, int userId) {
5497 mPermissionManager.updatePermissionFlags(
5498 permName, packageName, flagMask, flagValues, getCallingUid(), userId,
5499 mPermissionCallback);
5503 * Update the permission flags for all packages and runtime permissions of a user in order
5504 * to allow device or profile owner to remove POLICY_FIXED.
5507 public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
5508 synchronized (mPackages) {
5509 final boolean changed = mPermissionManager.updatePermissionFlagsForAllApps(
5510 flagMask, flagValues, getCallingUid(), userId, mPackages.values(),
5511 mPermissionCallback);
5513 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5519 public boolean shouldShowRequestPermissionRationale(String permissionName,
5520 String packageName, int userId) {
5521 if (UserHandle.getCallingUserId() != userId) {
5522 mContext.enforceCallingPermission(
5523 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5524 "canShowRequestPermissionRationale for user " + userId);
5527 final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
5528 if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
5532 if (checkPermission(permissionName, packageName, userId)
5533 == PackageManager.PERMISSION_GRANTED) {
5539 final long identity = Binder.clearCallingIdentity();
5541 flags = getPermissionFlags(permissionName,
5542 packageName, userId);
5544 Binder.restoreCallingIdentity(identity);
5547 final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
5548 | PackageManager.FLAG_PERMISSION_POLICY_FIXED
5549 | PackageManager.FLAG_PERMISSION_USER_FIXED;
5551 if ((flags & fixedFlags) != 0) {
5555 return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
5559 public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5560 mContext.enforceCallingOrSelfPermission(
5561 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
5562 "addOnPermissionsChangeListener");
5564 synchronized (mPackages) {
5565 mOnPermissionChangeListeners.addListenerLocked(listener);
5570 public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5571 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5572 throw new SecurityException("Instant applications don't have access to this method");
5574 synchronized (mPackages) {
5575 mOnPermissionChangeListeners.removeListenerLocked(listener);
5580 public boolean isProtectedBroadcast(String actionName) {
5581 // allow instant applications
5582 synchronized (mProtectedBroadcasts) {
5583 if (mProtectedBroadcasts.contains(actionName)) {
5585 } else if (actionName != null) {
5586 // TODO: remove these terrible hacks
5587 if (actionName.startsWith("android.net.netmon.lingerExpired")
5588 || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
5589 || actionName.startsWith("com.android.internal.telephony.data-reconnect")
5590 || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
5599 public int checkSignatures(String pkg1, String pkg2) {
5600 synchronized (mPackages) {
5601 final PackageParser.Package p1 = mPackages.get(pkg1);
5602 final PackageParser.Package p2 = mPackages.get(pkg2);
5603 if (p1 == null || p1.mExtras == null
5604 || p2 == null || p2.mExtras == null) {
5605 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5607 final int callingUid = Binder.getCallingUid();
5608 final int callingUserId = UserHandle.getUserId(callingUid);
5609 final PackageSetting ps1 = (PackageSetting) p1.mExtras;
5610 final PackageSetting ps2 = (PackageSetting) p2.mExtras;
5611 if (filterAppAccessLPr(ps1, callingUid, callingUserId)
5612 || filterAppAccessLPr(ps2, callingUid, callingUserId)) {
5613 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5615 return compareSignatures(p1.mSigningDetails.signatures, p2.mSigningDetails.signatures);
5620 public int checkUidSignatures(int uid1, int uid2) {
5621 final int callingUid = Binder.getCallingUid();
5622 final int callingUserId = UserHandle.getUserId(callingUid);
5623 final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5624 // Map to base uids.
5625 uid1 = UserHandle.getAppId(uid1);
5626 uid2 = UserHandle.getAppId(uid2);
5628 synchronized (mPackages) {
5631 Object obj = mSettings.getUserIdLPr(uid1);
5633 if (obj instanceof SharedUserSetting) {
5634 if (isCallerInstantApp) {
5635 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5637 s1 = ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
5638 } else if (obj instanceof PackageSetting) {
5639 final PackageSetting ps = (PackageSetting) obj;
5640 if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5641 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5643 s1 = ps.signatures.mSigningDetails.signatures;
5645 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5648 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5650 obj = mSettings.getUserIdLPr(uid2);
5652 if (obj instanceof SharedUserSetting) {
5653 if (isCallerInstantApp) {
5654 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5656 s2 = ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
5657 } else if (obj instanceof PackageSetting) {
5658 final PackageSetting ps = (PackageSetting) obj;
5659 if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5660 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5662 s2 = ps.signatures.mSigningDetails.signatures;
5664 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5667 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5669 return compareSignatures(s1, s2);
5674 public boolean hasSigningCertificate(
5675 String packageName, byte[] certificate, @PackageManager.CertificateInputType int type) {
5677 synchronized (mPackages) {
5678 final PackageParser.Package p = mPackages.get(packageName);
5679 if (p == null || p.mExtras == null) {
5682 final int callingUid = Binder.getCallingUid();
5683 final int callingUserId = UserHandle.getUserId(callingUid);
5684 final PackageSetting ps = (PackageSetting) p.mExtras;
5685 if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5689 case CERT_INPUT_RAW_X509:
5690 return p.mSigningDetails.hasCertificate(certificate);
5691 case CERT_INPUT_SHA256:
5692 return p.mSigningDetails.hasSha256Certificate(certificate);
5700 public boolean hasUidSigningCertificate(
5701 int uid, byte[] certificate, @PackageManager.CertificateInputType int type) {
5702 final int callingUid = Binder.getCallingUid();
5703 final int callingUserId = UserHandle.getUserId(callingUid);
5704 // Map to base uids.
5705 uid = UserHandle.getAppId(uid);
5707 synchronized (mPackages) {
5708 final PackageParser.SigningDetails signingDetails;
5709 final Object obj = mSettings.getUserIdLPr(uid);
5711 if (obj instanceof SharedUserSetting) {
5712 final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5713 if (isCallerInstantApp) {
5716 signingDetails = ((SharedUserSetting)obj).signatures.mSigningDetails;
5717 } else if (obj instanceof PackageSetting) {
5718 final PackageSetting ps = (PackageSetting) obj;
5719 if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5722 signingDetails = ps.signatures.mSigningDetails;
5730 case CERT_INPUT_RAW_X509:
5731 return signingDetails.hasCertificate(certificate);
5732 case CERT_INPUT_SHA256:
5733 return signingDetails.hasSha256Certificate(certificate);
5741 * This method should typically only be used when granting or revoking
5742 * permissions, since the app may immediately restart after this call.
5744 * If you're doing surgery on app code/data, use {@link PackageFreezer} to
5745 * guard your work against the app being relaunched.
5747 private void killUid(int appId, int userId, String reason) {
5748 final long identity = Binder.clearCallingIdentity();
5750 IActivityManager am = ActivityManager.getService();
5753 am.killUid(appId, userId, reason);
5754 } catch (RemoteException e) {
5755 /* ignore - same process */
5759 Binder.restoreCallingIdentity(identity);
5764 * If the database version for this type of package (internal storage or
5765 * external storage) is less than the version where package signatures
5766 * were updated, return true.
5768 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5769 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5770 return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
5773 private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5774 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5775 return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
5779 public List<String> getAllPackages() {
5780 final int callingUid = Binder.getCallingUid();
5781 final int callingUserId = UserHandle.getUserId(callingUid);
5782 synchronized (mPackages) {
5783 if (canViewInstantApps(callingUid, callingUserId)) {
5784 return new ArrayList<String>(mPackages.keySet());
5786 final String instantAppPkgName = getInstantAppPackageName(callingUid);
5787 final List<String> result = new ArrayList<>();
5788 if (instantAppPkgName != null) {
5789 // caller is an instant application; filter unexposed applications
5790 for (PackageParser.Package pkg : mPackages.values()) {
5791 if (!pkg.visibleToInstantApps) {
5794 result.add(pkg.packageName);
5797 // caller is a normal application; filter instant applications
5798 for (PackageParser.Package pkg : mPackages.values()) {
5799 final PackageSetting ps =
5800 pkg.mExtras != null ? (PackageSetting) pkg.mExtras : null;
5802 && ps.getInstantApp(callingUserId)
5803 && !mInstantAppRegistry.isInstantAccessGranted(
5804 callingUserId, UserHandle.getAppId(callingUid), ps.appId)) {
5807 result.add(pkg.packageName);
5815 public String[] getPackagesForUid(int uid) {
5816 final int callingUid = Binder.getCallingUid();
5817 final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5818 final int userId = UserHandle.getUserId(uid);
5819 uid = UserHandle.getAppId(uid);
5821 synchronized (mPackages) {
5822 Object obj = mSettings.getUserIdLPr(uid);
5823 if (obj instanceof SharedUserSetting) {
5824 if (isCallerInstantApp) {
5827 final SharedUserSetting sus = (SharedUserSetting) obj;
5828 final int N = sus.packages.size();
5829 String[] res = new String[N];
5830 final Iterator<PackageSetting> it = sus.packages.iterator();
5832 while (it.hasNext()) {
5833 PackageSetting ps = it.next();
5834 if (ps.getInstalled(userId)) {
5837 res = ArrayUtils.removeElement(String.class, res, res[i]);
5841 } else if (obj instanceof PackageSetting) {
5842 final PackageSetting ps = (PackageSetting) obj;
5843 if (ps.getInstalled(userId) && !filterAppAccessLPr(ps, callingUid, userId)) {
5844 return new String[]{ps.name};
5852 public String getNameForUid(int uid) {
5853 final int callingUid = Binder.getCallingUid();
5854 if (getInstantAppPackageName(callingUid) != null) {
5857 synchronized (mPackages) {
5858 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5859 if (obj instanceof SharedUserSetting) {
5860 final SharedUserSetting sus = (SharedUserSetting) obj;
5861 return sus.name + ":" + sus.userId;
5862 } else if (obj instanceof PackageSetting) {
5863 final PackageSetting ps = (PackageSetting) obj;
5864 if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5874 public String[] getNamesForUids(int[] uids) {
5875 if (uids == null || uids.length == 0) {
5878 final int callingUid = Binder.getCallingUid();
5879 if (getInstantAppPackageName(callingUid) != null) {
5882 final String[] names = new String[uids.length];
5883 synchronized (mPackages) {
5884 for (int i = uids.length - 1; i >= 0; i--) {
5885 final int uid = uids[i];
5886 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5887 if (obj instanceof SharedUserSetting) {
5888 final SharedUserSetting sus = (SharedUserSetting) obj;
5889 names[i] = "shared:" + sus.name;
5890 } else if (obj instanceof PackageSetting) {
5891 final PackageSetting ps = (PackageSetting) obj;
5892 if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5906 public int getUidForSharedUser(String sharedUserName) {
5907 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5910 if (sharedUserName == null) {
5914 synchronized (mPackages) {
5915 SharedUserSetting suid;
5917 suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
5921 } catch (PackageManagerException ignore) {
5922 // can't happen, but, still need to catch it
5929 public int getFlagsForUid(int uid) {
5930 final int callingUid = Binder.getCallingUid();
5931 if (getInstantAppPackageName(callingUid) != null) {
5934 synchronized (mPackages) {
5935 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5936 if (obj instanceof SharedUserSetting) {
5937 final SharedUserSetting sus = (SharedUserSetting) obj;
5938 return sus.pkgFlags;
5939 } else if (obj instanceof PackageSetting) {
5940 final PackageSetting ps = (PackageSetting) obj;
5941 if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5951 public int getPrivateFlagsForUid(int uid) {
5952 final int callingUid = Binder.getCallingUid();
5953 if (getInstantAppPackageName(callingUid) != null) {
5956 synchronized (mPackages) {
5957 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5958 if (obj instanceof SharedUserSetting) {
5959 final SharedUserSetting sus = (SharedUserSetting) obj;
5960 return sus.pkgPrivateFlags;
5961 } else if (obj instanceof PackageSetting) {
5962 final PackageSetting ps = (PackageSetting) obj;
5963 if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5966 return ps.pkgPrivateFlags;
5973 public boolean isUidPrivileged(int uid) {
5974 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5977 uid = UserHandle.getAppId(uid);
5979 synchronized (mPackages) {
5980 Object obj = mSettings.getUserIdLPr(uid);
5981 if (obj instanceof SharedUserSetting) {
5982 final SharedUserSetting sus = (SharedUserSetting) obj;
5983 final Iterator<PackageSetting> it = sus.packages.iterator();
5984 while (it.hasNext()) {
5985 if (it.next().isPrivileged()) {
5989 } else if (obj instanceof PackageSetting) {
5990 final PackageSetting ps = (PackageSetting) obj;
5991 return ps.isPrivileged();
5998 public String[] getAppOpPermissionPackages(String permName) {
5999 return mPermissionManager.getAppOpPermissionPackages(permName);
6003 public ResolveInfo resolveIntent(Intent intent, String resolvedType,
6004 int flags, int userId) {
6005 return resolveIntentInternal(intent, resolvedType, flags, userId, false,
6006 Binder.getCallingUid());
6010 * Normally instant apps can only be resolved when they're visible to the caller.
6011 * However, if {@code resolveForStart} is {@code true}, all instant apps are visible
6012 * since we need to allow the system to start any installed application.
6014 private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
6015 int flags, int userId, boolean resolveForStart, int filterCallingUid) {
6017 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
6019 if (!sUserManager.exists(userId)) return null;
6020 final int callingUid = Binder.getCallingUid();
6021 flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart);
6022 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
6023 false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
6025 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6026 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
6027 flags, filterCallingUid, userId, resolveForStart, true /*allowDynamicSplits*/);
6028 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6030 final ResolveInfo bestChoice =
6031 chooseBestActivity(intent, resolvedType, flags, query, userId);
6034 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6039 public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
6040 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
6041 throw new SecurityException(
6042 "findPersistentPreferredActivity can only be run by the system");
6044 if (!sUserManager.exists(userId)) {
6047 final int callingUid = Binder.getCallingUid();
6048 intent = updateIntentForResolve(intent);
6049 final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
6050 final int flags = updateFlagsForResolve(
6051 0, userId, intent, callingUid, false /*includeInstantApps*/);
6052 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6054 synchronized (mPackages) {
6055 return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
6061 public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
6062 IntentFilter filter, int match, ComponentName activity) {
6063 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6066 final int userId = UserHandle.getCallingUserId();
6067 if (DEBUG_PREFERRED) {
6068 Log.v(TAG, "setLastChosenActivity intent=" + intent
6069 + " resolvedType=" + resolvedType
6071 + " filter=" + filter
6073 + " activity=" + activity);
6074 filter.dump(new PrintStreamPrinter(System.out), " ");
6076 intent.setComponent(null);
6077 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6079 // Find any earlier preferred or last chosen entries and nuke them
6080 findPreferredActivity(intent, resolvedType,
6081 flags, query, 0, false, true, false, userId);
6082 // Add the new activity as the last chosen for this filter
6083 addPreferredActivityInternal(filter, match, null, activity, false, userId,
6084 "Setting last chosen");
6088 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
6089 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6092 final int userId = UserHandle.getCallingUserId();
6093 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
6094 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6096 return findPreferredActivity(intent, resolvedType, flags, query, 0,
6097 false, false, false, userId);
6101 * Returns whether or not instant apps have been disabled remotely.
6103 private boolean areWebInstantAppsDisabled() {
6104 return mWebInstantAppsDisabled;
6107 private boolean isInstantAppResolutionAllowed(
6108 Intent intent, List<ResolveInfo> resolvedActivities, int userId,
6109 boolean skipPackageCheck) {
6110 if (mInstantAppResolverConnection == null) {
6113 if (mInstantAppInstallerActivity == null) {
6116 if (intent.getComponent() != null) {
6119 if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
6122 if (!skipPackageCheck && intent.getPackage() != null) {
6125 if (!intent.isWebIntent()) {
6126 // for non web intents, we should not resolve externally if an app already exists to
6127 // handle it or if the caller didn't explicitly request it.
6128 if ((resolvedActivities != null && resolvedActivities.size() != 0)
6129 || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) == 0) {
6133 if (intent.getData() == null || TextUtils.isEmpty(intent.getData().getHost())) {
6135 } else if (areWebInstantAppsDisabled()) {
6139 // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
6140 // Or if there's already an ephemeral app installed that handles the action
6141 synchronized (mPackages) {
6142 final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
6143 for (int n = 0; n < count; n++) {
6144 final ResolveInfo info = resolvedActivities.get(n);
6145 final String packageName = info.activityInfo.packageName;
6146 final PackageSetting ps = mSettings.mPackages.get(packageName);
6148 // only check domain verification status if the app is not a browser
6149 if (!info.handleAllWebDataURI) {
6150 // Try to get the status from User settings first
6151 final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6152 final int status = (int) (packedStatus >> 32);
6153 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
6154 || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6155 if (DEBUG_INSTANT) {
6156 Slog.v(TAG, "DENY instant app;"
6157 + " pkg: " + packageName + ", status: " + status);
6162 if (ps.getInstantApp(userId)) {
6163 if (DEBUG_INSTANT) {
6164 Slog.v(TAG, "DENY instant app installed;"
6165 + " pkg: " + packageName);
6172 // We've exhausted all ways to deny ephemeral application; let the system look for them.
6176 private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
6177 Intent origIntent, String resolvedType, String callingPackage,
6178 Bundle verificationBundle, int userId) {
6179 final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
6180 new InstantAppRequest(responseObj, origIntent, resolvedType,
6181 callingPackage, userId, verificationBundle, false /*resolveForStart*/));
6182 mHandler.sendMessage(msg);
6185 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
6186 int flags, List<ResolveInfo> query, int userId) {
6187 if (query != null) {
6188 final int N = query.size();
6190 return query.get(0);
6192 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
6193 // If there is more than one activity with the same priority,
6194 // then let the user decide between them.
6195 ResolveInfo r0 = query.get(0);
6196 ResolveInfo r1 = query.get(1);
6197 if (DEBUG_INTENT_MATCHING || debug) {
6198 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
6199 + r1.activityInfo.name + "=" + r1.priority);
6201 // If the first activity has a higher priority, or a different
6202 // default, then it is always desirable to pick it.
6203 if (r0.priority != r1.priority
6204 || r0.preferredOrder != r1.preferredOrder
6205 || r0.isDefault != r1.isDefault) {
6206 return query.get(0);
6208 // If we have saved a preference for a preferred activity for
6209 // this Intent, use that.
6210 ResolveInfo ri = findPreferredActivity(intent, resolvedType,
6211 flags, query, r0.priority, true, false, debug, userId);
6215 // If we have an ephemeral app, use it
6216 for (int i = 0; i < N; i++) {
6218 if (ri.activityInfo.applicationInfo.isInstantApp()) {
6219 final String packageName = ri.activityInfo.packageName;
6220 final PackageSetting ps = mSettings.mPackages.get(packageName);
6221 final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6222 final int status = (int)(packedStatus >> 32);
6223 if (status != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6228 ri = new ResolveInfo(mResolveInfo);
6229 ri.activityInfo = new ActivityInfo(ri.activityInfo);
6230 ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
6231 // If all of the options come from the same package, show the application's
6232 // label and icon instead of the generic resolver's.
6233 // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
6234 // and then throw away the ResolveInfo itself, meaning that the caller loses
6235 // the resolvePackageName. Therefore the activityInfo.labelRes above provides
6236 // a fallback for this case; we only set the target package's resources on
6237 // the ResolveInfo, not the ActivityInfo.
6238 final String intentPackage = intent.getPackage();
6239 if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
6240 final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
6241 ri.resolvePackageName = intentPackage;
6242 if (userNeedsBadging(userId)) {
6243 ri.noResourceId = true;
6245 ri.icon = appi.icon;
6247 ri.iconResourceId = appi.icon;
6248 ri.labelRes = appi.labelRes;
6250 ri.activityInfo.applicationInfo = new ApplicationInfo(
6251 ri.activityInfo.applicationInfo);
6253 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
6254 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
6256 // Make sure that the resolver is displayable in car mode
6257 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
6258 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
6266 * Return true if the given list is not empty and all of its contents have
6267 * an activityInfo with the given package name.
6269 private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
6270 if (ArrayUtils.isEmpty(list)) {
6273 for (int i = 0, N = list.size(); i < N; i++) {
6274 final ResolveInfo ri = list.get(i);
6275 final ActivityInfo ai = ri != null ? ri.activityInfo : null;
6276 if (ai == null || !packageName.equals(ai.packageName)) {
6283 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
6284 int flags, List<ResolveInfo> query, boolean debug, int userId) {
6285 final int N = query.size();
6286 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
6288 // Get the list of persistent preferred activities that handle the intent
6289 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
6290 List<PersistentPreferredActivity> pprefs = ppir != null
6291 ? ppir.queryIntent(intent, resolvedType,
6292 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6295 if (pprefs != null && pprefs.size() > 0) {
6296 final int M = pprefs.size();
6297 for (int i=0; i<M; i++) {
6298 final PersistentPreferredActivity ppa = pprefs.get(i);
6299 if (DEBUG_PREFERRED || debug) {
6300 Slog.v(TAG, "Checking PersistentPreferredActivity ds="
6301 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
6302 + "\n component=" + ppa.mComponent);
6303 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
6305 final ActivityInfo ai = getActivityInfo(ppa.mComponent,
6306 flags | MATCH_DISABLED_COMPONENTS, userId);
6307 if (DEBUG_PREFERRED || debug) {
6308 Slog.v(TAG, "Found persistent preferred activity:");
6310 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
6312 Slog.v(TAG, " null");
6316 // This previously registered persistent preferred activity
6317 // component is no longer known. Ignore it and do NOT remove it.
6320 for (int j=0; j<N; j++) {
6321 final ResolveInfo ri = query.get(j);
6322 if (!ri.activityInfo.applicationInfo.packageName
6323 .equals(ai.applicationInfo.packageName)) {
6326 if (!ri.activityInfo.name.equals(ai.name)) {
6329 // Found a persistent preference that can handle the intent.
6330 if (DEBUG_PREFERRED || debug) {
6331 Slog.v(TAG, "Returning persistent preferred activity: " +
6332 ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6341 // TODO: handle preferred activities missing while user has amnesia
6342 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
6343 List<ResolveInfo> query, int priority, boolean always,
6344 boolean removeMatches, boolean debug, int userId) {
6345 if (!sUserManager.exists(userId)) return null;
6346 final int callingUid = Binder.getCallingUid();
6347 flags = updateFlagsForResolve(
6348 flags, userId, intent, callingUid, false /*includeInstantApps*/);
6349 intent = updateIntentForResolve(intent);
6351 synchronized (mPackages) {
6352 // Try to find a matching persistent preferred activity.
6353 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
6356 // If a persistent preferred activity matched, use it.
6361 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
6362 // Get the list of preferred activities that handle the intent
6363 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
6364 List<PreferredActivity> prefs = pir != null
6365 ? pir.queryIntent(intent, resolvedType,
6366 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6369 if (prefs != null && prefs.size() > 0) {
6370 boolean changed = false;
6372 // First figure out how good the original match set is.
6373 // We will only allow preferred activities that came
6374 // from the same match quality.
6377 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
6379 final int N = query.size();
6380 for (int j=0; j<N; j++) {
6381 final ResolveInfo ri = query.get(j);
6382 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
6383 + ": 0x" + Integer.toHexString(match));
6384 if (ri.match > match) {
6389 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
6390 + Integer.toHexString(match));
6392 match &= IntentFilter.MATCH_CATEGORY_MASK;
6393 final int M = prefs.size();
6394 for (int i=0; i<M; i++) {
6395 final PreferredActivity pa = prefs.get(i);
6396 if (DEBUG_PREFERRED || debug) {
6397 Slog.v(TAG, "Checking PreferredActivity ds="
6398 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
6399 + "\n component=" + pa.mPref.mComponent);
6400 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
6402 if (pa.mPref.mMatch != match) {
6403 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
6404 + Integer.toHexString(pa.mPref.mMatch));
6407 // If it's not an "always" type preferred activity and that's what we're
6408 // looking for, skip it.
6409 if (always && !pa.mPref.mAlways) {
6410 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
6413 final ActivityInfo ai = getActivityInfo(
6414 pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
6415 | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
6417 if (DEBUG_PREFERRED || debug) {
6418 Slog.v(TAG, "Found preferred activity:");
6420 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
6422 Slog.v(TAG, " null");
6426 // This previously registered preferred activity
6427 // component is no longer known. Most likely an update
6428 // to the app was installed and in the new version this
6429 // component no longer exists. Clean it up by removing
6430 // it from the preferred activities list, and skip it.
6431 Slog.w(TAG, "Removing dangling preferred activity: "
6432 + pa.mPref.mComponent);
6433 pir.removeFilter(pa);
6437 for (int j=0; j<N; j++) {
6438 final ResolveInfo ri = query.get(j);
6439 if (!ri.activityInfo.applicationInfo.packageName
6440 .equals(ai.applicationInfo.packageName)) {
6443 if (!ri.activityInfo.name.equals(ai.name)) {
6447 if (removeMatches) {
6448 pir.removeFilter(pa);
6450 if (DEBUG_PREFERRED) {
6451 Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
6456 // Okay we found a previously set preferred or last chosen app.
6457 // If the result set is different from when this
6458 // was created, and is not a subset of the preferred set, we need to
6459 // clear it and re-ask the user their preference, if we're looking for
6460 // an "always" type entry.
6461 if (always && !pa.mPref.sameSet(query)) {
6462 if (pa.mPref.isSuperset(query)) {
6463 // some components of the set are no longer present in
6464 // the query, but the preferred activity can still be reused
6465 if (DEBUG_PREFERRED) {
6466 Slog.i(TAG, "Result set changed, but PreferredActivity is"
6467 + " still valid as only non-preferred components"
6468 + " were removed for " + intent + " type "
6471 // remove obsolete components and re-add the up-to-date filter
6472 PreferredActivity freshPa = new PreferredActivity(pa,
6474 pa.mPref.discardObsoleteComponents(query),
6475 pa.mPref.mComponent,
6477 pir.removeFilter(pa);
6478 pir.addFilter(freshPa);
6482 "Result set changed, dropping preferred activity for "
6483 + intent + " type " + resolvedType);
6484 if (DEBUG_PREFERRED) {
6485 Slog.v(TAG, "Removing preferred activity since set changed "
6486 + pa.mPref.mComponent);
6488 pir.removeFilter(pa);
6489 // Re-add the filter as a "last chosen" entry (!always)
6490 PreferredActivity lastChosen = new PreferredActivity(
6491 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
6492 pir.addFilter(lastChosen);
6498 // Yay! Either the set matched or we're looking for the last chosen
6499 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
6500 + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6506 if (DEBUG_PREFERRED) {
6507 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
6509 scheduleWritePackageRestrictionsLocked(userId);
6514 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
6519 * Returns if intent can be forwarded from the sourceUserId to the targetUserId
6522 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
6524 mContext.enforceCallingOrSelfPermission(
6525 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
6526 List<CrossProfileIntentFilter> matches =
6527 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
6528 if (matches != null) {
6529 int size = matches.size();
6530 for (int i = 0; i < size; i++) {
6531 if (matches.get(i).getTargetUserId() == targetUserId) return true;
6534 if (intent.hasWebURI()) {
6535 // cross-profile app linking works only towards the parent.
6536 final int callingUid = Binder.getCallingUid();
6537 final UserInfo parent = getProfileParent(sourceUserId);
6538 synchronized(mPackages) {
6539 int flags = updateFlagsForResolve(0, parent.id, intent, callingUid,
6540 false /*includeInstantApps*/);
6541 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
6542 intent, resolvedType, flags, sourceUserId, parent.id);
6543 return xpDomainInfo != null;
6549 private UserInfo getProfileParent(int userId) {
6550 final long identity = Binder.clearCallingIdentity();
6552 return sUserManager.getProfileParent(userId);
6554 Binder.restoreCallingIdentity(identity);
6558 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
6559 String resolvedType, int userId) {
6560 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
6561 if (resolver != null) {
6562 return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
6568 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
6569 String resolvedType, int flags, int userId) {
6571 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6573 return new ParceledListSlice<>(
6574 queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
6576 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6581 * Returns the package name of the calling Uid if it's an instant app. If it isn't
6582 * instant, returns {@code null}.
6584 private String getInstantAppPackageName(int callingUid) {
6585 synchronized (mPackages) {
6586 // If the caller is an isolated app use the owner's uid for the lookup.
6587 if (Process.isIsolated(callingUid)) {
6588 callingUid = mIsolatedOwners.get(callingUid);
6590 final int appId = UserHandle.getAppId(callingUid);
6591 final Object obj = mSettings.getUserIdLPr(appId);
6592 if (obj instanceof PackageSetting) {
6593 final PackageSetting ps = (PackageSetting) obj;
6594 final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
6595 return isInstantApp ? ps.pkg.packageName : null;
6601 private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6602 String resolvedType, int flags, int userId) {
6603 return queryIntentActivitiesInternal(
6604 intent, resolvedType, flags, Binder.getCallingUid(), userId,
6605 false /*resolveForStart*/, true /*allowDynamicSplits*/);
6608 private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6609 String resolvedType, int flags, int filterCallingUid, int userId,
6610 boolean resolveForStart, boolean allowDynamicSplits) {
6611 if (!sUserManager.exists(userId)) return Collections.emptyList();
6612 final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
6613 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
6614 false /* requireFullPermission */, false /* checkShell */,
6615 "query intent activities");
6616 final String pkgName = intent.getPackage();
6617 ComponentName comp = intent.getComponent();
6619 if (intent.getSelector() != null) {
6620 intent = intent.getSelector();
6621 comp = intent.getComponent();
6625 flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart,
6626 comp != null || pkgName != null /*onlyExposedExplicitly*/);
6628 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6629 final ActivityInfo ai = getActivityInfo(comp, flags, userId);
6631 // When specifying an explicit component, we prevent the activity from being
6632 // used when either 1) the calling package is normal and the activity is within
6633 // an ephemeral application or 2) the calling package is ephemeral and the
6634 // activity is not visible to ephemeral applications.
6635 final boolean matchInstantApp =
6636 (flags & PackageManager.MATCH_INSTANT) != 0;
6637 final boolean matchVisibleToInstantAppOnly =
6638 (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
6639 final boolean matchExplicitlyVisibleOnly =
6640 (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
6641 final boolean isCallerInstantApp =
6642 instantAppPkgName != null;
6643 final boolean isTargetSameInstantApp =
6644 comp.getPackageName().equals(instantAppPkgName);
6645 final boolean isTargetInstantApp =
6646 (ai.applicationInfo.privateFlags
6647 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
6648 final boolean isTargetVisibleToInstantApp =
6649 (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
6650 final boolean isTargetExplicitlyVisibleToInstantApp =
6651 isTargetVisibleToInstantApp
6652 && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
6653 final boolean isTargetHiddenFromInstantApp =
6654 !isTargetVisibleToInstantApp
6655 || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
6656 final boolean blockResolution =
6657 !isTargetSameInstantApp
6658 && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
6659 || (matchVisibleToInstantAppOnly && isCallerInstantApp
6660 && isTargetHiddenFromInstantApp));
6661 if (!blockResolution) {
6662 final ResolveInfo ri = new ResolveInfo();
6663 ri.activityInfo = ai;
6667 return applyPostResolutionFilter(
6668 list, instantAppPkgName, allowDynamicSplits, filterCallingUid, resolveForStart,
6673 boolean sortResult = false;
6674 boolean addInstant = false;
6675 List<ResolveInfo> result;
6676 synchronized (mPackages) {
6677 if (pkgName == null) {
6678 List<CrossProfileIntentFilter> matchingFilters =
6679 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
6680 // Check for results that need to skip the current profile.
6681 ResolveInfo xpResolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent,
6682 resolvedType, flags, userId);
6683 if (xpResolveInfo != null) {
6684 List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
6685 xpResult.add(xpResolveInfo);
6686 return applyPostResolutionFilter(
6687 filterIfNotSystemUser(xpResult, userId), instantAppPkgName,
6688 allowDynamicSplits, filterCallingUid, resolveForStart, userId, intent);
6691 // Check for results in the current profile.
6692 result = filterIfNotSystemUser(mActivities.queryIntent(
6693 intent, resolvedType, flags, userId), userId);
6694 addInstant = isInstantAppResolutionAllowed(intent, result, userId,
6695 false /*skipPackageCheck*/);
6696 // Check for cross profile results.
6697 boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
6698 xpResolveInfo = queryCrossProfileIntents(
6699 matchingFilters, intent, resolvedType, flags, userId,
6700 hasNonNegativePriorityResult);
6701 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
6702 boolean isVisibleToUser = filterIfNotSystemUser(
6703 Collections.singletonList(xpResolveInfo), userId).size() > 0;
6704 if (isVisibleToUser) {
6705 result.add(xpResolveInfo);
6709 if (intent.hasWebURI()) {
6710 CrossProfileDomainInfo xpDomainInfo = null;
6711 final UserInfo parent = getProfileParent(userId);
6712 if (parent != null) {
6713 xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
6714 flags, userId, parent.id);
6716 if (xpDomainInfo != null) {
6717 if (xpResolveInfo != null) {
6718 // If we didn't remove it, the cross-profile ResolveInfo would be twice
6720 result.remove(xpResolveInfo);
6722 if (result.size() == 0 && !addInstant) {
6723 // No result in current profile, but found candidate in parent user.
6724 // And we are not going to add emphemeral app, so we can return the
6725 // result straight away.
6726 result.add(xpDomainInfo.resolveInfo);
6727 return applyPostResolutionFilter(result, instantAppPkgName,
6728 allowDynamicSplits, filterCallingUid, resolveForStart, userId,
6731 } else if (result.size() <= 1 && !addInstant) {
6732 // No result in parent user and <= 1 result in current profile, and we
6733 // are not going to add emphemeral app, so we can return the result without
6734 // further processing.
6735 return applyPostResolutionFilter(result, instantAppPkgName,
6736 allowDynamicSplits, filterCallingUid, resolveForStart, userId,
6739 // We have more than one candidate (combining results from current and parent
6740 // profile), so we need filtering and sorting.
6741 result = filterCandidatesWithDomainPreferredActivitiesLPr(
6742 intent, flags, result, xpDomainInfo, userId);
6746 final PackageParser.Package pkg = mPackages.get(pkgName);
6749 result = filterIfNotSystemUser(
6750 mActivities.queryIntentForPackage(
6751 intent, resolvedType, flags, pkg.activities, userId),
6754 if (result == null || result.size() == 0) {
6755 // the caller wants to resolve for a particular package; however, there
6756 // were no installed results, so, try to find an ephemeral result
6757 addInstant = isInstantAppResolutionAllowed(
6758 intent, null /*result*/, userId, true /*skipPackageCheck*/);
6759 if (result == null) {
6760 result = new ArrayList<>();
6766 result = maybeAddInstantAppInstaller(
6767 result, intent, resolvedType, flags, userId, resolveForStart);
6770 Collections.sort(result, mResolvePrioritySorter);
6772 return applyPostResolutionFilter(
6773 result, instantAppPkgName, allowDynamicSplits, filterCallingUid, resolveForStart,
6777 private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent,
6778 String resolvedType, int flags, int userId, boolean resolveForStart) {
6779 // first, check to see if we've got an instant app already installed
6780 final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
6781 ResolveInfo localInstantApp = null;
6782 boolean blockResolution = false;
6783 if (!alreadyResolvedLocally) {
6784 final List<ResolveInfo> instantApps = mActivities.queryIntent(intent, resolvedType,
6786 | PackageManager.GET_RESOLVED_FILTER
6787 | PackageManager.MATCH_INSTANT
6788 | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY,
6790 for (int i = instantApps.size() - 1; i >= 0; --i) {
6791 final ResolveInfo info = instantApps.get(i);
6792 final String packageName = info.activityInfo.packageName;
6793 final PackageSetting ps = mSettings.mPackages.get(packageName);
6794 if (ps.getInstantApp(userId)) {
6795 final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6796 final int status = (int)(packedStatus >> 32);
6797 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6798 // there's a local instant application installed, but, the user has
6799 // chosen to never use it; skip resolution and don't acknowledge
6800 // an instant application is even available
6801 if (DEBUG_INSTANT) {
6802 Slog.v(TAG, "Instant app marked to never run; pkg: " + packageName);
6804 blockResolution = true;
6807 // we have a locally installed instant application; skip resolution
6808 // but acknowledge there's an instant application available
6809 if (DEBUG_INSTANT) {
6810 Slog.v(TAG, "Found installed instant app; pkg: " + packageName);
6812 localInstantApp = info;
6818 // no app installed, let's see if one's available
6819 AuxiliaryResolveInfo auxiliaryResponse = null;
6820 if (!blockResolution) {
6821 if (localInstantApp == null) {
6822 // we don't have an instant app locally, resolve externally
6823 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
6824 final InstantAppRequest requestObject = new InstantAppRequest(
6825 null /*responseObj*/, intent /*origIntent*/, resolvedType,
6826 null /*callingPackage*/, userId, null /*verificationBundle*/,
6828 auxiliaryResponse = InstantAppResolver.doInstantAppResolutionPhaseOne(
6829 mInstantAppResolverConnection, requestObject);
6830 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6832 // we have an instant application locally, but, we can't admit that since
6833 // callers shouldn't be able to determine prior browsing. create a dummy
6834 // auxiliary response so the downstream code behaves as if there's an
6835 // instant application available externally. when it comes time to start
6836 // the instant application, we'll do the right thing.
6837 final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
6838 auxiliaryResponse = new AuxiliaryResolveInfo(null /* failureActivity */,
6839 ai.packageName, ai.longVersionCode, null /* splitName */);
6842 if (intent.isWebIntent() && auxiliaryResponse == null) {
6845 final PackageSetting ps = mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
6847 || ps.getUserState().get(userId) == null
6848 || !ps.getUserState().get(userId).isEnabled(mInstantAppInstallerActivity, 0)) {
6851 final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
6852 ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
6853 mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
6854 ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6855 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6856 // add a non-generic filter
6857 ephemeralInstaller.filter = new IntentFilter();
6858 if (intent.getAction() != null) {
6859 ephemeralInstaller.filter.addAction(intent.getAction());
6861 if (intent.getData() != null && intent.getData().getPath() != null) {
6862 ephemeralInstaller.filter.addDataPath(
6863 intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
6865 ephemeralInstaller.isInstantAppAvailable = true;
6866 // make sure this resolver is the default
6867 ephemeralInstaller.isDefault = true;
6868 ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
6869 if (DEBUG_INSTANT) {
6870 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
6873 result.add(ephemeralInstaller);
6877 private static class CrossProfileDomainInfo {
6878 /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
6879 ResolveInfo resolveInfo;
6880 /* Best domain verification status of the activities found in the other profile */
6881 int bestDomainVerificationStatus;
6884 private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
6885 String resolvedType, int flags, int sourceUserId, int parentUserId) {
6886 if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
6890 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
6891 resolvedType, flags, parentUserId);
6893 if (resultTargetUser == null || resultTargetUser.isEmpty()) {
6896 CrossProfileDomainInfo result = null;
6897 int size = resultTargetUser.size();
6898 for (int i = 0; i < size; i++) {
6899 ResolveInfo riTargetUser = resultTargetUser.get(i);
6900 // Intent filter verification is only for filters that specify a host. So don't return
6901 // those that handle all web uris.
6902 if (riTargetUser.handleAllWebDataURI) {
6905 String packageName = riTargetUser.activityInfo.packageName;
6906 PackageSetting ps = mSettings.mPackages.get(packageName);
6910 long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
6911 int status = (int)(verificationState >> 32);
6912 if (result == null) {
6913 result = new CrossProfileDomainInfo();
6914 result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
6915 sourceUserId, parentUserId);
6916 result.bestDomainVerificationStatus = status;
6918 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
6919 result.bestDomainVerificationStatus);
6922 // Don't consider matches with status NEVER across profiles.
6923 if (result != null && result.bestDomainVerificationStatus
6924 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6931 * Verification statuses are ordered from the worse to the best, except for
6932 * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
6934 private int bestDomainVerificationStatus(int status1, int status2) {
6935 if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6938 if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6941 return (int) MathUtils.max(status1, status2);
6944 private boolean isUserEnabled(int userId) {
6945 long callingId = Binder.clearCallingIdentity();
6947 UserInfo userInfo = sUserManager.getUserInfo(userId);
6948 return userInfo != null && userInfo.isEnabled();
6950 Binder.restoreCallingIdentity(callingId);
6955 * Filter out activities with systemUserOnly flag set, when current user is not System.
6957 * @return filtered list
6959 private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
6960 if (userId == UserHandle.USER_SYSTEM) {
6961 return resolveInfos;
6963 for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6964 ResolveInfo info = resolveInfos.get(i);
6965 if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
6966 resolveInfos.remove(i);
6969 return resolveInfos;
6973 * Filters out ephemeral activities.
6974 * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
6975 * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
6977 * @param resolveInfos The pre-filtered list of resolved activities
6978 * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
6981 * @return A filtered list of resolved activities.
6983 private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
6984 String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid,
6985 boolean resolveForStart, int userId, Intent intent) {
6986 final boolean blockInstant = intent.isWebIntent() && areWebInstantAppsDisabled();
6987 for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6988 final ResolveInfo info = resolveInfos.get(i);
6989 // remove locally resolved instant app web results when disabled
6990 if (info.isInstantAppAvailable && blockInstant) {
6991 resolveInfos.remove(i);
6994 // allow activities that are defined in the provided package
6995 if (allowDynamicSplits
6996 && info.activityInfo != null
6997 && info.activityInfo.splitName != null
6998 && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
6999 info.activityInfo.splitName)) {
7000 if (mInstantAppInstallerActivity == null) {
7001 if (DEBUG_INSTALL) {
7002 Slog.v(TAG, "No installer - not adding it to the ResolveInfo list");
7004 resolveInfos.remove(i);
7007 if (blockInstant && isInstantApp(info.activityInfo.packageName, userId)) {
7008 resolveInfos.remove(i);
7011 // requested activity is defined in a split that hasn't been installed yet.
7012 // add the installer to the resolve list
7013 if (DEBUG_INSTALL) {
7014 Slog.v(TAG, "Adding installer to the ResolveInfo list");
7016 final ResolveInfo installerInfo = new ResolveInfo(
7017 mInstantAppInstallerInfo);
7018 final ComponentName installFailureActivity = findInstallFailureActivity(
7019 info.activityInfo.packageName, filterCallingUid, userId);
7020 installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7021 installFailureActivity,
7022 info.activityInfo.packageName,
7023 info.activityInfo.applicationInfo.longVersionCode,
7024 info.activityInfo.splitName);
7025 // add a non-generic filter
7026 installerInfo.filter = new IntentFilter();
7028 // This resolve info may appear in the chooser UI, so let us make it
7029 // look as the one it replaces as far as the user is concerned which
7030 // requires loading the correct label and icon for the resolve info.
7031 installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7032 installerInfo.labelRes = info.resolveLabelResId();
7033 installerInfo.icon = info.resolveIconResId();
7034 installerInfo.isInstantAppAvailable = true;
7035 resolveInfos.set(i, installerInfo);
7038 // caller is a full app, don't need to apply any other filtering
7039 if (ephemeralPkgName == null) {
7041 } else if (ephemeralPkgName.equals(info.activityInfo.packageName)) {
7042 // caller is same app; don't need to apply any other filtering
7044 } else if (resolveForStart
7045 && (intent.isWebIntent()
7046 || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) != 0)
7047 && intent.getPackage() == null
7048 && intent.getComponent() == null) {
7049 // ephemeral apps can launch other ephemeral apps indirectly
7052 // allow activities that have been explicitly exposed to ephemeral apps
7053 final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
7055 && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7058 resolveInfos.remove(i);
7060 return resolveInfos;
7064 * Returns the activity component that can handle install failures.
7065 * <p>By default, the instant application installer handles failures. However, an
7066 * application may want to handle failures on its own. Applications do this by
7067 * creating an activity with an intent filter that handles the action
7068 * {@link Intent#ACTION_INSTALL_FAILURE}.
7070 private @Nullable ComponentName findInstallFailureActivity(
7071 String packageName, int filterCallingUid, int userId) {
7072 final Intent failureActivityIntent = new Intent(Intent.ACTION_INSTALL_FAILURE);
7073 failureActivityIntent.setPackage(packageName);
7074 // IMPORTANT: disallow dynamic splits to avoid an infinite loop
7075 final List<ResolveInfo> result = queryIntentActivitiesInternal(
7076 failureActivityIntent, null /*resolvedType*/, 0 /*flags*/, filterCallingUid, userId,
7077 false /*resolveForStart*/, false /*allowDynamicSplits*/);
7078 final int NR = result.size();
7080 for (int i = 0; i < NR; i++) {
7081 final ResolveInfo info = result.get(i);
7082 if (info.activityInfo.splitName != null) {
7085 return new ComponentName(packageName, info.activityInfo.name);
7092 * @param resolveInfos list of resolve infos in descending priority order
7093 * @return if the list contains a resolve info with non-negative priority
7095 private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
7096 return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
7099 private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
7100 int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
7102 final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
7104 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7105 Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
7109 ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
7110 ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
7111 ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
7112 ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
7113 ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
7114 ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
7116 synchronized (mPackages) {
7117 final int count = candidates.size();
7118 // First, try to use linked apps. Partition the candidates into four lists:
7119 // one for the final results, one for the "do not use ever", one for "undefined status"
7120 // and finally one for "browser app type".
7121 for (int n=0; n<count; n++) {
7122 ResolveInfo info = candidates.get(n);
7123 String packageName = info.activityInfo.packageName;
7124 PackageSetting ps = mSettings.mPackages.get(packageName);
7126 // Add to the special match all list (Browser use case)
7127 if (info.handleAllWebDataURI) {
7128 matchAllList.add(info);
7131 // Try to get the status from User settings first
7132 long packedStatus = getDomainVerificationStatusLPr(ps, userId);
7133 int status = (int)(packedStatus >> 32);
7134 int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
7135 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
7136 if (DEBUG_DOMAIN_VERIFICATION || debug) {
7137 Slog.i(TAG, " + always: " + info.activityInfo.packageName
7138 + " : linkgen=" + linkGeneration);
7140 // Use link-enabled generation as preferredOrder, i.e.
7141 // prefer newly-enabled over earlier-enabled.
7142 info.preferredOrder = linkGeneration;
7143 alwaysList.add(info);
7144 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7145 if (DEBUG_DOMAIN_VERIFICATION || debug) {
7146 Slog.i(TAG, " + never: " + info.activityInfo.packageName);
7148 neverList.add(info);
7149 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
7150 if (DEBUG_DOMAIN_VERIFICATION || debug) {
7151 Slog.i(TAG, " + always-ask: " + info.activityInfo.packageName);
7153 alwaysAskList.add(info);
7154 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
7155 status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
7156 if (DEBUG_DOMAIN_VERIFICATION || debug) {
7157 Slog.i(TAG, " + ask: " + info.activityInfo.packageName);
7159 undefinedList.add(info);
7164 // We'll want to include browser possibilities in a few cases
7165 boolean includeBrowser = false;
7167 // First try to add the "always" resolution(s) for the current user, if any
7168 if (alwaysList.size() > 0) {
7169 result.addAll(alwaysList);
7171 // Add all undefined apps as we want them to appear in the disambiguation dialog.
7172 result.addAll(undefinedList);
7173 // Maybe add one for the other profile.
7174 if (xpDomainInfo != null && (
7175 xpDomainInfo.bestDomainVerificationStatus
7176 != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
7177 result.add(xpDomainInfo.resolveInfo);
7179 includeBrowser = true;
7182 // The presence of any 'always ask' alternatives means we'll also offer browsers.
7183 // If there were 'always' entries their preferred order has been set, so we also
7184 // back that off to make the alternatives equivalent
7185 if (alwaysAskList.size() > 0) {
7186 for (ResolveInfo i : result) {
7187 i.preferredOrder = 0;
7189 result.addAll(alwaysAskList);
7190 includeBrowser = true;
7193 if (includeBrowser) {
7194 // Also add browsers (all of them or only the default one)
7195 if (DEBUG_DOMAIN_VERIFICATION) {
7196 Slog.v(TAG, " ...including browsers in candidate set");
7198 if ((matchFlags & MATCH_ALL) != 0) {
7199 result.addAll(matchAllList);
7201 // Browser/generic handling case. If there's a default browser, go straight
7202 // to that (but only if there is no other higher-priority match).
7203 final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
7204 int maxMatchPrio = 0;
7205 ResolveInfo defaultBrowserMatch = null;
7206 final int numCandidates = matchAllList.size();
7207 for (int n = 0; n < numCandidates; n++) {
7208 ResolveInfo info = matchAllList.get(n);
7209 // track the highest overall match priority...
7210 if (info.priority > maxMatchPrio) {
7211 maxMatchPrio = info.priority;
7213 // ...and the highest-priority default browser match
7214 if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
7215 if (defaultBrowserMatch == null
7216 || (defaultBrowserMatch.priority < info.priority)) {
7218 Slog.v(TAG, "Considering default browser match " + info);
7220 defaultBrowserMatch = info;
7224 if (defaultBrowserMatch != null
7225 && defaultBrowserMatch.priority >= maxMatchPrio
7226 && !TextUtils.isEmpty(defaultBrowserPackageName))
7229 Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
7231 result.add(defaultBrowserMatch);
7233 result.addAll(matchAllList);
7237 // If there is nothing selected, add all candidates and remove the ones that the user
7238 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
7239 if (result.size() == 0) {
7240 result.addAll(candidates);
7241 result.removeAll(neverList);
7245 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7246 Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
7248 for (ResolveInfo info : result) {
7249 Slog.v(TAG, " + " + info.activityInfo);
7255 // Returns a packed value as a long:
7257 // high 'int'-sized word: link status: undefined/ask/never/always.
7258 // low 'int'-sized word: relative priority among 'always' results.
7259 private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
7260 long result = ps.getDomainVerificationStatusForUser(userId);
7261 // if none available, get the master status
7262 if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
7263 if (ps.getIntentFilterVerificationInfo() != null) {
7264 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
7270 private ResolveInfo querySkipCurrentProfileIntents(
7271 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7272 int flags, int sourceUserId) {
7273 if (matchingFilters != null) {
7274 int size = matchingFilters.size();
7275 for (int i = 0; i < size; i ++) {
7276 CrossProfileIntentFilter filter = matchingFilters.get(i);
7277 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
7278 // Checking if there are activities in the target user that can handle the
7280 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7281 resolvedType, flags, sourceUserId);
7282 if (resolveInfo != null) {
7291 // Return matching ResolveInfo in target user if any.
7292 private ResolveInfo queryCrossProfileIntents(
7293 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7294 int flags, int sourceUserId, boolean matchInCurrentProfile) {
7295 if (matchingFilters != null) {
7296 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
7297 // match the same intent. For performance reasons, it is better not to
7298 // run queryIntent twice for the same userId
7299 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
7300 int size = matchingFilters.size();
7301 for (int i = 0; i < size; i++) {
7302 CrossProfileIntentFilter filter = matchingFilters.get(i);
7303 int targetUserId = filter.getTargetUserId();
7304 boolean skipCurrentProfile =
7305 (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
7306 boolean skipCurrentProfileIfNoMatchFound =
7307 (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
7308 if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
7309 && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
7310 // Checking if there are activities in the target user that can handle the
7312 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7313 resolvedType, flags, sourceUserId);
7314 if (resolveInfo != null) return resolveInfo;
7315 alreadyTriedUserIds.put(targetUserId, true);
7323 * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
7324 * will forward the intent to the filter's target user.
7325 * Otherwise, returns null.
7327 private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
7328 String resolvedType, int flags, int sourceUserId) {
7329 int targetUserId = filter.getTargetUserId();
7330 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
7331 resolvedType, flags, targetUserId);
7332 if (resultTargetUser != null && isUserEnabled(targetUserId)) {
7333 // If all the matches in the target profile are suspended, return null.
7334 for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
7335 if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
7336 & ApplicationInfo.FLAG_SUSPENDED) == 0) {
7337 return createForwardingResolveInfoUnchecked(filter, sourceUserId,
7345 private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
7346 int sourceUserId, int targetUserId) {
7347 ResolveInfo forwardingResolveInfo = new ResolveInfo();
7348 long ident = Binder.clearCallingIdentity();
7349 boolean targetIsProfile;
7351 targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
7353 Binder.restoreCallingIdentity(ident);
7356 if (targetIsProfile) {
7357 className = FORWARD_INTENT_TO_MANAGED_PROFILE;
7359 className = FORWARD_INTENT_TO_PARENT;
7361 ComponentName forwardingActivityComponentName = new ComponentName(
7362 mAndroidApplication.packageName, className);
7363 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
7365 if (!targetIsProfile) {
7366 forwardingActivityInfo.showUserIcon = targetUserId;
7367 forwardingResolveInfo.noResourceId = true;
7369 forwardingResolveInfo.activityInfo = forwardingActivityInfo;
7370 forwardingResolveInfo.priority = 0;
7371 forwardingResolveInfo.preferredOrder = 0;
7372 forwardingResolveInfo.match = 0;
7373 forwardingResolveInfo.isDefault = true;
7374 forwardingResolveInfo.filter = filter;
7375 forwardingResolveInfo.targetUserId = targetUserId;
7376 return forwardingResolveInfo;
7380 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
7381 Intent[] specifics, String[] specificTypes, Intent intent,
7382 String resolvedType, int flags, int userId) {
7383 return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
7384 specificTypes, intent, resolvedType, flags, userId));
7387 private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
7388 Intent[] specifics, String[] specificTypes, Intent intent,
7389 String resolvedType, int flags, int userId) {
7390 if (!sUserManager.exists(userId)) return Collections.emptyList();
7391 final int callingUid = Binder.getCallingUid();
7392 flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7393 false /*includeInstantApps*/);
7394 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7395 false /*requireFullPermission*/, false /*checkShell*/,
7396 "query intent activity options");
7397 final String resultsAction = intent.getAction();
7399 final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
7400 | PackageManager.GET_RESOLVED_FILTER, userId);
7402 if (DEBUG_INTENT_MATCHING) {
7403 Log.v(TAG, "Query " + intent + ": " + results);
7406 int specificsPos = 0;
7409 // todo: note that the algorithm used here is O(N^2). This
7410 // isn't a problem in our current environment, but if we start running
7411 // into situations where we have more than 5 or 10 matches then this
7412 // should probably be changed to something smarter...
7414 // First we go through and resolve each of the specific items
7415 // that were supplied, taking care of removing any corresponding
7416 // duplicate items in the generic resolve list.
7417 if (specifics != null) {
7418 for (int i=0; i<specifics.length; i++) {
7419 final Intent sintent = specifics[i];
7420 if (sintent == null) {
7424 if (DEBUG_INTENT_MATCHING) {
7425 Log.v(TAG, "Specific #" + i + ": " + sintent);
7428 String action = sintent.getAction();
7429 if (resultsAction != null && resultsAction.equals(action)) {
7430 // If this action was explicitly requested, then don't
7431 // remove things that have it.
7435 ResolveInfo ri = null;
7436 ActivityInfo ai = null;
7438 ComponentName comp = sintent.getComponent();
7442 specificTypes != null ? specificTypes[i] : null,
7447 if (ri == mResolveInfo) {
7448 // ACK! Must do something better with this.
7450 ai = ri.activityInfo;
7451 comp = new ComponentName(ai.applicationInfo.packageName,
7454 ai = getActivityInfo(comp, flags, userId);
7460 // Look for any generic query activities that are duplicates
7461 // of this specific one, and remove them from the results.
7462 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
7465 for (j=specificsPos; j<N; j++) {
7466 ResolveInfo sri = results.get(j);
7467 if ((sri.activityInfo.name.equals(comp.getClassName())
7468 && sri.activityInfo.applicationInfo.packageName.equals(
7469 comp.getPackageName()))
7470 || (action != null && sri.filter.matchAction(action))) {
7472 if (DEBUG_INTENT_MATCHING) Log.v(
7473 TAG, "Removing duplicate item from " + j
7474 + " due to specific " + specificsPos);
7483 // Add this specific item to its proper place.
7485 ri = new ResolveInfo();
7486 ri.activityInfo = ai;
7488 results.add(specificsPos, ri);
7489 ri.specificIndex = i;
7494 // Now we go through the remaining generic results and remove any
7495 // duplicate actions that are found here.
7497 for (int i=specificsPos; i<N-1; i++) {
7498 final ResolveInfo rii = results.get(i);
7499 if (rii.filter == null) {
7503 // Iterate over all of the actions of this result's intent
7504 // filter... typically this should be just one.
7505 final Iterator<String> it = rii.filter.actionsIterator();
7509 while (it.hasNext()) {
7510 final String action = it.next();
7511 if (resultsAction != null && resultsAction.equals(action)) {
7512 // If this action was explicitly requested, then don't
7513 // remove things that have it.
7516 for (int j=i+1; j<N; j++) {
7517 final ResolveInfo rij = results.get(j);
7518 if (rij.filter != null && rij.filter.hasAction(action)) {
7520 if (DEBUG_INTENT_MATCHING) Log.v(
7521 TAG, "Removing duplicate item from " + j
7522 + " due to action " + action + " at " + i);
7529 // If the caller didn't request filter information, drop it now
7530 // so we don't have to marshall/unmarshall it.
7531 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7536 // Filter out the caller activity if so requested.
7537 if (caller != null) {
7539 for (int i=0; i<N; i++) {
7540 ActivityInfo ainfo = results.get(i).activityInfo;
7541 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
7542 && caller.getClassName().equals(ainfo.name)) {
7549 // If the caller didn't request filter information,
7550 // drop them now so we don't have to
7551 // marshall/unmarshall it.
7552 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7554 for (int i=0; i<N; i++) {
7555 results.get(i).filter = null;
7559 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
7564 public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
7565 String resolvedType, int flags, int userId) {
7566 return new ParceledListSlice<>(
7567 queryIntentReceiversInternal(intent, resolvedType, flags, userId,
7568 false /*allowDynamicSplits*/));
7571 private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
7572 String resolvedType, int flags, int userId, boolean allowDynamicSplits) {
7573 if (!sUserManager.exists(userId)) return Collections.emptyList();
7574 final int callingUid = Binder.getCallingUid();
7575 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7576 false /*requireFullPermission*/, false /*checkShell*/,
7577 "query intent receivers");
7578 final String instantAppPkgName = getInstantAppPackageName(callingUid);
7579 flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7580 false /*includeInstantApps*/);
7581 ComponentName comp = intent.getComponent();
7583 if (intent.getSelector() != null) {
7584 intent = intent.getSelector();
7585 comp = intent.getComponent();
7589 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7590 final ActivityInfo ai = getReceiverInfo(comp, flags, userId);
7592 // When specifying an explicit component, we prevent the activity from being
7593 // used when either 1) the calling package is normal and the activity is within
7594 // an instant application or 2) the calling package is ephemeral and the
7595 // activity is not visible to instant applications.
7596 final boolean matchInstantApp =
7597 (flags & PackageManager.MATCH_INSTANT) != 0;
7598 final boolean matchVisibleToInstantAppOnly =
7599 (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7600 final boolean matchExplicitlyVisibleOnly =
7601 (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
7602 final boolean isCallerInstantApp =
7603 instantAppPkgName != null;
7604 final boolean isTargetSameInstantApp =
7605 comp.getPackageName().equals(instantAppPkgName);
7606 final boolean isTargetInstantApp =
7607 (ai.applicationInfo.privateFlags
7608 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7609 final boolean isTargetVisibleToInstantApp =
7610 (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
7611 final boolean isTargetExplicitlyVisibleToInstantApp =
7612 isTargetVisibleToInstantApp
7613 && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
7614 final boolean isTargetHiddenFromInstantApp =
7615 !isTargetVisibleToInstantApp
7616 || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
7617 final boolean blockResolution =
7618 !isTargetSameInstantApp
7619 && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7620 || (matchVisibleToInstantAppOnly && isCallerInstantApp
7621 && isTargetHiddenFromInstantApp));
7622 if (!blockResolution) {
7623 ResolveInfo ri = new ResolveInfo();
7624 ri.activityInfo = ai;
7628 return applyPostResolutionFilter(
7629 list, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
7634 synchronized (mPackages) {
7635 String pkgName = intent.getPackage();
7636 if (pkgName == null) {
7637 final List<ResolveInfo> result =
7638 mReceivers.queryIntent(intent, resolvedType, flags, userId);
7639 return applyPostResolutionFilter(
7640 result, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
7643 final PackageParser.Package pkg = mPackages.get(pkgName);
7645 final List<ResolveInfo> result = mReceivers.queryIntentForPackage(
7646 intent, resolvedType, flags, pkg.receivers, userId);
7647 return applyPostResolutionFilter(
7648 result, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
7651 return Collections.emptyList();
7656 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
7657 final int callingUid = Binder.getCallingUid();
7658 return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
7661 private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
7662 int userId, int callingUid) {
7663 if (!sUserManager.exists(userId)) return null;
7664 flags = updateFlagsForResolve(
7665 flags, userId, intent, callingUid, false /*includeInstantApps*/);
7666 List<ResolveInfo> query = queryIntentServicesInternal(
7667 intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
7668 if (query != null) {
7669 if (query.size() >= 1) {
7670 // If there is more than one service with the same priority,
7671 // just arbitrarily pick the first one.
7672 return query.get(0);
7679 public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
7680 String resolvedType, int flags, int userId) {
7681 final int callingUid = Binder.getCallingUid();
7682 return new ParceledListSlice<>(queryIntentServicesInternal(
7683 intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
7686 private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
7687 String resolvedType, int flags, int userId, int callingUid,
7688 boolean includeInstantApps) {
7689 if (!sUserManager.exists(userId)) return Collections.emptyList();
7690 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7691 false /*requireFullPermission*/, false /*checkShell*/,
7692 "query intent receivers");
7693 final String instantAppPkgName = getInstantAppPackageName(callingUid);
7694 flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
7695 ComponentName comp = intent.getComponent();
7697 if (intent.getSelector() != null) {
7698 intent = intent.getSelector();
7699 comp = intent.getComponent();
7703 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7704 final ServiceInfo si = getServiceInfo(comp, flags, userId);
7706 // When specifying an explicit component, we prevent the service from being
7707 // used when either 1) the service is in an instant application and the
7708 // caller is not the same instant application or 2) the calling package is
7709 // ephemeral and the activity is not visible to ephemeral applications.
7710 final boolean matchInstantApp =
7711 (flags & PackageManager.MATCH_INSTANT) != 0;
7712 final boolean matchVisibleToInstantAppOnly =
7713 (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7714 final boolean isCallerInstantApp =
7715 instantAppPkgName != null;
7716 final boolean isTargetSameInstantApp =
7717 comp.getPackageName().equals(instantAppPkgName);
7718 final boolean isTargetInstantApp =
7719 (si.applicationInfo.privateFlags
7720 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7721 final boolean isTargetHiddenFromInstantApp =
7722 (si.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
7723 final boolean blockResolution =
7724 !isTargetSameInstantApp
7725 && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7726 || (matchVisibleToInstantAppOnly && isCallerInstantApp
7727 && isTargetHiddenFromInstantApp));
7728 if (!blockResolution) {
7729 final ResolveInfo ri = new ResolveInfo();
7730 ri.serviceInfo = si;
7738 synchronized (mPackages) {
7739 String pkgName = intent.getPackage();
7740 if (pkgName == null) {
7741 return applyPostServiceResolutionFilter(
7742 mServices.queryIntent(intent, resolvedType, flags, userId),
7745 final PackageParser.Package pkg = mPackages.get(pkgName);
7747 return applyPostServiceResolutionFilter(
7748 mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
7752 return Collections.emptyList();
7756 private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
7757 String instantAppPkgName) {
7758 if (instantAppPkgName == null) {
7759 return resolveInfos;
7761 for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7762 final ResolveInfo info = resolveInfos.get(i);
7763 final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
7764 // allow services that are defined in the provided package
7765 if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
7766 if (info.serviceInfo.splitName != null
7767 && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
7768 info.serviceInfo.splitName)) {
7769 // requested service is defined in a split that hasn't been installed yet.
7770 // add the installer to the resolve list
7771 if (DEBUG_INSTANT) {
7772 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7774 final ResolveInfo installerInfo = new ResolveInfo(
7775 mInstantAppInstallerInfo);
7776 installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7777 null /* installFailureActivity */,
7778 info.serviceInfo.packageName,
7779 info.serviceInfo.applicationInfo.longVersionCode,
7780 info.serviceInfo.splitName);
7781 // add a non-generic filter
7782 installerInfo.filter = new IntentFilter();
7783 // load resources from the correct package
7784 installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7785 resolveInfos.set(i, installerInfo);
7789 // allow services that have been explicitly exposed to ephemeral apps
7791 && ((info.serviceInfo.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7794 resolveInfos.remove(i);
7796 return resolveInfos;
7800 public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
7801 String resolvedType, int flags, int userId) {
7802 return new ParceledListSlice<>(
7803 queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
7806 private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
7807 Intent intent, String resolvedType, int flags, int userId) {
7808 if (!sUserManager.exists(userId)) return Collections.emptyList();
7809 final int callingUid = Binder.getCallingUid();
7810 final String instantAppPkgName = getInstantAppPackageName(callingUid);
7811 flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7812 false /*includeInstantApps*/);
7813 ComponentName comp = intent.getComponent();
7815 if (intent.getSelector() != null) {
7816 intent = intent.getSelector();
7817 comp = intent.getComponent();
7821 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7822 final ProviderInfo pi = getProviderInfo(comp, flags, userId);
7824 // When specifying an explicit component, we prevent the provider from being
7825 // used when either 1) the provider is in an instant application and the
7826 // caller is not the same instant application or 2) the calling package is an
7827 // instant application and the provider is not visible to instant applications.
7828 final boolean matchInstantApp =
7829 (flags & PackageManager.MATCH_INSTANT) != 0;
7830 final boolean matchVisibleToInstantAppOnly =
7831 (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7832 final boolean isCallerInstantApp =
7833 instantAppPkgName != null;
7834 final boolean isTargetSameInstantApp =
7835 comp.getPackageName().equals(instantAppPkgName);
7836 final boolean isTargetInstantApp =
7837 (pi.applicationInfo.privateFlags
7838 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7839 final boolean isTargetHiddenFromInstantApp =
7840 (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
7841 final boolean blockResolution =
7842 !isTargetSameInstantApp
7843 && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7844 || (matchVisibleToInstantAppOnly && isCallerInstantApp
7845 && isTargetHiddenFromInstantApp));
7846 if (!blockResolution) {
7847 final ResolveInfo ri = new ResolveInfo();
7848 ri.providerInfo = pi;
7856 synchronized (mPackages) {
7857 String pkgName = intent.getPackage();
7858 if (pkgName == null) {
7859 return applyPostContentProviderResolutionFilter(
7860 mProviders.queryIntent(intent, resolvedType, flags, userId),
7863 final PackageParser.Package pkg = mPackages.get(pkgName);
7865 return applyPostContentProviderResolutionFilter(
7866 mProviders.queryIntentForPackage(
7867 intent, resolvedType, flags, pkg.providers, userId),
7870 return Collections.emptyList();
7874 private List<ResolveInfo> applyPostContentProviderResolutionFilter(
7875 List<ResolveInfo> resolveInfos, String instantAppPkgName) {
7876 if (instantAppPkgName == null) {
7877 return resolveInfos;
7879 for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7880 final ResolveInfo info = resolveInfos.get(i);
7881 final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
7882 // allow providers that are defined in the provided package
7883 if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
7884 if (info.providerInfo.splitName != null
7885 && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
7886 info.providerInfo.splitName)) {
7887 // requested provider is defined in a split that hasn't been installed yet.
7888 // add the installer to the resolve list
7889 if (DEBUG_INSTANT) {
7890 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7892 final ResolveInfo installerInfo = new ResolveInfo(
7893 mInstantAppInstallerInfo);
7894 installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7895 null /*failureActivity*/,
7896 info.providerInfo.packageName,
7897 info.providerInfo.applicationInfo.longVersionCode,
7898 info.providerInfo.splitName);
7899 // add a non-generic filter
7900 installerInfo.filter = new IntentFilter();
7901 // load resources from the correct package
7902 installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7903 resolveInfos.set(i, installerInfo);
7907 // allow providers that have been explicitly exposed to instant applications
7909 && ((info.providerInfo.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7912 resolveInfos.remove(i);
7914 return resolveInfos;
7918 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
7919 final int callingUid = Binder.getCallingUid();
7920 if (getInstantAppPackageName(callingUid) != null) {
7921 return ParceledListSlice.emptyList();
7923 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7924 flags = updateFlagsForPackage(flags, userId, null);
7925 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7926 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7927 false /* requireFullPermission */, false /* checkShell */,
7928 "get installed packages");
7931 synchronized (mPackages) {
7932 ArrayList<PackageInfo> list;
7933 if (listUninstalled) {
7934 list = new ArrayList<>(mSettings.mPackages.size());
7935 for (PackageSetting ps : mSettings.mPackages.values()) {
7936 if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
7939 if (filterAppAccessLPr(ps, callingUid, userId)) {
7942 final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7948 list = new ArrayList<>(mPackages.size());
7949 for (PackageParser.Package p : mPackages.values()) {
7950 final PackageSetting ps = (PackageSetting) p.mExtras;
7951 if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
7954 if (filterAppAccessLPr(ps, callingUid, userId)) {
7957 final PackageInfo pi = generatePackageInfo((PackageSetting)
7958 p.mExtras, flags, userId);
7965 return new ParceledListSlice<>(list);
7969 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
7970 String[] permissions, boolean[] tmp, int flags, int userId) {
7972 final PermissionsState permissionsState = ps.getPermissionsState();
7973 for (int i=0; i<permissions.length; i++) {
7974 final String permission = permissions[i];
7975 if (permissionsState.hasPermission(permission, userId)) {
7982 if (numMatch == 0) {
7985 final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7987 // The above might return null in cases of uninstalled apps or install-state
7988 // skew across users/profiles.
7990 if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
7991 if (numMatch == permissions.length) {
7992 pi.requestedPermissions = permissions;
7994 pi.requestedPermissions = new String[numMatch];
7996 for (int i=0; i<permissions.length; i++) {
7998 pi.requestedPermissions[numMatch] = permissions[i];
8009 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
8010 String[] permissions, int flags, int userId) {
8011 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8012 flags = updateFlagsForPackage(flags, userId, permissions);
8013 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8014 true /* requireFullPermission */, false /* checkShell */,
8015 "get packages holding permissions");
8016 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8019 synchronized (mPackages) {
8020 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
8021 boolean[] tmpBools = new boolean[permissions.length];
8022 if (listUninstalled) {
8023 for (PackageSetting ps : mSettings.mPackages.values()) {
8024 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
8028 for (PackageParser.Package pkg : mPackages.values()) {
8029 PackageSetting ps = (PackageSetting)pkg.mExtras;
8031 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
8037 return new ParceledListSlice<PackageInfo>(list);
8042 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
8043 final int callingUid = Binder.getCallingUid();
8044 if (getInstantAppPackageName(callingUid) != null) {
8045 return ParceledListSlice.emptyList();
8047 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8048 flags = updateFlagsForApplication(flags, userId, null);
8049 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8051 mPermissionManager.enforceCrossUserPermission(
8054 false /* requireFullPermission */,
8055 false /* checkShell */,
8056 "get installed application info");
8059 synchronized (mPackages) {
8060 ArrayList<ApplicationInfo> list;
8061 if (listUninstalled) {
8062 list = new ArrayList<>(mSettings.mPackages.size());
8063 for (PackageSetting ps : mSettings.mPackages.values()) {
8065 int effectiveFlags = flags;
8066 if (ps.isSystem()) {
8067 effectiveFlags |= PackageManager.MATCH_ANY_USER;
8069 if (ps.pkg != null) {
8070 if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8073 if (filterAppAccessLPr(ps, callingUid, userId)) {
8076 ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
8077 ps.readUserState(userId), userId);
8079 ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
8082 // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
8083 // and already converts to externally visible package name
8084 ai = generateApplicationInfoFromSettingsLPw(ps.name,
8085 callingUid, effectiveFlags, userId);
8092 list = new ArrayList<>(mPackages.size());
8093 for (PackageParser.Package p : mPackages.values()) {
8094 if (p.mExtras != null) {
8095 PackageSetting ps = (PackageSetting) p.mExtras;
8096 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
8099 if (filterAppAccessLPr(ps, callingUid, userId)) {
8102 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
8103 ps.readUserState(userId), userId);
8105 ai.packageName = resolveExternalPackageNameLPr(p);
8112 return new ParceledListSlice<>(list);
8117 public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
8118 if (HIDE_EPHEMERAL_APIS) {
8121 if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
8122 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8123 "getEphemeralApplications");
8125 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8126 true /* requireFullPermission */, false /* checkShell */,
8127 "getEphemeralApplications");
8128 synchronized (mPackages) {
8129 List<InstantAppInfo> instantApps = mInstantAppRegistry
8130 .getInstantAppsLPr(userId);
8131 if (instantApps != null) {
8132 return new ParceledListSlice<>(instantApps);
8139 public boolean isInstantApp(String packageName, int userId) {
8140 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8141 true /* requireFullPermission */, false /* checkShell */,
8143 if (HIDE_EPHEMERAL_APIS) {
8147 synchronized (mPackages) {
8148 int callingUid = Binder.getCallingUid();
8149 if (Process.isIsolated(callingUid)) {
8150 callingUid = mIsolatedOwners.get(callingUid);
8152 final PackageSetting ps = mSettings.mPackages.get(packageName);
8153 PackageParser.Package pkg = mPackages.get(packageName);
8154 final boolean returnAllowed =
8156 && (isCallerSameApp(packageName, callingUid)
8157 || canViewInstantApps(callingUid, userId)
8158 || mInstantAppRegistry.isInstantAccessGranted(
8159 userId, UserHandle.getAppId(callingUid), ps.appId));
8160 if (returnAllowed) {
8161 return ps.getInstantApp(userId);
8168 public byte[] getInstantAppCookie(String packageName, int userId) {
8169 if (HIDE_EPHEMERAL_APIS) {
8173 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8174 true /* requireFullPermission */, false /* checkShell */,
8175 "getInstantAppCookie");
8176 if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8179 synchronized (mPackages) {
8180 return mInstantAppRegistry.getInstantAppCookieLPw(
8181 packageName, userId);
8186 public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
8187 if (HIDE_EPHEMERAL_APIS) {
8191 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8192 true /* requireFullPermission */, true /* checkShell */,
8193 "setInstantAppCookie");
8194 if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8197 synchronized (mPackages) {
8198 return mInstantAppRegistry.setInstantAppCookieLPw(
8199 packageName, cookie, userId);
8204 public Bitmap getInstantAppIcon(String packageName, int userId) {
8205 if (HIDE_EPHEMERAL_APIS) {
8209 if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
8210 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8211 "getInstantAppIcon");
8213 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8214 true /* requireFullPermission */, false /* checkShell */,
8215 "getInstantAppIcon");
8217 synchronized (mPackages) {
8218 return mInstantAppRegistry.getInstantAppIconLPw(
8219 packageName, userId);
8223 private boolean isCallerSameApp(String packageName, int uid) {
8224 PackageParser.Package pkg = mPackages.get(packageName);
8226 && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
8230 public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
8231 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8232 return ParceledListSlice.emptyList();
8234 return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
8237 private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
8238 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
8241 synchronized (mPackages) {
8242 final Iterator<PackageParser.Package> i = mPackages.values().iterator();
8243 final int userId = UserHandle.getCallingUserId();
8244 while (i.hasNext()) {
8245 final PackageParser.Package p = i.next();
8246 if (p.applicationInfo == null) continue;
8248 final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
8249 && !p.applicationInfo.isDirectBootAware();
8250 final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
8251 && p.applicationInfo.isDirectBootAware();
8253 if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
8254 && (!mSafeMode || isSystemApp(p))
8255 && (matchesUnaware || matchesAware)) {
8256 PackageSetting ps = mSettings.mPackages.get(p.packageName);
8258 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
8259 ps.readUserState(userId), userId);
8272 public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
8273 return resolveContentProviderInternal(name, flags, userId);
8276 private ProviderInfo resolveContentProviderInternal(String name, int flags, int userId) {
8277 if (!sUserManager.exists(userId)) return null;
8278 flags = updateFlagsForComponent(flags, userId, name);
8279 final int callingUid = Binder.getCallingUid();
8280 synchronized (mPackages) {
8281 final PackageParser.Provider provider = mProvidersByAuthority.get(name);
8282 PackageSetting ps = provider != null
8283 ? mSettings.mPackages.get(provider.owner.packageName)
8286 // provider not enabled
8287 if (!mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)) {
8290 final ComponentName component =
8291 new ComponentName(provider.info.packageName, provider.info.name);
8292 if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
8295 return PackageParser.generateProviderInfo(
8296 provider, flags, ps.readUserState(userId), userId);
8306 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
8307 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8311 synchronized (mPackages) {
8312 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
8313 .entrySet().iterator();
8314 final int userId = UserHandle.getCallingUserId();
8315 while (i.hasNext()) {
8316 Map.Entry<String, PackageParser.Provider> entry = i.next();
8317 PackageParser.Provider p = entry.getValue();
8318 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8320 if (ps != null && p.syncable
8321 && (!mSafeMode || (p.info.applicationInfo.flags
8322 &ApplicationInfo.FLAG_SYSTEM) != 0)) {
8323 ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
8324 ps.readUserState(userId), userId);
8326 outNames.add(entry.getKey());
8335 public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
8336 int uid, int flags, String metaDataKey) {
8337 final int callingUid = Binder.getCallingUid();
8338 final int userId = processName != null ? UserHandle.getUserId(uid)
8339 : UserHandle.getCallingUserId();
8340 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8341 flags = updateFlagsForComponent(flags, userId, processName);
8342 ArrayList<ProviderInfo> finalList = null;
8344 synchronized (mPackages) {
8345 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
8346 while (i.hasNext()) {
8347 final PackageParser.Provider p = i.next();
8348 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8349 if (ps != null && p.info.authority != null
8350 && (processName == null
8351 || (p.info.processName.equals(processName)
8352 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
8353 && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
8355 // See PM.queryContentProviders()'s javadoc for why we have the metaData
8357 if (metaDataKey != null
8358 && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
8361 final ComponentName component =
8362 new ComponentName(p.info.packageName, p.info.name);
8363 if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
8366 if (finalList == null) {
8367 finalList = new ArrayList<ProviderInfo>(3);
8369 ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
8370 ps.readUserState(userId), userId);
8372 finalList.add(info);
8378 if (finalList != null) {
8379 Collections.sort(finalList, mProviderInitOrderSorter);
8380 return new ParceledListSlice<ProviderInfo>(finalList);
8383 return ParceledListSlice.emptyList();
8387 public InstrumentationInfo getInstrumentationInfo(ComponentName component, int flags) {
8389 synchronized (mPackages) {
8390 final int callingUid = Binder.getCallingUid();
8391 final int callingUserId = UserHandle.getUserId(callingUid);
8392 final PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
8393 if (ps == null) return null;
8394 if (filterAppAccessLPr(ps, callingUid, component, TYPE_UNKNOWN, callingUserId)) {
8397 final PackageParser.Instrumentation i = mInstrumentation.get(component);
8398 return PackageParser.generateInstrumentationInfo(i, flags);
8403 public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
8404 String targetPackage, int flags) {
8405 final int callingUid = Binder.getCallingUid();
8406 final int callingUserId = UserHandle.getUserId(callingUid);
8407 final PackageSetting ps = mSettings.mPackages.get(targetPackage);
8408 if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
8409 return ParceledListSlice.emptyList();
8411 return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
8414 private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
8416 ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
8419 synchronized (mPackages) {
8420 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
8421 while (i.hasNext()) {
8422 final PackageParser.Instrumentation p = i.next();
8423 if (targetPackage == null
8424 || targetPackage.equals(p.info.targetPackage)) {
8425 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
8437 private void scanDirTracedLI(File scanDir, final int parseFlags, int scanFlags, long currentTime) {
8438 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + scanDir.getAbsolutePath() + "]");
8440 scanDirLI(scanDir, parseFlags, scanFlags, currentTime);
8442 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8446 private void scanDirLI(File scanDir, int parseFlags, int scanFlags, long currentTime) {
8447 final File[] files = scanDir.listFiles();
8448 if (ArrayUtils.isEmpty(files)) {
8449 Log.d(TAG, "No files in app dir " + scanDir);
8453 if (DEBUG_PACKAGE_SCANNING) {
8454 Log.d(TAG, "Scanning app dir " + scanDir + " scanFlags=" + scanFlags
8455 + " flags=0x" + Integer.toHexString(parseFlags));
8457 try (ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
8458 mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,
8459 mParallelPackageParserCallback)) {
8460 // Submit files for parsing in parallel
8462 for (File file : files) {
8463 final boolean isPackage = (isApkFile(file) || file.isDirectory())
8464 && !PackageInstallerService.isStageName(file.getName());
8466 // Ignore entries which are not packages
8469 parallelPackageParser.submit(file, parseFlags);
8473 // Process results one by one
8474 for (; fileCount > 0; fileCount--) {
8475 ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
8476 Throwable throwable = parseResult.throwable;
8477 int errorCode = PackageManager.INSTALL_SUCCEEDED;
8479 if (throwable == null) {
8480 // TODO(toddke): move lower in the scan chain
8481 // Static shared libraries have synthetic package names
8482 if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
8483 renameStaticSharedLibraryPackage(parseResult.pkg);
8486 if (errorCode == PackageManager.INSTALL_SUCCEEDED) {
8487 scanPackageChildLI(parseResult.pkg, parseFlags, scanFlags,
8490 } catch (PackageManagerException e) {
8491 errorCode = e.error;
8492 Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
8494 } else if (throwable instanceof PackageParser.PackageParserException) {
8495 PackageParser.PackageParserException e = (PackageParser.PackageParserException)
8497 errorCode = e.error;
8498 Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
8500 throw new IllegalStateException("Unexpected exception occurred while parsing "
8501 + parseResult.scanFile, throwable);
8504 // Delete invalid userdata apps
8505 if ((scanFlags & SCAN_AS_SYSTEM) == 0 &&
8506 errorCode != PackageManager.INSTALL_SUCCEEDED) {
8507 logCriticalInfo(Log.WARN,
8508 "Deleting invalid package at " + parseResult.scanFile);
8509 removeCodePathLI(parseResult.scanFile);
8515 public static void reportSettingsProblem(int priority, String msg) {
8516 logCriticalInfo(priority, msg);
8519 private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg,
8520 boolean forceCollect, boolean skipVerify) throws PackageManagerException {
8521 // When upgrading from pre-N MR1, verify the package time stamp using the package
8522 // directory and not the APK file.
8523 final long lastModifiedTime = mIsPreNMR1Upgrade
8524 ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg);
8525 if (ps != null && !forceCollect
8526 && ps.codePathString.equals(pkg.codePath)
8527 && ps.timeStamp == lastModifiedTime
8528 && !isCompatSignatureUpdateNeeded(pkg)
8529 && !isRecoverSignatureUpdateNeeded(pkg)) {
8530 if (ps.signatures.mSigningDetails.signatures != null
8531 && ps.signatures.mSigningDetails.signatures.length != 0
8532 && ps.signatures.mSigningDetails.signatureSchemeVersion
8533 != SignatureSchemeVersion.UNKNOWN) {
8534 // Optimization: reuse the existing cached signing data
8535 // if the package appears to be unchanged.
8536 pkg.mSigningDetails =
8537 new PackageParser.SigningDetails(ps.signatures.mSigningDetails);
8541 Slog.w(TAG, "PackageSetting for " + ps.name
8542 + " is missing signatures. Collecting certs again to recover them.");
8544 Slog.i(TAG, pkg.codePath + " changed; collecting certs" +
8545 (forceCollect ? " (forced)" : ""));
8549 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
8550 PackageParser.collectCertificates(pkg, skipVerify);
8551 } catch (PackageParserException e) {
8552 throw PackageManagerException.from(e);
8554 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8559 * Clear the package profile if this was an upgrade and the package
8560 * version was updated.
8562 private void maybeClearProfilesForUpgradesLI(
8563 @Nullable PackageSetting originalPkgSetting,
8564 @NonNull PackageParser.Package currentPkg) {
8565 if (originalPkgSetting == null || !isUpgrade()) {
8568 if (originalPkgSetting.versionCode == currentPkg.mVersionCode) {
8572 clearAppProfilesLIF(currentPkg, UserHandle.USER_ALL);
8573 if (DEBUG_INSTALL) {
8574 Slog.d(TAG, originalPkgSetting.name
8575 + " clear profile due to version change "
8576 + originalPkgSetting.versionCode + " != "
8577 + currentPkg.mVersionCode);
8582 * Traces a package scan.
8583 * @see #scanPackageLI(File, int, int, long, UserHandle)
8585 private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
8586 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
8587 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
8589 return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
8591 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8596 * Scans a package and returns the newly parsed package.
8597 * Returns {@code null} in case of errors and the error code is stored in mLastScanError
8599 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
8600 long currentTime, UserHandle user) throws PackageManagerException {
8601 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
8602 PackageParser pp = new PackageParser();
8603 pp.setSeparateProcesses(mSeparateProcesses);
8604 pp.setOnlyCoreApps(mOnlyCore);
8605 pp.setDisplayMetrics(mMetrics);
8606 pp.setCallback(mPackageParserCallback);
8608 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
8609 final PackageParser.Package pkg;
8611 pkg = pp.parsePackage(scanFile, parseFlags);
8612 } catch (PackageParserException e) {
8613 throw PackageManagerException.from(e);
8615 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8618 // Static shared libraries have synthetic package names
8619 if (pkg.applicationInfo.isStaticSharedLibrary()) {
8620 renameStaticSharedLibraryPackage(pkg);
8623 return scanPackageChildLI(pkg, parseFlags, scanFlags, currentTime, user);
8627 * Scans a package and returns the newly parsed package.
8628 * @throws PackageManagerException on a parse error.
8630 private PackageParser.Package scanPackageChildLI(PackageParser.Package pkg,
8631 final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
8632 @Nullable UserHandle user)
8633 throws PackageManagerException {
8634 // If the package has children and this is the first dive in the function
8635 // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
8636 // packages (parent and children) would be successfully scanned before the
8637 // actual scan since scanning mutates internal state and we want to atomically
8638 // install the package and its children.
8639 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
8640 if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
8641 scanFlags |= SCAN_CHECK_ONLY;
8644 scanFlags &= ~SCAN_CHECK_ONLY;
8648 PackageParser.Package scannedPkg = addForInitLI(pkg, parseFlags,
8649 scanFlags, currentTime, user);
8651 // Scan the children
8652 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8653 for (int i = 0; i < childCount; i++) {
8654 PackageParser.Package childPackage = pkg.childPackages.get(i);
8655 addForInitLI(childPackage, parseFlags, scanFlags,
8660 if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8661 return scanPackageChildLI(pkg, parseFlags, scanFlags, currentTime, user);
8668 * Returns if full apk verification can be skipped for the whole package, including the splits.
8670 private boolean canSkipFullPackageVerification(PackageParser.Package pkg) {
8671 if (!canSkipFullApkVerification(pkg.baseCodePath)) {
8674 // TODO: Allow base and splits to be verified individually.
8675 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
8676 for (int i = 0; i < pkg.splitCodePaths.length; i++) {
8677 if (!canSkipFullApkVerification(pkg.splitCodePaths[i])) {
8686 * Returns if full apk verification can be skipped, depending on current FSVerity setup and
8687 * whether the apk contains signed root hash. Note that the signer's certificate still needs to
8688 * match one in a trusted source, and should be done separately.
8690 private boolean canSkipFullApkVerification(String apkPath) {
8691 byte[] rootHashObserved = null;
8693 rootHashObserved = VerityUtils.generateFsverityRootHash(apkPath);
8694 if (rootHashObserved == null) {
8695 return false; // APK does not contain Merkle tree root hash.
8697 synchronized (mInstallLock) {
8698 // Returns whether the observed root hash matches what kernel has.
8699 mInstaller.assertFsverityRootHashMatches(apkPath, rootHashObserved);
8702 } catch (InstallerException | IOException | DigestException |
8703 NoSuchAlgorithmException e) {
8704 Slog.w(TAG, "Error in fsverity check. Fallback to full apk verification.", e);
8710 * Adds a new package to the internal data structures during platform initialization.
8711 * <p>After adding, the package is known to the system and available for querying.
8712 * <p>For packages located on the device ROM [eg. packages located in /system, /vendor,
8713 * etc...], additional checks are performed. Basic verification [such as ensuring
8714 * matching signatures, checking version codes, etc...] occurs if the package is
8715 * identical to a previously known package. If the package fails a signature check,
8716 * the version installed on /data will be removed. If the version of the new package
8717 * is less than or equal than the version on /data, it will be ignored.
8718 * <p>Regardless of the package location, the results are applied to the internal
8719 * structures and the package is made available to the rest of the system.
8720 * <p>NOTE: The return value should be removed. It's the passed in package object.
8722 private PackageParser.Package addForInitLI(PackageParser.Package pkg,
8723 @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
8724 @Nullable UserHandle user)
8725 throws PackageManagerException {
8726 final boolean scanSystemPartition = (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0;
8727 final String renamedPkgName;
8728 final PackageSetting disabledPkgSetting;
8729 final boolean isSystemPkgUpdated;
8730 final boolean pkgAlreadyExists;
8731 PackageSetting pkgSetting;
8733 // NOTE: installPackageLI() has the same code to setup the package's
8734 // application info. This probably should be done lower in the call
8735 // stack [such as scanPackageOnly()]. However, we verify the application
8736 // info prior to that [in scanPackageNew()] and thus have to setup
8737 // the application info early.
8738 pkg.setApplicationVolumeUuid(pkg.volumeUuid);
8739 pkg.setApplicationInfoCodePath(pkg.codePath);
8740 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
8741 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
8742 pkg.setApplicationInfoResourcePath(pkg.codePath);
8743 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
8744 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
8746 synchronized (mPackages) {
8747 renamedPkgName = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
8748 final String realPkgName = getRealPackageName(pkg, renamedPkgName);
8749 if (realPkgName != null) {
8750 ensurePackageRenamed(pkg, renamedPkgName);
8752 final PackageSetting originalPkgSetting = getOriginalPackageLocked(pkg, renamedPkgName);
8753 final PackageSetting installedPkgSetting = mSettings.getPackageLPr(pkg.packageName);
8754 pkgSetting = originalPkgSetting == null ? installedPkgSetting : originalPkgSetting;
8755 pkgAlreadyExists = pkgSetting != null;
8756 final String disabledPkgName = pkgAlreadyExists ? pkgSetting.name : pkg.packageName;
8757 disabledPkgSetting = mSettings.getDisabledSystemPkgLPr(disabledPkgName);
8758 isSystemPkgUpdated = disabledPkgSetting != null;
8760 if (DEBUG_INSTALL && isSystemPkgUpdated) {
8761 Slog.d(TAG, "updatedPkg = " + disabledPkgSetting);
8764 final SharedUserSetting sharedUserSetting = (pkg.mSharedUserId != null)
8765 ? mSettings.getSharedUserLPw(pkg.mSharedUserId,
8766 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true)
8768 if (DEBUG_PACKAGE_SCANNING
8769 && (parseFlags & PackageParser.PARSE_CHATTY) != 0
8770 && sharedUserSetting != null) {
8771 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId
8772 + " (uid=" + sharedUserSetting.userId + "):"
8773 + " packages=" + sharedUserSetting.packages);
8776 if (scanSystemPartition) {
8777 // Potentially prune child packages. If the application on the /system
8778 // partition has been updated via OTA, but, is still disabled by a
8779 // version on /data, cycle through all of its children packages and
8780 // remove children that are no longer defined.
8781 if (isSystemPkgUpdated) {
8782 final int scannedChildCount = (pkg.childPackages != null)
8783 ? pkg.childPackages.size() : 0;
8784 final int disabledChildCount = disabledPkgSetting.childPackageNames != null
8785 ? disabledPkgSetting.childPackageNames.size() : 0;
8786 for (int i = 0; i < disabledChildCount; i++) {
8787 String disabledChildPackageName =
8788 disabledPkgSetting.childPackageNames.get(i);
8789 boolean disabledPackageAvailable = false;
8790 for (int j = 0; j < scannedChildCount; j++) {
8791 PackageParser.Package childPkg = pkg.childPackages.get(j);
8792 if (childPkg.packageName.equals(disabledChildPackageName)) {
8793 disabledPackageAvailable = true;
8797 if (!disabledPackageAvailable) {
8798 mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
8801 // we're updating the disabled package, so, scan it as the package setting
8802 final ScanRequest request = new ScanRequest(pkg, sharedUserSetting, null,
8803 disabledPkgSetting /* pkgSetting */, null /* disabledPkgSetting */,
8804 null /* originalPkgSetting */, null, parseFlags, scanFlags,
8805 (pkg == mPlatformPackage), user);
8806 applyPolicy(pkg, parseFlags, scanFlags, mPlatformPackage);
8807 scanPackageOnlyLI(request, mFactoryTest, -1L);
8812 final boolean newPkgChangedPaths =
8813 pkgAlreadyExists && !pkgSetting.codePathString.equals(pkg.codePath);
8814 final boolean newPkgVersionGreater =
8815 pkgAlreadyExists && pkg.getLongVersionCode() > pkgSetting.versionCode;
8816 final boolean isSystemPkgBetter = scanSystemPartition && isSystemPkgUpdated
8817 && newPkgChangedPaths && newPkgVersionGreater;
8818 if (isSystemPkgBetter) {
8819 // The version of the application on /system is greater than the version on
8820 // /data. Switch back to the application on /system.
8821 // It's safe to assume the application on /system will correctly scan. If not,
8822 // there won't be a working copy of the application.
8823 synchronized (mPackages) {
8824 // just remove the loaded entries from package lists
8825 mPackages.remove(pkgSetting.name);
8828 logCriticalInfo(Log.WARN,
8829 "System package updated;"
8830 + " name: " + pkgSetting.name
8831 + "; " + pkgSetting.versionCode + " --> " + pkg.getLongVersionCode()
8832 + "; " + pkgSetting.codePathString + " --> " + pkg.codePath);
8834 final InstallArgs args = createInstallArgsForExisting(
8835 packageFlagsToInstallFlags(pkgSetting), pkgSetting.codePathString,
8836 pkgSetting.resourcePathString, getAppDexInstructionSets(pkgSetting));
8837 args.cleanUpResourcesLI();
8838 synchronized (mPackages) {
8839 mSettings.enableSystemPackageLPw(pkgSetting.name);
8843 if (scanSystemPartition && isSystemPkgUpdated && !isSystemPkgBetter) {
8844 // The version of the application on the /system partition is less than or
8845 // equal to the version on the /data partition. Even though the disabled system package
8846 // is likely to be replaced by a version on the /data partition, we make assumptions
8847 // that it's part of the mPackages collection during package manager initialization. So,
8848 // add it to mPackages if there isn't already a package in the collection and then throw
8849 // an exception to use the application already installed on the /data partition.
8850 synchronized (mPackages) {
8851 if (!mPackages.containsKey(pkg.packageName)) {
8852 mPackages.put(pkg.packageName, pkg);
8855 throw new PackageManagerException(Log.WARN, "Package " + pkg.packageName + " at "
8856 + pkg.codePath + " ignored: updated version " + pkgSetting.versionCode
8857 + " better than this " + pkg.getLongVersionCode());
8860 // Verify certificates against what was last scanned. If it is an updated priv app, we will
8861 // force re-collecting certificate.
8862 final boolean forceCollect = PackageManagerServiceUtils.isApkVerificationForced(
8863 disabledPkgSetting);
8864 // Full APK verification can be skipped during certificate collection, only if the file is
8865 // in verified partition, or can be verified on access (when apk verity is enabled). In both
8866 // cases, only data in Signing Block is verified instead of the whole file.
8867 final boolean skipVerify = ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) ||
8868 (forceCollect && canSkipFullPackageVerification(pkg));
8869 collectCertificatesLI(pkgSetting, pkg, forceCollect, skipVerify);
8871 // Reset profile if the application version is changed
8872 maybeClearProfilesForUpgradesLI(pkgSetting, pkg);
8875 * A new system app appeared, but we already had a non-system one of the
8876 * same name installed earlier.
8878 boolean shouldHideSystemApp = false;
8879 // A new application appeared on /system, but, we already have a copy of
8880 // the application installed on /data.
8881 if (scanSystemPartition && !isSystemPkgUpdated && pkgAlreadyExists
8882 && !pkgSetting.isSystem()) {
8884 if (!pkg.mSigningDetails.checkCapability(pkgSetting.signatures.mSigningDetails,
8885 PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA)
8886 && !pkgSetting.signatures.mSigningDetails.checkCapability(
8887 pkg.mSigningDetails,
8888 PackageParser.SigningDetails.CertCapabilities.ROLLBACK)) {
8889 logCriticalInfo(Log.WARN,
8890 "System package signature mismatch;"
8891 + " name: " + pkgSetting.name);
8892 try (PackageFreezer freezer = freezePackage(pkg.packageName,
8893 "scanPackageInternalLI")) {
8894 deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
8897 } else if (newPkgVersionGreater) {
8898 // The application on /system is newer than the application on /data.
8899 // Simply remove the application on /data [keeping application data]
8900 // and replace it with the version on /system.
8901 logCriticalInfo(Log.WARN,
8902 "System package enabled;"
8903 + " name: " + pkgSetting.name
8904 + "; " + pkgSetting.versionCode + " --> " + pkg.getLongVersionCode()
8905 + "; " + pkgSetting.codePathString + " --> " + pkg.codePath);
8906 InstallArgs args = createInstallArgsForExisting(
8907 packageFlagsToInstallFlags(pkgSetting), pkgSetting.codePathString,
8908 pkgSetting.resourcePathString, getAppDexInstructionSets(pkgSetting));
8909 synchronized (mInstallLock) {
8910 args.cleanUpResourcesLI();
8913 // The application on /system is older than the application on /data. Hide
8914 // the application on /system and the version on /data will be scanned later
8915 // and re-added like an update.
8916 shouldHideSystemApp = true;
8917 logCriticalInfo(Log.INFO,
8918 "System package disabled;"
8919 + " name: " + pkgSetting.name
8920 + "; old: " + pkgSetting.codePathString + " @ " + pkgSetting.versionCode
8921 + "; new: " + pkg.codePath + " @ " + pkg.codePath);
8925 final PackageParser.Package scannedPkg = scanPackageNewLI(pkg, parseFlags, scanFlags
8926 | SCAN_UPDATE_SIGNATURE, currentTime, user);
8928 if (shouldHideSystemApp) {
8929 synchronized (mPackages) {
8930 mSettings.disableSystemPackageLPw(pkg.packageName, true);
8936 private static void renameStaticSharedLibraryPackage(PackageParser.Package pkg) {
8937 // Derive the new package synthetic package name
8938 pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER
8939 + pkg.staticSharedLibVersion);
8942 private static String fixProcessName(String defProcessName,
8943 String processName) {
8944 if (processName == null) {
8945 return defProcessName;
8951 * Enforces that only the system UID or root's UID can call a method exposed
8954 * @param message used as message if SecurityException is thrown
8955 * @throws SecurityException if the caller is not system or root
8957 private static final void enforceSystemOrRoot(String message) {
8958 final int uid = Binder.getCallingUid();
8959 if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID) {
8960 throw new SecurityException(message);
8965 public void performFstrimIfNeeded() {
8966 enforceSystemOrRoot("Only the system can request fstrim");
8968 // Before everything else, see whether we need to fstrim.
8970 IStorageManager sm = PackageHelper.getStorageManager();
8972 boolean doTrim = false;
8973 final long interval = android.provider.Settings.Global.getLong(
8974 mContext.getContentResolver(),
8975 android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
8976 DEFAULT_MANDATORY_FSTRIM_INTERVAL);
8978 final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
8979 if (timeSinceLast > interval) {
8981 Slog.w(TAG, "No disk maintenance in " + timeSinceLast
8982 + "; running immediately");
8986 final boolean dexOptDialogShown;
8987 synchronized (mPackages) {
8988 dexOptDialogShown = mDexOptDialogShown;
8990 if (!isFirstBoot() && dexOptDialogShown) {
8992 ActivityManager.getService().showBootMessage(
8993 mContext.getResources().getString(
8994 R.string.android_upgrading_fstrim), true);
8995 } catch (RemoteException e) {
8998 sm.runMaintenance();
9001 Slog.e(TAG, "storageManager service unavailable!");
9003 } catch (RemoteException e) {
9004 // Can't happen; StorageManagerService is local
9009 public void updatePackagesIfNeeded() {
9010 enforceSystemOrRoot("Only the system can request package update");
9012 // We need to re-extract after an OTA.
9013 boolean causeUpgrade = isUpgrade();
9015 // First boot or factory reset.
9016 // Note: we also handle devices that are upgrading to N right now as if it is their
9017 // first boot, as they do not have profile data.
9018 boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
9020 // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
9021 boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
9023 if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
9027 List<PackageParser.Package> pkgs;
9028 synchronized (mPackages) {
9029 pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
9032 final long startTime = System.nanoTime();
9033 final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
9034 causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT,
9035 false /* bootComplete */);
9037 final int elapsedTimeSeconds =
9038 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
9040 MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
9041 MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
9042 MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
9043 MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
9044 MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
9048 * Return the prebuilt profile path given a package base code path.
9050 private static String getPrebuildProfilePath(PackageParser.Package pkg) {
9051 return pkg.baseCodePath + ".prof";
9055 * Performs dexopt on the set of packages in {@code packages} and returns an int array
9056 * containing statistics about the invocation. The array consists of three elements,
9057 * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
9058 * and {@code numberOfPackagesFailed}.
9060 private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
9061 final int compilationReason, boolean bootComplete) {
9063 int numberOfPackagesVisited = 0;
9064 int numberOfPackagesOptimized = 0;
9065 int numberOfPackagesSkipped = 0;
9066 int numberOfPackagesFailed = 0;
9067 final int numberOfPackagesToDexopt = pkgs.size();
9069 for (PackageParser.Package pkg : pkgs) {
9070 numberOfPackagesVisited++;
9072 boolean useProfileForDexopt = false;
9074 if ((isFirstBoot() || isUpgrade()) && isSystemApp(pkg)) {
9075 // Copy over initial preopt profiles since we won't get any JIT samples for methods
9076 // that are already compiled.
9077 File profileFile = new File(getPrebuildProfilePath(pkg));
9078 // Copy profile if it exists.
9079 if (profileFile.exists()) {
9081 // We could also do this lazily before calling dexopt in
9082 // PackageDexOptimizer to prevent this happening on first boot. The issue
9083 // is that we don't have a good way to say "do this only once".
9084 if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
9085 pkg.applicationInfo.uid, pkg.packageName,
9086 ArtManager.getProfileName(null))) {
9087 Log.e(TAG, "Installer failed to copy system profile!");
9089 // Disabled as this causes speed-profile compilation during first boot
9090 // even if things are already compiled.
9091 // useProfileForDexopt = true;
9093 } catch (Exception e) {
9094 Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ",
9098 PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
9099 // Handle compressed APKs in this path. Only do this for stubs with profiles to
9100 // minimize the number off apps being speed-profile compiled during first boot.
9101 // The other paths will not change the filter.
9102 if (disabledPs != null && disabledPs.pkg.isStub) {
9103 // The package is the stub one, remove the stub suffix to get the normal
9104 // package and APK names.
9105 String systemProfilePath =
9106 getPrebuildProfilePath(disabledPs.pkg).replace(STUB_SUFFIX, "");
9107 profileFile = new File(systemProfilePath);
9108 // If we have a profile for a compressed APK, copy it to the reference
9110 // Note that copying the profile here will cause it to override the
9111 // reference profile every OTA even though the existing reference profile
9112 // may have more data. We can't copy during decompression since the
9113 // directories are not set up at that point.
9114 if (profileFile.exists()) {
9116 // We could also do this lazily before calling dexopt in
9117 // PackageDexOptimizer to prevent this happening on first boot. The
9118 // issue is that we don't have a good way to say "do this only
9120 if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
9121 pkg.applicationInfo.uid, pkg.packageName,
9122 ArtManager.getProfileName(null))) {
9123 Log.e(TAG, "Failed to copy system profile for stub package!");
9125 useProfileForDexopt = true;
9127 } catch (Exception e) {
9128 Log.e(TAG, "Failed to copy profile " +
9129 profileFile.getAbsolutePath() + " ", e);
9136 if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
9138 Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
9140 numberOfPackagesSkipped++;
9145 Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
9146 numberOfPackagesToDexopt + ": " + pkg.packageName);
9151 ActivityManager.getService().showBootMessage(
9152 mContext.getResources().getString(R.string.android_upgrading_apk,
9153 numberOfPackagesVisited, numberOfPackagesToDexopt), true);
9154 } catch (RemoteException e) {
9156 synchronized (mPackages) {
9157 mDexOptDialogShown = true;
9161 int pkgCompilationReason = compilationReason;
9162 if (useProfileForDexopt) {
9163 // Use background dexopt mode to try and use the profile. Note that this does not
9164 // guarantee usage of the profile.
9165 pkgCompilationReason = PackageManagerService.REASON_BACKGROUND_DEXOPT;
9168 // checkProfiles is false to avoid merging profiles during boot which
9169 // might interfere with background compilation (b/28612421).
9170 // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
9171 // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
9172 // trade-off worth doing to save boot time work.
9173 int dexoptFlags = bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0;
9174 if (compilationReason == REASON_FIRST_BOOT) {
9175 // TODO: This doesn't cover the upgrade case, we should check for this too.
9176 dexoptFlags |= DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE;
9178 int primaryDexOptStaus = performDexOptTraced(new DexoptOptions(
9180 pkgCompilationReason,
9183 switch (primaryDexOptStaus) {
9184 case PackageDexOptimizer.DEX_OPT_PERFORMED:
9185 numberOfPackagesOptimized++;
9187 case PackageDexOptimizer.DEX_OPT_SKIPPED:
9188 numberOfPackagesSkipped++;
9190 case PackageDexOptimizer.DEX_OPT_FAILED:
9191 numberOfPackagesFailed++;
9194 Log.e(TAG, "Unexpected dexopt return code " + primaryDexOptStaus);
9199 return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
9200 numberOfPackagesFailed };
9204 public void notifyPackageUse(String packageName, int reason) {
9205 synchronized (mPackages) {
9206 final int callingUid = Binder.getCallingUid();
9207 final int callingUserId = UserHandle.getUserId(callingUid);
9208 if (getInstantAppPackageName(callingUid) != null) {
9209 if (!isCallerSameApp(packageName, callingUid)) {
9213 if (isInstantApp(packageName, callingUserId)) {
9217 notifyPackageUseLocked(packageName, reason);
9221 @GuardedBy("mPackages")
9222 private void notifyPackageUseLocked(String packageName, int reason) {
9223 final PackageParser.Package p = mPackages.get(packageName);
9227 p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
9231 public void notifyDexLoad(String loadingPackageName, List<String> classLoaderNames,
9232 List<String> classPaths, String loaderIsa) {
9233 int userId = UserHandle.getCallingUserId();
9234 ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
9236 Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
9237 + loadingPackageName + ", user=" + userId);
9240 mDexManager.notifyDexLoad(ai, classLoaderNames, classPaths, loaderIsa, userId);
9244 public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule,
9245 IDexModuleRegisterCallback callback) {
9246 int userId = UserHandle.getCallingUserId();
9247 ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId);
9248 DexManager.RegisterDexModuleResult result;
9250 Slog.w(TAG, "Registering a dex module for a package that does not exist for the" +
9251 " calling user. package=" + packageName + ", user=" + userId);
9252 result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
9254 result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId);
9257 if (callback != null) {
9258 mHandler.post(() -> {
9260 callback.onDexModuleRegistered(dexModulePath, result.success, result.message);
9261 } catch (RemoteException e) {
9262 Slog.w(TAG, "Failed to callback after module registration " + dexModulePath, e);
9269 * Ask the package manager to perform a dex-opt with the given compiler filter.
9271 * Note: exposed only for the shell command to allow moving packages explicitly to a
9275 public boolean performDexOptMode(String packageName,
9276 boolean checkProfiles, String targetCompilerFilter, boolean force,
9277 boolean bootComplete, String splitName) {
9278 int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0) |
9279 (force ? DexoptOptions.DEXOPT_FORCE : 0) |
9280 (bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0);
9281 return performDexOpt(new DexoptOptions(packageName, REASON_UNKNOWN,
9282 targetCompilerFilter, splitName, flags));
9286 * Ask the package manager to perform a dex-opt with the given compiler filter on the
9287 * secondary dex files belonging to the given package.
9289 * Note: exposed only for the shell command to allow moving packages explicitly to a
9293 public boolean performDexOptSecondary(String packageName, String compilerFilter,
9295 int flags = DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
9296 DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
9297 DexoptOptions.DEXOPT_BOOT_COMPLETE |
9298 (force ? DexoptOptions.DEXOPT_FORCE : 0);
9299 return performDexOpt(new DexoptOptions(packageName, compilerFilter, flags));
9302 /*package*/ boolean performDexOpt(DexoptOptions options) {
9303 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9305 } else if (isInstantApp(options.getPackageName(), UserHandle.getCallingUserId())) {
9309 if (options.isDexoptOnlySecondaryDex()) {
9310 return mDexManager.dexoptSecondaryDex(options);
9312 int dexoptStatus = performDexOptWithStatus(options);
9313 return dexoptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
9318 * Perform dexopt on the given package and return one of following result:
9319 * {@link PackageDexOptimizer#DEX_OPT_SKIPPED}
9320 * {@link PackageDexOptimizer#DEX_OPT_PERFORMED}
9321 * {@link PackageDexOptimizer#DEX_OPT_FAILED}
9323 /* package */ int performDexOptWithStatus(DexoptOptions options) {
9324 return performDexOptTraced(options);
9327 private int performDexOptTraced(DexoptOptions options) {
9328 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9330 return performDexOptInternal(options);
9332 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9336 // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
9337 // if the package can now be considered up to date for the given filter.
9338 private int performDexOptInternal(DexoptOptions options) {
9339 PackageParser.Package p;
9340 synchronized (mPackages) {
9341 p = mPackages.get(options.getPackageName());
9343 // Package could not be found. Report failure.
9344 return PackageDexOptimizer.DEX_OPT_FAILED;
9346 mPackageUsage.maybeWriteAsync(mPackages);
9347 mCompilerStats.maybeWriteAsync();
9349 long callingId = Binder.clearCallingIdentity();
9351 synchronized (mInstallLock) {
9352 return performDexOptInternalWithDependenciesLI(p, options);
9355 Binder.restoreCallingIdentity(callingId);
9359 public ArraySet<String> getOptimizablePackages() {
9360 ArraySet<String> pkgs = new ArraySet<String>();
9361 synchronized (mPackages) {
9362 for (PackageParser.Package p : mPackages.values()) {
9363 if (PackageDexOptimizer.canOptimizePackage(p)) {
9364 pkgs.add(p.packageName);
9371 private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
9372 DexoptOptions options) {
9373 // Select the dex optimizer based on the force parameter.
9374 // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
9375 // allocate an object here.
9376 PackageDexOptimizer pdo = options.isForce()
9377 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
9378 : mPackageDexOptimizer;
9380 // Dexopt all dependencies first. Note: we ignore the return value and march on
9382 // Note that we are going to call performDexOpt on those libraries as many times as
9383 // they are referenced in packages. When we do a batch of performDexOpt (for example
9384 // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
9385 // and the first package that uses the library will dexopt it. The
9386 // others will see that the compiled code for the library is up to date.
9387 Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
9388 final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
9389 if (!deps.isEmpty()) {
9390 DexoptOptions libraryOptions = new DexoptOptions(options.getPackageName(),
9391 options.getCompilationReason(), options.getCompilerFilter(),
9392 options.getSplitName(),
9393 options.getFlags() | DexoptOptions.DEXOPT_AS_SHARED_LIBRARY);
9394 for (PackageParser.Package depPackage : deps) {
9395 // TODO: Analyze and investigate if we (should) profile libraries.
9396 pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
9397 getOrCreateCompilerPackageStats(depPackage),
9398 mDexManager.getPackageUseInfoOrDefault(depPackage.packageName), libraryOptions);
9401 return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets,
9402 getOrCreateCompilerPackageStats(p),
9403 mDexManager.getPackageUseInfoOrDefault(p.packageName), options);
9407 * Reconcile the information we have about the secondary dex files belonging to
9408 * {@code packagName} and the actual dex files. For all dex files that were
9409 * deleted, update the internal records and delete the generated oat files.
9412 public void reconcileSecondaryDexFiles(String packageName) {
9413 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9415 } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
9418 mDexManager.reconcileSecondaryDexFiles(packageName);
9421 // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
9422 // a reference there.
9423 /*package*/ DexManager getDexManager() {
9428 * Execute the background dexopt job immediately.
9431 public boolean runBackgroundDexoptJob(@Nullable List<String> packageNames) {
9432 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9435 return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext, packageNames);
9438 List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
9439 if (p.usesLibraries != null || p.usesOptionalLibraries != null
9440 || p.usesStaticLibraries != null) {
9441 ArrayList<PackageParser.Package> retValue = new ArrayList<>();
9442 Set<String> collectedNames = new HashSet<>();
9443 findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
9449 return Collections.emptyList();
9453 private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
9454 ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9455 if (!collectedNames.contains(p.packageName)) {
9456 collectedNames.add(p.packageName);
9459 if (p.usesLibraries != null) {
9460 findSharedNonSystemLibrariesRecursive(p.usesLibraries,
9461 null, collected, collectedNames);
9463 if (p.usesOptionalLibraries != null) {
9464 findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries,
9465 null, collected, collectedNames);
9467 if (p.usesStaticLibraries != null) {
9468 findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries,
9469 p.usesStaticLibrariesVersions, collected, collectedNames);
9474 private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, long[] versions,
9475 ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9476 final int libNameCount = libs.size();
9477 for (int i = 0; i < libNameCount; i++) {
9478 String libName = libs.get(i);
9479 long version = (versions != null && versions.length == libNameCount)
9480 ? versions[i] : PackageManager.VERSION_CODE_HIGHEST;
9481 PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version);
9482 if (libPkg != null) {
9483 findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
9488 private PackageParser.Package findSharedNonSystemLibrary(String name, long version) {
9489 synchronized (mPackages) {
9490 SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version);
9491 if (libEntry != null) {
9492 return mPackages.get(libEntry.apk);
9498 private SharedLibraryEntry getSharedLibraryEntryLPr(String name, long version) {
9499 LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
9500 if (versionedLib == null) {
9503 return versionedLib.get(version);
9506 private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
9507 LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
9508 pkg.staticSharedLibName);
9509 if (versionedLib == null) {
9512 long previousLibVersion = -1;
9513 final int versionCount = versionedLib.size();
9514 for (int i = 0; i < versionCount; i++) {
9515 final long libVersion = versionedLib.keyAt(i);
9516 if (libVersion < pkg.staticSharedLibVersion) {
9517 previousLibVersion = Math.max(previousLibVersion, libVersion);
9520 if (previousLibVersion >= 0) {
9521 return versionedLib.get(previousLibVersion);
9526 public void shutdown() {
9527 mPackageUsage.writeNow(mPackages);
9528 mCompilerStats.writeNow();
9529 mDexManager.writePackageDexUsageNow();
9531 // This is the last chance to write out pending restriction settings
9532 synchronized (mPackages) {
9533 if (mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
9534 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
9535 for (int userId : mDirtyUsers) {
9536 mSettings.writePackageRestrictionsLPr(userId);
9538 mDirtyUsers.clear();
9544 public void dumpProfiles(String packageName) {
9545 PackageParser.Package pkg;
9546 synchronized (mPackages) {
9547 pkg = mPackages.get(packageName);
9549 throw new IllegalArgumentException("Unknown package: " + packageName);
9552 /* Only the shell, root, or the app user should be able to dump profiles. */
9553 int callingUid = Binder.getCallingUid();
9554 if (callingUid != Process.SHELL_UID &&
9555 callingUid != Process.ROOT_UID &&
9556 callingUid != pkg.applicationInfo.uid) {
9557 throw new SecurityException("dumpProfiles");
9560 synchronized (mInstallLock) {
9561 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
9562 mArtManagerService.dumpProfiles(pkg);
9563 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9568 public void forceDexOpt(String packageName) {
9569 enforceSystemOrRoot("forceDexOpt");
9571 PackageParser.Package pkg;
9572 synchronized (mPackages) {
9573 pkg = mPackages.get(packageName);
9575 throw new IllegalArgumentException("Unknown package: " + packageName);
9579 synchronized (mInstallLock) {
9580 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9582 // Whoever is calling forceDexOpt wants a compiled package.
9583 // Don't use profiles since that may cause compilation to be skipped.
9584 final int res = performDexOptInternalWithDependenciesLI(
9586 new DexoptOptions(packageName,
9587 getDefaultCompilerFilter(),
9588 DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE));
9590 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9591 if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
9592 throw new IllegalStateException("Failed to dexopt: " + res);
9597 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
9598 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9599 Slog.w(TAG, "Unable to update from " + oldPkg.name
9600 + " to " + newPkg.packageName
9601 + ": old package not in system partition");
9603 } else if (mPackages.get(oldPkg.name) != null) {
9604 Slog.w(TAG, "Unable to update from " + oldPkg.name
9605 + " to " + newPkg.packageName
9606 + ": old package still exists");
9612 void removeCodePathLI(File codePath) {
9613 if (codePath.isDirectory()) {
9615 mInstaller.rmPackageDir(codePath.getAbsolutePath());
9616 } catch (InstallerException e) {
9617 Slog.w(TAG, "Failed to remove code path", e);
9624 private int[] resolveUserIds(int userId) {
9625 return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
9628 private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
9630 Slog.wtf(TAG, "Package was null!", new Throwable());
9633 clearAppDataLeafLIF(pkg, userId, flags);
9634 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9635 for (int i = 0; i < childCount; i++) {
9636 clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
9639 clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
9642 private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
9643 final PackageSetting ps;
9644 synchronized (mPackages) {
9645 ps = mSettings.mPackages.get(pkg.packageName);
9647 for (int realUserId : resolveUserIds(userId)) {
9648 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9650 mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
9652 } catch (InstallerException e) {
9653 Slog.w(TAG, String.valueOf(e));
9658 private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
9660 Slog.wtf(TAG, "Package was null!", new Throwable());
9663 destroyAppDataLeafLIF(pkg, userId, flags);
9664 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9665 for (int i = 0; i < childCount; i++) {
9666 destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
9670 private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
9671 final PackageSetting ps;
9672 synchronized (mPackages) {
9673 ps = mSettings.mPackages.get(pkg.packageName);
9675 for (int realUserId : resolveUserIds(userId)) {
9676 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9678 mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
9680 } catch (InstallerException e) {
9681 Slog.w(TAG, String.valueOf(e));
9683 mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
9687 private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
9689 Slog.wtf(TAG, "Package was null!", new Throwable());
9692 destroyAppProfilesLeafLIF(pkg);
9693 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9694 for (int i = 0; i < childCount; i++) {
9695 destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
9699 private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
9701 mInstaller.destroyAppProfiles(pkg.packageName);
9702 } catch (InstallerException e) {
9703 Slog.w(TAG, String.valueOf(e));
9707 private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
9709 Slog.wtf(TAG, "Package was null!", new Throwable());
9712 mArtManagerService.clearAppProfiles(pkg);
9713 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9714 for (int i = 0; i < childCount; i++) {
9715 mArtManagerService.clearAppProfiles(pkg.childPackages.get(i));
9719 private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
9720 long lastUpdateTime) {
9721 // Set parent install/update time
9722 PackageSetting ps = (PackageSetting) pkg.mExtras;
9724 ps.firstInstallTime = firstInstallTime;
9725 ps.lastUpdateTime = lastUpdateTime;
9727 // Set children install/update time
9728 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9729 for (int i = 0; i < childCount; i++) {
9730 PackageParser.Package childPkg = pkg.childPackages.get(i);
9731 ps = (PackageSetting) childPkg.mExtras;
9733 ps.firstInstallTime = firstInstallTime;
9734 ps.lastUpdateTime = lastUpdateTime;
9739 private void addSharedLibraryLPr(Set<String> usesLibraryFiles,
9740 SharedLibraryEntry file,
9741 PackageParser.Package changingLib) {
9742 if (file.path != null) {
9743 usesLibraryFiles.add(file.path);
9746 PackageParser.Package p = mPackages.get(file.apk);
9747 if (changingLib != null && changingLib.packageName.equals(file.apk)) {
9748 // If we are doing this while in the middle of updating a library apk,
9749 // then we need to make sure to use that new apk for determining the
9750 // dependencies here. (We haven't yet finished committing the new apk
9751 // to the package manager state.)
9752 if (p == null || p.packageName.equals(changingLib.packageName)) {
9757 usesLibraryFiles.addAll(p.getAllCodePaths());
9758 if (p.usesLibraryFiles != null) {
9759 Collections.addAll(usesLibraryFiles, p.usesLibraryFiles);
9764 private void updateSharedLibrariesLPr(PackageParser.Package pkg,
9765 PackageParser.Package changingLib) throws PackageManagerException {
9769 // The collection used here must maintain the order of addition (so
9770 // that libraries are searched in the correct order) and must have no
9772 Set<String> usesLibraryFiles = null;
9773 if (pkg.usesLibraries != null) {
9774 usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries,
9775 null, null, pkg.packageName, changingLib, true,
9776 pkg.applicationInfo.targetSdkVersion, null);
9778 if (pkg.usesStaticLibraries != null) {
9779 usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries,
9780 pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests,
9781 pkg.packageName, changingLib, true,
9782 pkg.applicationInfo.targetSdkVersion, usesLibraryFiles);
9784 if (pkg.usesOptionalLibraries != null) {
9785 usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries,
9786 null, null, pkg.packageName, changingLib, false,
9787 pkg.applicationInfo.targetSdkVersion, usesLibraryFiles);
9789 if (!ArrayUtils.isEmpty(usesLibraryFiles)) {
9790 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
9792 pkg.usesLibraryFiles = null;
9796 private Set<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
9797 @Nullable long[] requiredVersions, @Nullable String[][] requiredCertDigests,
9798 @NonNull String packageName, @Nullable PackageParser.Package changingLib,
9799 boolean required, int targetSdk, @Nullable Set<String> outUsedLibraries)
9800 throws PackageManagerException {
9801 final int libCount = requestedLibraries.size();
9802 for (int i = 0; i < libCount; i++) {
9803 final String libName = requestedLibraries.get(i);
9804 final long libVersion = requiredVersions != null ? requiredVersions[i]
9805 : SharedLibraryInfo.VERSION_UNDEFINED;
9806 final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion);
9807 if (libEntry == null) {
9809 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9810 "Package " + packageName + " requires unavailable shared library "
9811 + libName + "; failing!");
9812 } else if (DEBUG_SHARED_LIBRARIES) {
9813 Slog.i(TAG, "Package " + packageName
9814 + " desires unavailable shared library "
9815 + libName + "; ignoring!");
9818 if (requiredVersions != null && requiredCertDigests != null) {
9819 if (libEntry.info.getLongVersion() != requiredVersions[i]) {
9820 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9821 "Package " + packageName + " requires unavailable static shared"
9822 + " library " + libName + " version "
9823 + libEntry.info.getLongVersion() + "; failing!");
9826 PackageParser.Package libPkg = mPackages.get(libEntry.apk);
9827 if (libPkg == null) {
9828 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9829 "Package " + packageName + " requires unavailable static shared"
9830 + " library; failing!");
9833 final String[] expectedCertDigests = requiredCertDigests[i];
9836 if (expectedCertDigests.length > 1) {
9838 // For apps targeting O MR1 we require explicit enumeration of all certs.
9839 final String[] libCertDigests = (targetSdk >= Build.VERSION_CODES.O_MR1)
9840 ? PackageUtils.computeSignaturesSha256Digests(
9841 libPkg.mSigningDetails.signatures)
9842 : PackageUtils.computeSignaturesSha256Digests(
9843 new Signature[]{libPkg.mSigningDetails.signatures[0]});
9845 // Take a shortcut if sizes don't match. Note that if an app doesn't
9846 // target O we don't parse the "additional-certificate" tags similarly
9847 // how we only consider all certs only for apps targeting O (see above).
9848 // Therefore, the size check is safe to make.
9849 if (expectedCertDigests.length != libCertDigests.length) {
9850 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9851 "Package " + packageName + " requires differently signed" +
9852 " static shared library; failing!");
9855 // Use a predictable order as signature order may vary
9856 Arrays.sort(libCertDigests);
9857 Arrays.sort(expectedCertDigests);
9859 final int certCount = libCertDigests.length;
9860 for (int j = 0; j < certCount; j++) {
9861 if (!libCertDigests[j].equalsIgnoreCase(expectedCertDigests[j])) {
9862 throw new PackageManagerException(
9863 INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9864 "Package " + packageName + " requires differently signed" +
9865 " static shared library; failing!");
9870 // lib signing cert could have rotated beyond the one expected, check to see
9871 // if the new one has been blessed by the old
9872 if (!libPkg.mSigningDetails.hasSha256Certificate(
9873 ByteStringUtils.fromHexToByteArray(expectedCertDigests[0]))) {
9874 throw new PackageManagerException(
9875 INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9876 "Package " + packageName + " requires differently signed" +
9877 " static shared library; failing!");
9882 if (outUsedLibraries == null) {
9883 // Use LinkedHashSet to preserve the order of files added to
9884 // usesLibraryFiles while eliminating duplicates.
9885 outUsedLibraries = new LinkedHashSet<>();
9887 addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib);
9890 return outUsedLibraries;
9893 private static boolean hasString(List<String> list, List<String> which) {
9897 for (int i=list.size()-1; i>=0; i--) {
9898 for (int j=which.size()-1; j>=0; j--) {
9899 if (which.get(j).equals(list.get(i))) {
9907 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
9908 PackageParser.Package changingPkg) {
9909 ArrayList<PackageParser.Package> res = null;
9910 for (PackageParser.Package pkg : mPackages.values()) {
9911 if (changingPkg != null
9912 && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
9913 && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
9914 && !ArrayUtils.contains(pkg.usesStaticLibraries,
9915 changingPkg.staticSharedLibName)) {
9919 res = new ArrayList<>();
9923 updateSharedLibrariesLPr(pkg, changingPkg);
9924 } catch (PackageManagerException e) {
9925 // If a system app update or an app and a required lib missing we
9926 // delete the package and for updated system apps keep the data as
9927 // it is better for the user to reinstall than to be in an limbo
9928 // state. Also libs disappearing under an app should never happen
9930 if (!pkg.isSystem() || pkg.isUpdatedSystemApp()) {
9931 final int flags = pkg.isUpdatedSystemApp()
9932 ? PackageManager.DELETE_KEEP_DATA : 0;
9933 deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
9934 flags , null, true, null);
9936 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
9942 private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
9943 final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
9944 @Nullable UserHandle user) throws PackageManagerException {
9945 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
9946 // If the package has children and this is the first dive in the function
9947 // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
9948 // whether all packages (parent and children) would be successfully scanned
9949 // before the actual scan since scanning mutates internal state and we want
9950 // to atomically install the package and its children.
9951 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9952 if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
9953 scanFlags |= SCAN_CHECK_ONLY;
9956 scanFlags &= ~SCAN_CHECK_ONLY;
9959 final PackageParser.Package scannedPkg;
9962 scannedPkg = scanPackageNewLI(pkg, parseFlags, scanFlags, currentTime, user);
9963 // Scan the children
9964 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9965 for (int i = 0; i < childCount; i++) {
9966 PackageParser.Package childPkg = pkg.childPackages.get(i);
9967 scanPackageNewLI(childPkg, parseFlags,
9968 scanFlags, currentTime, user);
9971 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9974 if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9975 return scanPackageTracedLI(pkg, parseFlags, scanFlags, currentTime, user);
9981 /** The result of a package scan. */
9982 private static class ScanResult {
9983 /** Whether or not the package scan was successful */
9984 public final boolean success;
9986 * The final package settings. This may be the same object passed in
9987 * the {@link ScanRequest}, but, with modified values.
9989 @Nullable public final PackageSetting pkgSetting;
9990 /** ABI code paths that have changed in the package scan */
9991 @Nullable public final List<String> changedAbiCodePath;
9994 @Nullable PackageSetting pkgSetting,
9995 @Nullable List<String> changedAbiCodePath) {
9996 this.success = success;
9997 this.pkgSetting = pkgSetting;
9998 this.changedAbiCodePath = changedAbiCodePath;
10002 /** A package to be scanned */
10003 private static class ScanRequest {
10004 /** The parsed package */
10005 @NonNull public final PackageParser.Package pkg;
10006 /** The package this package replaces */
10007 @Nullable public final PackageParser.Package oldPkg;
10008 /** Shared user settings, if the package has a shared user */
10009 @Nullable public final SharedUserSetting sharedUserSetting;
10011 * Package settings of the currently installed version.
10012 * <p><em>IMPORTANT:</em> The contents of this object may be modified
10015 @Nullable public final PackageSetting pkgSetting;
10016 /** A copy of the settings for the currently installed version */
10017 @Nullable public final PackageSetting oldPkgSetting;
10018 /** Package settings for the disabled version on the /system partition */
10019 @Nullable public final PackageSetting disabledPkgSetting;
10020 /** Package settings for the installed version under its original package name */
10021 @Nullable public final PackageSetting originalPkgSetting;
10022 /** The real package name of a renamed application */
10023 @Nullable public final String realPkgName;
10024 public final @ParseFlags int parseFlags;
10025 public final @ScanFlags int scanFlags;
10026 /** The user for which the package is being scanned */
10027 @Nullable public final UserHandle user;
10028 /** Whether or not the platform package is being scanned */
10029 public final boolean isPlatformPackage;
10030 public ScanRequest(
10031 @NonNull PackageParser.Package pkg,
10032 @Nullable SharedUserSetting sharedUserSetting,
10033 @Nullable PackageParser.Package oldPkg,
10034 @Nullable PackageSetting pkgSetting,
10035 @Nullable PackageSetting disabledPkgSetting,
10036 @Nullable PackageSetting originalPkgSetting,
10037 @Nullable String realPkgName,
10038 @ParseFlags int parseFlags,
10039 @ScanFlags int scanFlags,
10040 boolean isPlatformPackage,
10041 @Nullable UserHandle user) {
10043 this.oldPkg = oldPkg;
10044 this.pkgSetting = pkgSetting;
10045 this.sharedUserSetting = sharedUserSetting;
10046 this.oldPkgSetting = pkgSetting == null ? null : new PackageSetting(pkgSetting);
10047 this.disabledPkgSetting = disabledPkgSetting;
10048 this.originalPkgSetting = originalPkgSetting;
10049 this.realPkgName = realPkgName;
10050 this.parseFlags = parseFlags;
10051 this.scanFlags = scanFlags;
10052 this.isPlatformPackage = isPlatformPackage;
10058 * Returns the actual scan flags depending upon the state of the other settings.
10059 * <p>Updated system applications will not have the following flags set
10060 * by default and need to be adjusted after the fact:
10062 * <li>{@link #SCAN_AS_SYSTEM}</li>
10063 * <li>{@link #SCAN_AS_PRIVILEGED}</li>
10064 * <li>{@link #SCAN_AS_OEM}</li>
10065 * <li>{@link #SCAN_AS_VENDOR}</li>
10066 * <li>{@link #SCAN_AS_PRODUCT}</li>
10067 * <li>{@link #SCAN_AS_INSTANT_APP}</li>
10068 * <li>{@link #SCAN_AS_VIRTUAL_PRELOAD}</li>
10071 private @ScanFlags int adjustScanFlags(@ScanFlags int scanFlags,
10072 PackageSetting pkgSetting, PackageSetting disabledPkgSetting, UserHandle user,
10073 PackageParser.Package pkg) {
10074 if (disabledPkgSetting != null) {
10075 // updated system application, must at least have SCAN_AS_SYSTEM
10076 scanFlags |= SCAN_AS_SYSTEM;
10077 if ((disabledPkgSetting.pkgPrivateFlags
10078 & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
10079 scanFlags |= SCAN_AS_PRIVILEGED;
10081 if ((disabledPkgSetting.pkgPrivateFlags
10082 & ApplicationInfo.PRIVATE_FLAG_OEM) != 0) {
10083 scanFlags |= SCAN_AS_OEM;
10085 if ((disabledPkgSetting.pkgPrivateFlags
10086 & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0) {
10087 scanFlags |= SCAN_AS_VENDOR;
10089 if ((disabledPkgSetting.pkgPrivateFlags
10090 & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0) {
10091 scanFlags |= SCAN_AS_PRODUCT;
10094 if (pkgSetting != null) {
10095 final int userId = ((user == null) ? 0 : user.getIdentifier());
10096 if (pkgSetting.getInstantApp(userId)) {
10097 scanFlags |= SCAN_AS_INSTANT_APP;
10099 if (pkgSetting.getVirtulalPreload(userId)) {
10100 scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
10104 // Scan as privileged apps that share a user with a priv-app.
10105 final boolean skipVendorPrivilegeScan = ((scanFlags & SCAN_AS_VENDOR) != 0)
10106 && SystemProperties.getInt("ro.vndk.version", 28) < 28;
10107 if (((scanFlags & SCAN_AS_PRIVILEGED) == 0)
10108 && !pkg.isPrivileged()
10109 && (pkg.mSharedUserId != null)
10110 && !skipVendorPrivilegeScan) {
10111 SharedUserSetting sharedUserSetting = null;
10113 sharedUserSetting = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, false);
10114 } catch (PackageManagerException ignore) {}
10115 if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
10116 // Exempt SharedUsers signed with the platform key.
10117 // TODO(b/72378145) Fix this exemption. Force signature apps
10118 // to whitelist their privileged permissions just like other
10120 synchronized (mPackages) {
10121 PackageSetting platformPkgSetting = mSettings.mPackages.get("android");
10122 if ((compareSignatures(platformPkgSetting.signatures.mSigningDetails.signatures,
10123 pkg.mSigningDetails.signatures) != PackageManager.SIGNATURE_MATCH)) {
10124 scanFlags |= SCAN_AS_PRIVILEGED;
10133 // TODO: scanPackageNewLI() and scanPackageOnly() should be merged. But, first, commiting
10134 // the results / removing app data needs to be moved up a level to the callers of this
10135 // method. Also, we need to solve the problem of potentially creating a new shared user
10136 // setting. That can probably be done later and patch things up after the fact.
10137 @GuardedBy("mInstallLock")
10138 private PackageParser.Package scanPackageNewLI(@NonNull PackageParser.Package pkg,
10139 final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
10140 @Nullable UserHandle user) throws PackageManagerException {
10142 final String renamedPkgName = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
10143 final String realPkgName = getRealPackageName(pkg, renamedPkgName);
10144 if (realPkgName != null) {
10145 ensurePackageRenamed(pkg, renamedPkgName);
10147 final PackageSetting originalPkgSetting = getOriginalPackageLocked(pkg, renamedPkgName);
10148 final PackageSetting pkgSetting = mSettings.getPackageLPr(pkg.packageName);
10149 final PackageSetting disabledPkgSetting =
10150 mSettings.getDisabledSystemPkgLPr(pkg.packageName);
10152 if (mTransferedPackages.contains(pkg.packageName)) {
10153 Slog.w(TAG, "Package " + pkg.packageName
10154 + " was transferred to another, but its .apk remains");
10157 scanFlags = adjustScanFlags(scanFlags, pkgSetting, disabledPkgSetting, user, pkg);
10158 synchronized (mPackages) {
10159 applyPolicy(pkg, parseFlags, scanFlags, mPlatformPackage);
10160 assertPackageIsValid(pkg, parseFlags, scanFlags);
10162 SharedUserSetting sharedUserSetting = null;
10163 if (pkg.mSharedUserId != null) {
10164 // SIDE EFFECTS; may potentially allocate a new shared user
10165 sharedUserSetting = mSettings.getSharedUserLPw(
10166 pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
10167 if (DEBUG_PACKAGE_SCANNING) {
10168 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
10169 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId
10170 + " (uid=" + sharedUserSetting.userId + "):"
10171 + " packages=" + sharedUserSetting.packages);
10175 boolean scanSucceeded = false;
10177 final ScanRequest request = new ScanRequest(pkg, sharedUserSetting,
10178 pkgSetting == null ? null : pkgSetting.pkg, pkgSetting, disabledPkgSetting,
10179 originalPkgSetting, realPkgName, parseFlags, scanFlags,
10180 (pkg == mPlatformPackage), user);
10181 final ScanResult result = scanPackageOnlyLI(request, mFactoryTest, currentTime);
10182 if (result.success) {
10183 commitScanResultsLocked(request, result);
10185 scanSucceeded = true;
10187 if (!scanSucceeded && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
10188 // DELETE_DATA_ON_FAILURES is only used by frozen paths
10189 destroyAppDataLIF(pkg, UserHandle.USER_ALL,
10190 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
10191 destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
10199 * Commits the package scan and modifies system state.
10200 * <p><em>WARNING:</em> The method may throw an excpetion in the middle
10201 * of committing the package, leaving the system in an inconsistent state.
10202 * This needs to be fixed so, once we get to this point, no errors are
10203 * possible and the system is not left in an inconsistent state.
10205 @GuardedBy("mPackages")
10206 private void commitScanResultsLocked(@NonNull ScanRequest request, @NonNull ScanResult result)
10207 throws PackageManagerException {
10208 final PackageParser.Package pkg = request.pkg;
10209 final PackageParser.Package oldPkg = request.oldPkg;
10210 final @ParseFlags int parseFlags = request.parseFlags;
10211 final @ScanFlags int scanFlags = request.scanFlags;
10212 final PackageSetting oldPkgSetting = request.oldPkgSetting;
10213 final PackageSetting originalPkgSetting = request.originalPkgSetting;
10214 final PackageSetting disabledPkgSetting = request.disabledPkgSetting;
10215 final UserHandle user = request.user;
10216 final String realPkgName = request.realPkgName;
10217 final PackageSetting pkgSetting = result.pkgSetting;
10218 final List<String> changedAbiCodePath = result.changedAbiCodePath;
10219 final boolean newPkgSettingCreated = (result.pkgSetting != request.pkgSetting);
10221 if (newPkgSettingCreated) {
10222 if (originalPkgSetting != null) {
10223 mSettings.addRenamedPackageLPw(pkg.packageName, originalPkgSetting.name);
10225 // THROWS: when we can't allocate a user id. add call to check if there's
10226 // enough space to ensure we won't throw; otherwise, don't modify state
10227 mSettings.addUserToSettingLPw(pkgSetting);
10229 if (originalPkgSetting != null && (scanFlags & SCAN_CHECK_ONLY) == 0) {
10230 mTransferedPackages.add(originalPkgSetting.name);
10233 // TODO(toddke): Consider a method specifically for modifying the Package object
10234 // post scan; or, moving this stuff out of the Package object since it has nothing
10235 // to do with the package on disk.
10236 // We need to have this here because addUserToSettingLPw() is sometimes responsible
10237 // for creating the application ID. If we did this earlier, we would be saving the
10239 pkg.applicationInfo.uid = pkgSetting.appId;
10241 mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
10243 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realPkgName != null) {
10244 mTransferedPackages.add(pkg.packageName);
10247 // THROWS: when requested libraries that can't be found. it only changes
10248 // the state of the passed in pkg object, so, move to the top of the method
10249 // and allow it to abort
10250 if ((scanFlags & SCAN_BOOTING) == 0
10251 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10252 // Check all shared libraries and map to their actual file path.
10253 // We only do this here for apps not on a system dir, because those
10254 // are the only ones that can fail an install due to this. We
10255 // will take care of the system apps by updating all of their
10256 // library paths after the scan is done. Also during the initial
10257 // scan don't update any libs as we do this wholesale after all
10258 // apps are scanned to avoid dependency based scanning.
10259 updateSharedLibrariesLPr(pkg, null);
10262 // All versions of a static shared library are referenced with the same
10263 // package name. Internally, we use a synthetic package name to allow
10264 // multiple versions of the same shared library to be installed. So,
10265 // we need to generate the synthetic package name of the latest shared
10266 // library in order to compare signatures.
10267 PackageSetting signatureCheckPs = pkgSetting;
10268 if (pkg.applicationInfo.isStaticSharedLibrary()) {
10269 SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
10270 if (libraryEntry != null) {
10271 signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
10275 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
10276 if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
10277 if (ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) {
10278 // We just determined the app is signed correctly, so bring
10279 // over the latest parsed certs.
10280 pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails;
10282 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10283 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
10284 "Package " + pkg.packageName + " upgrade keys do not match the "
10285 + "previously installed version");
10287 pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails;
10288 String msg = "System package " + pkg.packageName
10289 + " signature changed; retaining data.";
10290 reportSettingsProblem(Log.WARN, msg);
10295 final boolean compareCompat = isCompatSignatureUpdateNeeded(pkg);
10296 final boolean compareRecover = isRecoverSignatureUpdateNeeded(pkg);
10297 final boolean compatMatch = verifySignatures(signatureCheckPs, disabledPkgSetting,
10298 pkg.mSigningDetails, compareCompat, compareRecover);
10299 // The new KeySets will be re-added later in the scanning process.
10301 synchronized (mPackages) {
10302 ksms.removeAppKeySetDataLPw(pkg.packageName);
10305 // We just determined the app is signed correctly, so bring
10306 // over the latest parsed certs.
10307 pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails;
10310 // if this is is a sharedUser, check to see if the new package is signed by a newer
10311 // signing certificate than the existing one, and if so, copy over the new details
10312 if (signatureCheckPs.sharedUser != null) {
10313 if (pkg.mSigningDetails.hasAncestor(
10314 signatureCheckPs.sharedUser.signatures.mSigningDetails)) {
10315 signatureCheckPs.sharedUser.signatures.mSigningDetails = pkg.mSigningDetails;
10317 if (signatureCheckPs.sharedUser.signaturesChanged == null) {
10318 signatureCheckPs.sharedUser.signaturesChanged = Boolean.FALSE;
10321 } catch (PackageManagerException e) {
10322 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10325 // The signature has changed, but this package is in the system
10326 // image... let's recover!
10327 pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails;
10329 // If the system app is part of a shared user we allow that shared user to change
10330 // signatures as well as part of an OTA. We still need to verify that the signatures
10331 // are consistent within the shared user for a given boot, so only allow updating
10332 // the signatures on the first package scanned for the shared user (i.e. if the
10333 // signaturesChanged state hasn't been initialized yet in SharedUserSetting).
10334 if (signatureCheckPs.sharedUser != null) {
10335 if (signatureCheckPs.sharedUser.signaturesChanged != null &&
10337 signatureCheckPs.sharedUser.signatures.mSigningDetails.signatures,
10338 pkg.mSigningDetails.signatures) != PackageManager.SIGNATURE_MATCH) {
10339 throw new PackageManagerException(
10340 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
10341 "Signature mismatch for shared user: " + pkgSetting.sharedUser);
10344 signatureCheckPs.sharedUser.signatures.mSigningDetails = pkg.mSigningDetails;
10345 signatureCheckPs.sharedUser.signaturesChanged = Boolean.TRUE;
10347 // File a report about this.
10348 String msg = "System package " + pkg.packageName
10349 + " signature changed; retaining data.";
10350 reportSettingsProblem(Log.WARN, msg);
10351 } catch (IllegalArgumentException e) {
10353 // should never happen: certs matched when checking, but not when comparing
10354 // old to new for sharedUser
10355 throw new PackageManagerException(INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
10356 "Signing certificates comparison made on incomparable signing details"
10357 + " but somehow passed verifySignatures!");
10361 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
10362 // This package wants to adopt ownership of permissions from
10363 // another package.
10364 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
10365 final String origName = pkg.mAdoptPermissions.get(i);
10366 final PackageSetting orig = mSettings.getPackageLPr(origName);
10367 if (orig != null) {
10368 if (verifyPackageUpdateLPr(orig, pkg)) {
10369 Slog.i(TAG, "Adopting permissions from " + origName + " to "
10370 + pkg.packageName);
10371 mSettings.mPermissions.transferPermissions(origName, pkg.packageName);
10377 if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
10378 for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
10379 final String codePathString = changedAbiCodePath.get(i);
10381 mInstaller.rmdex(codePathString,
10382 getDexCodeInstructionSet(getPreferredInstructionSet()));
10383 } catch (InstallerException ignored) {
10388 if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10389 if (oldPkgSetting != null) {
10390 synchronized (mPackages) {
10391 mSettings.mPackages.put(oldPkgSetting.name, oldPkgSetting);
10395 final int userId = user == null ? 0 : user.getIdentifier();
10396 // Modify state for the given package setting
10397 commitPackageSettings(pkg, oldPkg, pkgSetting, user, scanFlags,
10398 (parseFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
10399 if (pkgSetting.getInstantApp(userId)) {
10400 mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
10406 * Returns the "real" name of the package.
10407 * <p>This may differ from the package's actual name if the application has already
10408 * been installed under one of this package's original names.
10410 private static @Nullable String getRealPackageName(@NonNull PackageParser.Package pkg,
10411 @Nullable String renamedPkgName) {
10412 if (isPackageRenamed(pkg, renamedPkgName)) {
10413 return pkg.mRealPackage;
10418 /** Returns {@code true} if the package has been renamed. Otherwise, {@code false}. */
10419 private static boolean isPackageRenamed(@NonNull PackageParser.Package pkg,
10420 @Nullable String renamedPkgName) {
10421 return pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(renamedPkgName);
10425 * Returns the original package setting.
10426 * <p>A package can migrate its name during an update. In this scenario, a package
10427 * designates a set of names that it considers as one of its original names.
10428 * <p>An original package must be signed identically and it must have the same
10429 * shared user [if any].
10431 @GuardedBy("mPackages")
10432 private @Nullable PackageSetting getOriginalPackageLocked(@NonNull PackageParser.Package pkg,
10433 @Nullable String renamedPkgName) {
10434 if (!isPackageRenamed(pkg, renamedPkgName)) {
10437 for (int i = pkg.mOriginalPackages.size() - 1; i >= 0; --i) {
10438 final PackageSetting originalPs =
10439 mSettings.getPackageLPr(pkg.mOriginalPackages.get(i));
10440 if (originalPs != null) {
10441 // the package is already installed under its original name...
10442 // but, should we use it?
10443 if (!verifyPackageUpdateLPr(originalPs, pkg)) {
10444 // the new package is incompatible with the original
10446 } else if (originalPs.sharedUser != null) {
10447 if (!originalPs.sharedUser.name.equals(pkg.mSharedUserId)) {
10448 // the shared user id is incompatible with the original
10449 Slog.w(TAG, "Unable to migrate data from " + originalPs.name
10450 + " to " + pkg.packageName + ": old uid "
10451 + originalPs.sharedUser.name
10452 + " differs from " + pkg.mSharedUserId);
10455 // TODO: Add case when shared user id is added [b/28144775]
10457 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
10458 + pkg.packageName + " to old name " + originalPs.name);
10467 * Renames the package if it was installed under a different name.
10468 * <p>When we've already installed the package under an original name, update
10469 * the new package so we can continue to have the old name.
10471 private static void ensurePackageRenamed(@NonNull PackageParser.Package pkg,
10472 @NonNull String renamedPackageName) {
10473 if (pkg.mOriginalPackages == null
10474 || !pkg.mOriginalPackages.contains(renamedPackageName)
10475 || pkg.packageName.equals(renamedPackageName)) {
10478 pkg.setPackageName(renamedPackageName);
10482 * Just scans the package without any side effects.
10483 * <p>Not entirely true at the moment. There is still one side effect -- this
10484 * method potentially modifies a live {@link PackageSetting} object representing
10485 * the package being scanned. This will be resolved in the future.
10487 * @param request Information about the package to be scanned
10488 * @param isUnderFactoryTest Whether or not the device is under factory test
10489 * @param currentTime The current time, in millis
10490 * @return The results of the scan
10492 @GuardedBy("mInstallLock")
10493 private static @NonNull ScanResult scanPackageOnlyLI(@NonNull ScanRequest request,
10494 boolean isUnderFactoryTest, long currentTime)
10495 throws PackageManagerException {
10496 final PackageParser.Package pkg = request.pkg;
10497 PackageSetting pkgSetting = request.pkgSetting;
10498 final PackageSetting disabledPkgSetting = request.disabledPkgSetting;
10499 final PackageSetting originalPkgSetting = request.originalPkgSetting;
10500 final @ParseFlags int parseFlags = request.parseFlags;
10501 final @ScanFlags int scanFlags = request.scanFlags;
10502 final String realPkgName = request.realPkgName;
10503 final SharedUserSetting sharedUserSetting = request.sharedUserSetting;
10504 final UserHandle user = request.user;
10505 final boolean isPlatformPackage = request.isPlatformPackage;
10507 List<String> changedAbiCodePath = null;
10509 if (DEBUG_PACKAGE_SCANNING) {
10510 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
10511 Log.d(TAG, "Scanning package " + pkg.packageName);
10514 DexManager.maybeLogUnexpectedPackageDetails(pkg);
10516 // Initialize package source and resource directories
10517 final File scanFile = new File(pkg.codePath);
10518 final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
10519 final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
10521 // We keep references to the derived CPU Abis from settings in oder to reuse
10522 // them in the case where we're not upgrading or booting for the first time.
10523 String primaryCpuAbiFromSettings = null;
10524 String secondaryCpuAbiFromSettings = null;
10525 boolean needToDeriveAbi = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0;
10527 if (!needToDeriveAbi) {
10528 if (pkgSetting != null) {
10529 primaryCpuAbiFromSettings = pkgSetting.primaryCpuAbiString;
10530 secondaryCpuAbiFromSettings = pkgSetting.secondaryCpuAbiString;
10532 // Re-scanning a system package after uninstalling updates; need to derive ABI
10533 needToDeriveAbi = true;
10537 if (pkgSetting != null && pkgSetting.sharedUser != sharedUserSetting) {
10538 PackageManagerService.reportSettingsProblem(Log.WARN,
10539 "Package " + pkg.packageName + " shared user changed from "
10540 + (pkgSetting.sharedUser != null
10541 ? pkgSetting.sharedUser.name : "<nothing>")
10543 + (sharedUserSetting != null ? sharedUserSetting.name : "<nothing>")
10544 + "; replacing with new");
10548 String[] usesStaticLibraries = null;
10549 if (pkg.usesStaticLibraries != null) {
10550 usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
10551 pkg.usesStaticLibraries.toArray(usesStaticLibraries);
10553 final boolean createNewPackage = (pkgSetting == null);
10554 if (createNewPackage) {
10555 final String parentPackageName = (pkg.parentPackage != null)
10556 ? pkg.parentPackage.packageName : null;
10557 final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
10558 final boolean virtualPreload = (scanFlags & SCAN_AS_VIRTUAL_PRELOAD) != 0;
10559 // REMOVE SharedUserSetting from method; update in a separate call
10560 pkgSetting = Settings.createNewSetting(pkg.packageName, originalPkgSetting,
10561 disabledPkgSetting, realPkgName, sharedUserSetting, destCodeFile,
10562 destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
10563 pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi,
10564 pkg.mVersionCode, pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
10565 user, true /*allowInstall*/, instantApp, virtualPreload,
10566 parentPackageName, pkg.getChildPackageNames(),
10567 UserManagerService.getInstance(), usesStaticLibraries,
10568 pkg.usesStaticLibrariesVersions);
10570 // REMOVE SharedUserSetting from method; update in a separate call.
10572 // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
10573 // secondaryCpuAbi are not known at this point so we always update them
10574 // to null here, only to reset them at a later point.
10575 Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, sharedUserSetting,
10576 destCodeFile, destResourceFile, pkg.applicationInfo.nativeLibraryDir,
10577 pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi,
10578 pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
10579 pkg.getChildPackageNames(), UserManagerService.getInstance(),
10580 usesStaticLibraries, pkg.usesStaticLibrariesVersions);
10582 if (createNewPackage && originalPkgSetting != null) {
10583 // This is the initial transition from the original package, so,
10584 // fix up the new package's name now. We must do this after looking
10585 // up the package under its new name, so getPackageLP takes care of
10586 // fiddling things correctly.
10587 pkg.setPackageName(originalPkgSetting.name);
10589 // File a report about this.
10590 String msg = "New package " + pkgSetting.realName
10591 + " renamed to replace old package " + pkgSetting.name;
10592 reportSettingsProblem(Log.WARN, msg);
10595 final int userId = (user == null ? UserHandle.USER_SYSTEM : user.getIdentifier());
10596 // for existing packages, change the install state; but, only if it's explicitly specified
10597 if (!createNewPackage) {
10598 final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
10599 final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
10600 setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
10603 if (disabledPkgSetting != null) {
10604 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
10607 // Apps which share a sharedUserId must be placed in the same selinux domain. If this
10608 // package is the first app installed as this shared user, set seInfoTargetSdkVersion to its
10609 // targetSdkVersion. These are later adjusted in PackageManagerService's constructor to be
10610 // the lowest targetSdkVersion of all apps within the shared user, which corresponds to the
10611 // least restrictive selinux domain.
10612 // NOTE: As new packages are installed / updated, the shared user's seinfoTargetSdkVersion
10613 // will NOT be modified until next boot, even if a lower targetSdkVersion is used. This
10614 // ensures that all packages continue to run in the same selinux domain.
10615 final int targetSdkVersion =
10616 ((sharedUserSetting != null) && (sharedUserSetting.packages.size() != 0)) ?
10617 sharedUserSetting.seInfoTargetSdkVersion : pkg.applicationInfo.targetSdkVersion;
10618 // TODO(b/71593002): isPrivileged for sharedUser and appInfo should never be out of sync.
10619 // They currently can be if the sharedUser apps are signed with the platform key.
10620 final boolean isPrivileged = (sharedUserSetting != null) ?
10621 sharedUserSetting.isPrivileged() | pkg.isPrivileged() : pkg.isPrivileged();
10623 pkg.applicationInfo.seInfo = SELinuxMMAC.getSeInfo(pkg, isPrivileged,
10624 pkg.applicationInfo.targetSandboxVersion, targetSdkVersion);
10625 pkg.applicationInfo.seInfoUser = SELinuxUtil.assignSeinfoUser(pkgSetting.readUserState(
10626 userId == UserHandle.USER_ALL ? UserHandle.USER_SYSTEM : userId));
10628 pkg.mExtras = pkgSetting;
10629 pkg.applicationInfo.processName = fixProcessName(
10630 pkg.applicationInfo.packageName,
10631 pkg.applicationInfo.processName);
10633 if (!isPlatformPackage) {
10634 // Get all of our default paths setup
10635 pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
10638 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
10640 if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
10641 if (needToDeriveAbi) {
10642 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
10643 final boolean extractNativeLibs = !pkg.isLibrary();
10644 derivePackageAbi(pkg, cpuAbiOverride, extractNativeLibs);
10645 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10647 // Some system apps still use directory structure for native libraries
10648 // in which case we might end up not detecting abi solely based on apk
10649 // structure. Try to detect abi based on directory structure.
10650 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
10651 pkg.applicationInfo.primaryCpuAbi == null) {
10652 setBundledAppAbisAndRoots(pkg, pkgSetting);
10653 setNativeLibraryPaths(pkg, sAppLib32InstallDir);
10656 // This is not a first boot or an upgrade, don't bother deriving the
10657 // ABI during the scan. Instead, trust the value that was stored in the
10658 // package setting.
10659 pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
10660 pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
10662 setNativeLibraryPaths(pkg, sAppLib32InstallDir);
10664 if (DEBUG_ABI_SELECTION) {
10665 Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
10666 pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
10667 pkg.applicationInfo.secondaryCpuAbi);
10671 if ((scanFlags & SCAN_MOVE) != 0) {
10672 // We haven't run dex-opt for this move (since we've moved the compiled output too)
10673 // but we already have this packages package info in the PackageSetting. We just
10674 // use that and derive the native library path based on the new codepath.
10675 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
10676 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
10679 // Set native library paths again. For moves, the path will be updated based on the
10680 // ABIs we've determined above. For non-moves, the path will be updated based on the
10681 // ABIs we determined during compilation, but the path will depend on the final
10682 // package path (after the rename away from the stage path).
10683 setNativeLibraryPaths(pkg, sAppLib32InstallDir);
10686 // This is a special case for the "system" package, where the ABI is
10687 // dictated by the zygote configuration (and init.rc). We should keep track
10688 // of this ABI so that we can deal with "normal" applications that run under
10689 // the same UID correctly.
10690 if (isPlatformPackage) {
10691 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
10692 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
10695 // If there's a mismatch between the abi-override in the package setting
10696 // and the abiOverride specified for the install. Warn about this because we
10697 // would've already compiled the app without taking the package setting into
10699 if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
10700 if (cpuAbiOverride == null && pkg.packageName != null) {
10701 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
10702 " for package " + pkg.packageName);
10706 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
10707 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
10708 pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
10710 // Copy the derived override back to the parsed package, so that we can
10711 // update the package settings accordingly.
10712 pkg.cpuAbiOverride = cpuAbiOverride;
10714 if (DEBUG_ABI_SELECTION) {
10715 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.packageName
10716 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
10717 + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
10720 // Push the derived path down into PackageSettings so we know what to
10721 // clean up at uninstall time.
10722 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
10724 if (DEBUG_ABI_SELECTION) {
10725 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
10726 " primary=" + pkg.applicationInfo.primaryCpuAbi +
10727 " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
10730 if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
10731 // We don't do this here during boot because we can do it all
10732 // at once after scanning all existing packages.
10734 // We also do this *before* we perform dexopt on this package, so that
10735 // we can avoid redundant dexopts, and also to make sure we've got the
10736 // code and package path correct.
10737 changedAbiCodePath =
10738 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
10741 if (isUnderFactoryTest && pkg.requestedPermissions.contains(
10742 android.Manifest.permission.FACTORY_TEST)) {
10743 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
10746 if (isSystemApp(pkg)) {
10747 pkgSetting.isOrphaned = true;
10750 // Take care of first install / last update times.
10751 final long scanFileTime = getLastModifiedTime(pkg);
10752 if (currentTime != 0) {
10753 if (pkgSetting.firstInstallTime == 0) {
10754 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
10755 } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
10756 pkgSetting.lastUpdateTime = currentTime;
10758 } else if (pkgSetting.firstInstallTime == 0) {
10759 // We need *something*. Take time time stamp of the file.
10760 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
10761 } else if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
10762 if (scanFileTime != pkgSetting.timeStamp) {
10763 // A package on the system image has changed; consider this
10764 // to be an update.
10765 pkgSetting.lastUpdateTime = scanFileTime;
10768 pkgSetting.setTimeStamp(scanFileTime);
10770 pkgSetting.pkg = pkg;
10771 pkgSetting.pkgFlags = pkg.applicationInfo.flags;
10772 if (pkg.getLongVersionCode() != pkgSetting.versionCode) {
10773 pkgSetting.versionCode = pkg.getLongVersionCode();
10775 // Update volume if needed
10776 final String volumeUuid = pkg.applicationInfo.volumeUuid;
10777 if (!Objects.equals(volumeUuid, pkgSetting.volumeUuid)) {
10778 Slog.i(PackageManagerService.TAG,
10779 "Update" + (pkgSetting.isSystem() ? " system" : "")
10780 + " package " + pkg.packageName
10781 + " volume from " + pkgSetting.volumeUuid
10782 + " to " + volumeUuid);
10783 pkgSetting.volumeUuid = volumeUuid;
10786 return new ScanResult(true, pkgSetting, changedAbiCodePath);
10790 * Returns {@code true} if the given file contains code. Otherwise {@code false}.
10792 private static boolean apkHasCode(String fileName) {
10793 StrictJarFile jarFile = null;
10795 jarFile = new StrictJarFile(fileName,
10796 false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
10797 return jarFile.findEntry("classes.dex") != null;
10798 } catch (IOException ignore) {
10801 if (jarFile != null) {
10804 } catch (IOException ignore) {}
10810 * Enforces code policy for the package. This ensures that if an APK has
10811 * declared hasCode="true" in its manifest that the APK actually contains
10814 * @throws PackageManagerException If bytecode could not be found when it should exist
10816 private static void assertCodePolicy(PackageParser.Package pkg)
10817 throws PackageManagerException {
10818 final boolean shouldHaveCode =
10819 (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
10820 if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
10821 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10822 "Package " + pkg.baseCodePath + " code is missing");
10825 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
10826 for (int i = 0; i < pkg.splitCodePaths.length; i++) {
10827 final boolean splitShouldHaveCode =
10828 (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
10829 if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
10830 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10831 "Package " + pkg.splitCodePaths[i] + " code is missing");
10838 * Applies policy to the parsed package based upon the given policy flags.
10839 * Ensures the package is in a good state.
10841 * Implementation detail: This method must NOT have any side effect. It would
10842 * ideally be static, but, it requires locks to read system state.
10844 private static void applyPolicy(PackageParser.Package pkg, final @ParseFlags int parseFlags,
10845 final @ScanFlags int scanFlags, PackageParser.Package platformPkg) {
10846 if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
10847 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
10848 if (pkg.applicationInfo.isDirectBootAware()) {
10849 // we're direct boot aware; set for all components
10850 for (PackageParser.Service s : pkg.services) {
10851 s.info.encryptionAware = s.info.directBootAware = true;
10853 for (PackageParser.Provider p : pkg.providers) {
10854 p.info.encryptionAware = p.info.directBootAware = true;
10856 for (PackageParser.Activity a : pkg.activities) {
10857 a.info.encryptionAware = a.info.directBootAware = true;
10859 for (PackageParser.Activity r : pkg.receivers) {
10860 r.info.encryptionAware = r.info.directBootAware = true;
10863 if (compressedFileExists(pkg.codePath)) {
10867 // non system apps can't be flagged as core
10868 pkg.coreApp = false;
10869 // clear flags not applicable to regular apps
10870 pkg.applicationInfo.flags &=
10871 ~ApplicationInfo.FLAG_PERSISTENT;
10872 pkg.applicationInfo.privateFlags &=
10873 ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
10874 pkg.applicationInfo.privateFlags &=
10875 ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
10876 // cap permission priorities
10877 if (pkg.permissionGroups != null && pkg.permissionGroups.size() > 0) {
10878 for (int i = pkg.permissionGroups.size() - 1; i >= 0; --i) {
10879 pkg.permissionGroups.get(i).info.priority = 0;
10883 if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) {
10884 // clear protected broadcasts
10885 pkg.protectedBroadcasts = null;
10886 // ignore export request for single user receivers
10887 if (pkg.receivers != null) {
10888 for (int i = pkg.receivers.size() - 1; i >= 0; --i) {
10889 final PackageParser.Activity receiver = pkg.receivers.get(i);
10890 if ((receiver.info.flags & ActivityInfo.FLAG_SINGLE_USER) != 0) {
10891 receiver.info.exported = false;
10895 // ignore export request for single user services
10896 if (pkg.services != null) {
10897 for (int i = pkg.services.size() - 1; i >= 0; --i) {
10898 final PackageParser.Service service = pkg.services.get(i);
10899 if ((service.info.flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
10900 service.info.exported = false;
10904 // ignore export request for single user providers
10905 if (pkg.providers != null) {
10906 for (int i = pkg.providers.size() - 1; i >= 0; --i) {
10907 final PackageParser.Provider provider = pkg.providers.get(i);
10908 if ((provider.info.flags & ProviderInfo.FLAG_SINGLE_USER) != 0) {
10909 provider.info.exported = false;
10915 if ((scanFlags & SCAN_AS_PRIVILEGED) != 0) {
10916 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
10919 if ((scanFlags & SCAN_AS_OEM) != 0) {
10920 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_OEM;
10923 if ((scanFlags & SCAN_AS_VENDOR) != 0) {
10924 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_VENDOR;
10927 if ((scanFlags & SCAN_AS_PRODUCT) != 0) {
10928 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRODUCT;
10931 // Check if the package is signed with the same key as the platform package.
10932 if (PLATFORM_PACKAGE_NAME.equals(pkg.packageName) ||
10933 (platformPkg != null && compareSignatures(
10934 platformPkg.mSigningDetails.signatures,
10935 pkg.mSigningDetails.signatures) == PackageManager.SIGNATURE_MATCH)) {
10936 pkg.applicationInfo.privateFlags |=
10937 ApplicationInfo.PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY;
10940 if (!isSystemApp(pkg)) {
10941 // Only system apps can use these features.
10942 pkg.mOriginalPackages = null;
10943 pkg.mRealPackage = null;
10944 pkg.mAdoptPermissions = null;
10948 private static @NonNull <T> T assertNotNull(@Nullable T object, String message)
10949 throws PackageManagerException {
10950 if (object == null) {
10951 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, message);
10957 * Asserts the parsed package is valid according to the given policy. If the
10958 * package is invalid, for whatever reason, throws {@link PackageManagerException}.
10960 * Implementation detail: This method must NOT have any side effects. It would
10961 * ideally be static, but, it requires locks to read system state.
10963 * @throws PackageManagerException If the package fails any of the validation checks
10965 private void assertPackageIsValid(PackageParser.Package pkg, final @ParseFlags int parseFlags,
10966 final @ScanFlags int scanFlags)
10967 throws PackageManagerException {
10968 if ((parseFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
10969 assertCodePolicy(pkg);
10972 if (pkg.applicationInfo.getCodePath() == null ||
10973 pkg.applicationInfo.getResourcePath() == null) {
10974 // Bail out. The resource and code paths haven't been set.
10975 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10976 "Code and resource paths haven't been set correctly");
10979 // Make sure we're not adding any bogus keyset info
10980 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
10981 ksms.assertScannedPackageValid(pkg);
10983 synchronized (mPackages) {
10984 // The special "android" package can only be defined once
10985 if (pkg.packageName.equals("android")) {
10986 if (mAndroidApplication != null) {
10987 Slog.w(TAG, "*************************************************");
10988 Slog.w(TAG, "Core android package being redefined. Skipping.");
10989 Slog.w(TAG, " codePath=" + pkg.codePath);
10990 Slog.w(TAG, "*************************************************");
10991 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
10992 "Core android package being redefined. Skipping.");
10996 // A package name must be unique; don't allow duplicates
10997 if (mPackages.containsKey(pkg.packageName)) {
10998 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
10999 "Application package " + pkg.packageName
11000 + " already installed. Skipping duplicate.");
11003 if (pkg.applicationInfo.isStaticSharedLibrary()) {
11004 // Static libs have a synthetic package name containing the version
11005 // but we still want the base name to be unique.
11006 if (mPackages.containsKey(pkg.manifestPackageName)) {
11007 throw new PackageManagerException(
11008 "Duplicate static shared lib provider package");
11011 // Static shared libraries should have at least O target SDK
11012 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
11013 throw new PackageManagerException(
11014 "Packages declaring static-shared libs must target O SDK or higher");
11017 // Package declaring static a shared lib cannot be instant apps
11018 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11019 throw new PackageManagerException(
11020 "Packages declaring static-shared libs cannot be instant apps");
11023 // Package declaring static a shared lib cannot be renamed since the package
11024 // name is synthetic and apps can't code around package manager internals.
11025 if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) {
11026 throw new PackageManagerException(
11027 "Packages declaring static-shared libs cannot be renamed");
11030 // Package declaring static a shared lib cannot declare child packages
11031 if (!ArrayUtils.isEmpty(pkg.childPackages)) {
11032 throw new PackageManagerException(
11033 "Packages declaring static-shared libs cannot have child packages");
11036 // Package declaring static a shared lib cannot declare dynamic libs
11037 if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
11038 throw new PackageManagerException(
11039 "Packages declaring static-shared libs cannot declare dynamic libs");
11042 // Package declaring static a shared lib cannot declare shared users
11043 if (pkg.mSharedUserId != null) {
11044 throw new PackageManagerException(
11045 "Packages declaring static-shared libs cannot declare shared users");
11048 // Static shared libs cannot declare activities
11049 if (!pkg.activities.isEmpty()) {
11050 throw new PackageManagerException(
11051 "Static shared libs cannot declare activities");
11054 // Static shared libs cannot declare services
11055 if (!pkg.services.isEmpty()) {
11056 throw new PackageManagerException(
11057 "Static shared libs cannot declare services");
11060 // Static shared libs cannot declare providers
11061 if (!pkg.providers.isEmpty()) {
11062 throw new PackageManagerException(
11063 "Static shared libs cannot declare content providers");
11066 // Static shared libs cannot declare receivers
11067 if (!pkg.receivers.isEmpty()) {
11068 throw new PackageManagerException(
11069 "Static shared libs cannot declare broadcast receivers");
11072 // Static shared libs cannot declare permission groups
11073 if (!pkg.permissionGroups.isEmpty()) {
11074 throw new PackageManagerException(
11075 "Static shared libs cannot declare permission groups");
11078 // Static shared libs cannot declare permissions
11079 if (!pkg.permissions.isEmpty()) {
11080 throw new PackageManagerException(
11081 "Static shared libs cannot declare permissions");
11084 // Static shared libs cannot declare protected broadcasts
11085 if (pkg.protectedBroadcasts != null) {
11086 throw new PackageManagerException(
11087 "Static shared libs cannot declare protected broadcasts");
11090 // Static shared libs cannot be overlay targets
11091 if (pkg.mOverlayTarget != null) {
11092 throw new PackageManagerException(
11093 "Static shared libs cannot be overlay targets");
11096 // The version codes must be ordered as lib versions
11097 long minVersionCode = Long.MIN_VALUE;
11098 long maxVersionCode = Long.MAX_VALUE;
11100 LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
11101 pkg.staticSharedLibName);
11102 if (versionedLib != null) {
11103 final int versionCount = versionedLib.size();
11104 for (int i = 0; i < versionCount; i++) {
11105 SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
11106 final long libVersionCode = libInfo.getDeclaringPackage()
11107 .getLongVersionCode();
11108 if (libInfo.getLongVersion() < pkg.staticSharedLibVersion) {
11109 minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
11110 } else if (libInfo.getLongVersion() > pkg.staticSharedLibVersion) {
11111 maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
11113 minVersionCode = maxVersionCode = libVersionCode;
11118 if (pkg.getLongVersionCode() < minVersionCode
11119 || pkg.getLongVersionCode() > maxVersionCode) {
11120 throw new PackageManagerException("Static shared"
11121 + " lib version codes must be ordered as lib versions");
11125 // Only privileged apps and updated privileged apps can add child packages.
11126 if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
11127 if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) {
11128 throw new PackageManagerException("Only privileged apps can add child "
11129 + "packages. Ignoring package " + pkg.packageName);
11131 final int childCount = pkg.childPackages.size();
11132 for (int i = 0; i < childCount; i++) {
11133 PackageParser.Package childPkg = pkg.childPackages.get(i);
11134 if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
11135 childPkg.packageName)) {
11136 throw new PackageManagerException("Can't override child of "
11137 + "another disabled app. Ignoring package " + pkg.packageName);
11142 // If we're only installing presumed-existing packages, require that the
11143 // scanned APK is both already known and at the path previously established
11144 // for it. Previously unknown packages we pick up normally, but if we have an
11145 // a priori expectation about this package's install presence, enforce it.
11146 // With a singular exception for new system packages. When an OTA contains
11147 // a new system package, we allow the codepath to change from a system location
11148 // to the user-installed location. If we don't allow this change, any newer,
11149 // user-installed version of the application will be ignored.
11150 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
11151 if (mExpectingBetter.containsKey(pkg.packageName)) {
11152 logCriticalInfo(Log.WARN,
11153 "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
11155 PackageSetting known = mSettings.getPackageLPr(pkg.packageName);
11156 if (known != null) {
11157 if (DEBUG_PACKAGE_SCANNING) {
11158 Log.d(TAG, "Examining " + pkg.codePath
11159 + " and requiring known paths " + known.codePathString
11160 + " & " + known.resourcePathString);
11162 if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
11163 || !pkg.applicationInfo.getResourcePath().equals(
11164 known.resourcePathString)) {
11165 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
11166 "Application package " + pkg.packageName
11167 + " found at " + pkg.applicationInfo.getCodePath()
11168 + " but expected at " + known.codePathString
11172 throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
11173 "Application package " + pkg.packageName
11174 + " not found; ignoring.");
11179 // Verify that this new package doesn't have any content providers
11180 // that conflict with existing packages. Only do this if the
11181 // package isn't already installed, since we don't want to break
11182 // things that are installed.
11183 if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
11184 final int N = pkg.providers.size();
11186 for (i=0; i<N; i++) {
11187 PackageParser.Provider p = pkg.providers.get(i);
11188 if (p.info.authority != null) {
11189 String names[] = p.info.authority.split(";");
11190 for (int j = 0; j < names.length; j++) {
11191 if (mProvidersByAuthority.containsKey(names[j])) {
11192 PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
11193 final String otherPackageName =
11194 ((other != null && other.getComponentName() != null) ?
11195 other.getComponentName().getPackageName() : "?");
11196 throw new PackageManagerException(
11197 INSTALL_FAILED_CONFLICTING_PROVIDER,
11198 "Can't install because provider name " + names[j]
11199 + " (in package " + pkg.applicationInfo.packageName
11200 + ") is already used by " + otherPackageName);
11207 // Verify that packages sharing a user with a privileged app are marked as privileged.
11208 if (!pkg.isPrivileged() && (pkg.mSharedUserId != null)) {
11209 SharedUserSetting sharedUserSetting = null;
11211 sharedUserSetting = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, false);
11212 } catch (PackageManagerException ignore) {}
11213 if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
11214 // Exempt SharedUsers signed with the platform key.
11215 PackageSetting platformPkgSetting = mSettings.mPackages.get("android");
11216 if ((platformPkgSetting.signatures.mSigningDetails
11217 != PackageParser.SigningDetails.UNKNOWN)
11218 && (compareSignatures(
11219 platformPkgSetting.signatures.mSigningDetails.signatures,
11220 pkg.mSigningDetails.signatures)
11221 != PackageManager.SIGNATURE_MATCH)) {
11222 throw new PackageManagerException("Apps that share a user with a " +
11223 "privileged app must themselves be marked as privileged. " +
11224 pkg.packageName + " shares privileged user " +
11225 pkg.mSharedUserId + ".");
11230 // Apply policies specific for runtime resource overlays (RROs).
11231 if (pkg.mOverlayTarget != null) {
11232 // System overlays have some restrictions on their use of the 'static' state.
11233 if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
11234 // We are scanning a system overlay. This can be the first scan of the
11235 // system/vendor/oem partition, or an update to the system overlay.
11236 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
11237 // This must be an update to a system overlay.
11238 final PackageSetting previousPkg = assertNotNull(
11239 mSettings.getPackageLPr(pkg.packageName),
11240 "previous package state not present");
11242 // previousPkg.pkg may be null: the package will be not be scanned if the
11243 // package manager knows there is a newer version on /data.
11244 // TODO[b/79435695]: Find a better way to keep track of the "static"
11245 // property for RROs instead of having to parse packages on /system
11246 PackageParser.Package ppkg = previousPkg.pkg;
11247 if (ppkg == null) {
11249 final PackageParser pp = new PackageParser();
11250 ppkg = pp.parsePackage(previousPkg.codePath,
11251 parseFlags | PackageParser.PARSE_IS_SYSTEM_DIR);
11252 } catch (PackageParserException e) {
11253 Slog.w(TAG, "failed to parse " + previousPkg.codePath, e);
11257 // Static overlays cannot be updated.
11258 if (ppkg != null && ppkg.mOverlayIsStatic) {
11259 throw new PackageManagerException("Overlay " + pkg.packageName +
11260 " is static and cannot be upgraded.");
11261 // Non-static overlays cannot be converted to static overlays.
11262 } else if (pkg.mOverlayIsStatic) {
11263 throw new PackageManagerException("Overlay " + pkg.packageName +
11264 " cannot be upgraded into a static overlay.");
11268 // The overlay is a non-system overlay. Non-system overlays cannot be static.
11269 if (pkg.mOverlayIsStatic) {
11270 throw new PackageManagerException("Overlay " + pkg.packageName +
11271 " is static but not pre-installed.");
11274 // The only case where we allow installation of a non-system overlay is when
11275 // its signature is signed with the platform certificate.
11276 PackageSetting platformPkgSetting = mSettings.getPackageLPr("android");
11277 if ((platformPkgSetting.signatures.mSigningDetails
11278 != PackageParser.SigningDetails.UNKNOWN)
11279 && (compareSignatures(
11280 platformPkgSetting.signatures.mSigningDetails.signatures,
11281 pkg.mSigningDetails.signatures)
11282 != PackageManager.SIGNATURE_MATCH)) {
11283 throw new PackageManagerException("Overlay " + pkg.packageName +
11284 " must be signed with the platform certificate.");
11291 private boolean addSharedLibraryLPw(String path, String apk, String name, long version,
11292 int type, String declaringPackageName, long declaringVersionCode) {
11293 LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
11294 if (versionedLib == null) {
11295 versionedLib = new LongSparseArray<>();
11296 mSharedLibraries.put(name, versionedLib);
11297 if (type == SharedLibraryInfo.TYPE_STATIC) {
11298 mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
11300 } else if (versionedLib.indexOfKey(version) >= 0) {
11303 SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name,
11304 version, type, declaringPackageName, declaringVersionCode);
11305 versionedLib.put(version, libEntry);
11309 private boolean removeSharedLibraryLPw(String name, long version) {
11310 LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
11311 if (versionedLib == null) {
11314 final int libIdx = versionedLib.indexOfKey(version);
11318 SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx);
11319 versionedLib.remove(version);
11320 if (versionedLib.size() <= 0) {
11321 mSharedLibraries.remove(name);
11322 if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) {
11323 mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage()
11324 .getPackageName());
11331 * Adds a scanned package to the system. When this method is finished, the package will
11332 * be available for query, resolution, etc...
11334 private void commitPackageSettings(PackageParser.Package pkg,
11335 @Nullable PackageParser.Package oldPkg, PackageSetting pkgSetting, UserHandle user,
11336 final @ScanFlags int scanFlags, boolean chatty) {
11337 final String pkgName = pkg.packageName;
11338 if (mCustomResolverComponentName != null &&
11339 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
11340 setUpCustomResolverActivity(pkg);
11343 if (pkg.packageName.equals("android")) {
11344 synchronized (mPackages) {
11345 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
11346 // Set up information for our fall-back user intent resolution activity.
11347 mPlatformPackage = pkg;
11348 pkg.mVersionCode = mSdkVersion;
11349 pkg.mVersionCodeMajor = 0;
11350 mAndroidApplication = pkg.applicationInfo;
11351 if (!mResolverReplaced) {
11352 mResolveActivity.applicationInfo = mAndroidApplication;
11353 mResolveActivity.name = ResolverActivity.class.getName();
11354 mResolveActivity.packageName = mAndroidApplication.packageName;
11355 mResolveActivity.processName = "system:ui";
11356 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11357 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
11358 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
11359 mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
11360 mResolveActivity.exported = true;
11361 mResolveActivity.enabled = true;
11362 mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
11363 mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
11364 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
11365 | ActivityInfo.CONFIG_SCREEN_LAYOUT
11366 | ActivityInfo.CONFIG_ORIENTATION
11367 | ActivityInfo.CONFIG_KEYBOARD
11368 | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
11369 mResolveInfo.activityInfo = mResolveActivity;
11370 mResolveInfo.priority = 0;
11371 mResolveInfo.preferredOrder = 0;
11372 mResolveInfo.match = 0;
11373 mResolveComponentName = new ComponentName(
11374 mAndroidApplication.packageName, mResolveActivity.name);
11380 ArrayList<PackageParser.Package> clientLibPkgs = null;
11382 synchronized (mPackages) {
11383 boolean hasStaticSharedLibs = false;
11385 // Any app can add new static shared libraries
11386 if (pkg.staticSharedLibName != null) {
11387 // Static shared libs don't allow renaming as they have synthetic package
11388 // names to allow install of multiple versions, so use name from manifest.
11389 if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName,
11390 pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC,
11391 pkg.manifestPackageName, pkg.getLongVersionCode())) {
11392 hasStaticSharedLibs = true;
11394 Slog.w(TAG, "Package " + pkg.packageName + " library "
11395 + pkg.staticSharedLibName + " already exists; skipping");
11397 // Static shared libs cannot be updated once installed since they
11398 // use synthetic package name which includes the version code, so
11399 // not need to update other packages's shared lib dependencies.
11402 if (!hasStaticSharedLibs
11403 && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11404 // Only system apps can add new dynamic shared libraries.
11405 if (pkg.libraryNames != null) {
11406 for (int i = 0; i < pkg.libraryNames.size(); i++) {
11407 String name = pkg.libraryNames.get(i);
11408 boolean allowed = false;
11409 if (pkg.isUpdatedSystemApp()) {
11410 // New library entries can only be added through the
11411 // system image. This is important to get rid of a lot
11412 // of nasty edge cases: for example if we allowed a non-
11413 // system update of the app to add a library, then uninstalling
11414 // the update would make the library go away, and assumptions
11415 // we made such as through app install filtering would now
11416 // have allowed apps on the device which aren't compatible
11417 // with it. Better to just have the restriction here, be
11418 // conservative, and create many fewer cases that can negatively
11419 // impact the user experience.
11420 final PackageSetting sysPs = mSettings
11421 .getDisabledSystemPkgLPr(pkg.packageName);
11422 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
11423 for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
11424 if (name.equals(sysPs.pkg.libraryNames.get(j))) {
11434 if (!addSharedLibraryLPw(null, pkg.packageName, name,
11435 SharedLibraryInfo.VERSION_UNDEFINED,
11436 SharedLibraryInfo.TYPE_DYNAMIC,
11437 pkg.packageName, pkg.getLongVersionCode())) {
11438 Slog.w(TAG, "Package " + pkg.packageName + " library "
11439 + name + " already exists; skipping");
11442 Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
11443 + name + " that is not declared on system image; skipping");
11447 if ((scanFlags & SCAN_BOOTING) == 0) {
11448 // If we are not booting, we need to update any applications
11449 // that are clients of our shared library. If we are booting,
11450 // this will all be done once the scan is complete.
11451 clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
11457 if ((scanFlags & SCAN_BOOTING) != 0) {
11458 // No apps can run during boot scan, so they don't need to be frozen
11459 } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
11460 // Caller asked to not kill app, so it's probably not frozen
11461 } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
11462 // Caller asked us to ignore frozen check for some reason; they
11463 // probably didn't know the package name
11465 // We're doing major surgery on this package, so it better be frozen
11466 // right now to keep it from launching
11467 checkPackageFrozen(pkgName);
11470 // Also need to kill any apps that are dependent on the library.
11471 if (clientLibPkgs != null) {
11472 for (int i=0; i<clientLibPkgs.size(); i++) {
11473 PackageParser.Package clientPkg = clientLibPkgs.get(i);
11474 killApplication(clientPkg.applicationInfo.packageName,
11475 clientPkg.applicationInfo.uid, "update lib");
11480 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
11482 synchronized (mPackages) {
11483 // We don't expect installation to fail beyond this point
11485 // Add the new setting to mSettings
11486 mSettings.insertPackageSettingLPw(pkgSetting, pkg);
11487 // Add the new setting to mPackages
11488 mPackages.put(pkg.applicationInfo.packageName, pkg);
11489 // Make sure we don't accidentally delete its data.
11490 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
11491 while (iter.hasNext()) {
11492 PackageCleanItem item = iter.next();
11493 if (pkgName.equals(item.packageName)) {
11498 // Add the package's KeySets to the global KeySetManagerService
11499 KeySetManagerService ksms = mSettings.mKeySetManagerService;
11500 ksms.addScannedPackageLPw(pkg);
11502 int N = pkg.providers.size();
11503 StringBuilder r = null;
11505 for (i=0; i<N; i++) {
11506 PackageParser.Provider p = pkg.providers.get(i);
11507 p.info.processName = fixProcessName(pkg.applicationInfo.processName,
11508 p.info.processName);
11509 mProviders.addProvider(p);
11510 p.syncable = p.info.isSyncable;
11511 if (p.info.authority != null) {
11512 String names[] = p.info.authority.split(";");
11513 p.info.authority = null;
11514 for (int j = 0; j < names.length; j++) {
11515 if (j == 1 && p.syncable) {
11516 // We only want the first authority for a provider to possibly be
11517 // syncable, so if we already added this provider using a different
11518 // authority clear the syncable flag. We copy the provider before
11519 // changing it because the mProviders object contains a reference
11520 // to a provider that we don't want to change.
11521 // Only do this for the second authority since the resulting provider
11522 // object can be the same for all future authorities for this provider.
11523 p = new PackageParser.Provider(p);
11524 p.syncable = false;
11526 if (!mProvidersByAuthority.containsKey(names[j])) {
11527 mProvidersByAuthority.put(names[j], p);
11528 if (p.info.authority == null) {
11529 p.info.authority = names[j];
11531 p.info.authority = p.info.authority + ";" + names[j];
11533 if (DEBUG_PACKAGE_SCANNING) {
11535 Log.d(TAG, "Registered content provider: " + names[j]
11536 + ", className = " + p.info.name + ", isSyncable = "
11537 + p.info.isSyncable);
11540 PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
11541 Slog.w(TAG, "Skipping provider name " + names[j] +
11542 " (in package " + pkg.applicationInfo.packageName +
11543 "): name already used by "
11544 + ((other != null && other.getComponentName() != null)
11545 ? other.getComponentName().getPackageName() : "?"));
11551 r = new StringBuilder(256);
11555 r.append(p.info.name);
11559 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r);
11562 N = pkg.services.size();
11564 for (i=0; i<N; i++) {
11565 PackageParser.Service s = pkg.services.get(i);
11566 s.info.processName = fixProcessName(pkg.applicationInfo.processName,
11567 s.info.processName);
11568 mServices.addService(s);
11571 r = new StringBuilder(256);
11575 r.append(s.info.name);
11579 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r);
11582 N = pkg.receivers.size();
11584 for (i=0; i<N; i++) {
11585 PackageParser.Activity a = pkg.receivers.get(i);
11586 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11587 a.info.processName);
11588 mReceivers.addActivity(a, "receiver");
11591 r = new StringBuilder(256);
11595 r.append(a.info.name);
11599 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r);
11602 N = pkg.activities.size();
11604 for (i=0; i<N; i++) {
11605 PackageParser.Activity a = pkg.activities.get(i);
11606 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11607 a.info.processName);
11608 mActivities.addActivity(a, "activity");
11611 r = new StringBuilder(256);
11615 r.append(a.info.name);
11619 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r);
11622 // Don't allow ephemeral applications to define new permissions groups.
11623 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11624 Slog.w(TAG, "Permission groups from package " + pkg.packageName
11625 + " ignored: instant apps cannot define new permission groups.");
11627 mPermissionManager.addAllPermissionGroups(pkg, chatty);
11630 // Don't allow ephemeral applications to define new permissions.
11631 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11632 Slog.w(TAG, "Permissions from package " + pkg.packageName
11633 + " ignored: instant apps cannot define new permissions.");
11635 mPermissionManager.addAllPermissions(pkg, chatty);
11638 N = pkg.instrumentation.size();
11640 for (i=0; i<N; i++) {
11641 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
11642 a.info.packageName = pkg.applicationInfo.packageName;
11643 a.info.sourceDir = pkg.applicationInfo.sourceDir;
11644 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
11645 a.info.splitNames = pkg.splitNames;
11646 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
11647 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
11648 a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
11649 a.info.dataDir = pkg.applicationInfo.dataDir;
11650 a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
11651 a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
11652 a.info.primaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
11653 a.info.secondaryCpuAbi = pkg.applicationInfo.secondaryCpuAbi;
11654 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
11655 a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
11656 mInstrumentation.put(a.getComponentName(), a);
11659 r = new StringBuilder(256);
11663 r.append(a.info.name);
11667 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r);
11670 if (pkg.protectedBroadcasts != null) {
11671 N = pkg.protectedBroadcasts.size();
11672 synchronized (mProtectedBroadcasts) {
11673 for (i = 0; i < N; i++) {
11674 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
11679 if (oldPkg != null) {
11680 // We need to call revokeRuntimePermissionsIfGroupChanged async as permission
11681 // revoke callbacks from this method might need to kill apps which need the
11682 // mPackages lock on a different thread. This would dead lock.
11684 // Hence create a copy of all package names and pass it into
11685 // revokeRuntimePermissionsIfGroupChanged. Only for those permissions might get
11686 // revoked. If a new package is added before the async code runs the permission
11687 // won't be granted yet, hence new packages are no problem.
11688 final ArrayList<String> allPackageNames = new ArrayList<>(mPackages.keySet());
11690 AsyncTask.execute(() ->
11691 mPermissionManager.revokeRuntimePermissionsIfGroupChanged(pkg, oldPkg,
11692 allPackageNames, mPermissionCallback));
11696 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11700 * Derive the ABI of a non-system package located at {@code scanFile}. This information
11701 * is derived purely on the basis of the contents of {@code scanFile} and
11702 * {@code cpuAbiOverride}.
11704 * If {@code extractLibs} is true, native libraries are extracted from the app if required.
11706 private static void derivePackageAbi(PackageParser.Package pkg, String cpuAbiOverride,
11707 boolean extractLibs)
11708 throws PackageManagerException {
11709 // Give ourselves some initial paths; we'll come back for another
11710 // pass once we've determined ABI below.
11711 setNativeLibraryPaths(pkg, sAppLib32InstallDir);
11713 // We would never need to extract libs for forward-locked and external packages,
11714 // since the container service will do it for us. We shouldn't attempt to
11715 // extract libs from system app when it was not updated.
11716 if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
11717 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
11718 extractLibs = false;
11721 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
11722 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
11724 NativeLibraryHelper.Handle handle = null;
11726 handle = NativeLibraryHelper.Handle.create(pkg);
11727 // TODO(multiArch): This can be null for apps that didn't go through the
11728 // usual installation process. We can calculate it again, like we
11729 // do during install time.
11731 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
11733 final File nativeLibraryRoot = new File(nativeLibraryRootStr);
11735 // Null out the abis so that they can be recalculated.
11736 pkg.applicationInfo.primaryCpuAbi = null;
11737 pkg.applicationInfo.secondaryCpuAbi = null;
11738 if (isMultiArch(pkg.applicationInfo)) {
11739 // Warn if we've set an abiOverride for multi-lib packages..
11740 // By definition, we need to copy both 32 and 64 bit libraries for
11742 if (pkg.cpuAbiOverride != null
11743 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
11744 Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
11747 int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
11748 int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
11749 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
11751 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11752 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11753 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
11754 useIsaSpecificSubdirs);
11756 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11757 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
11759 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11762 // Shared library native code should be in the APK zip aligned
11763 if (abi32 >= 0 && pkg.isLibrary() && extractLibs) {
11764 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11765 "Shared library native lib extraction not supported");
11768 maybeThrowExceptionForMultiArchCopy(
11769 "Error unpackaging 32 bit native libs for multiarch app.", abi32);
11771 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
11773 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11774 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11775 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
11776 useIsaSpecificSubdirs);
11778 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11779 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
11781 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11784 maybeThrowExceptionForMultiArchCopy(
11785 "Error unpackaging 64 bit native libs for multiarch app.", abi64);
11788 // Shared library native libs should be in the APK zip aligned
11789 if (extractLibs && pkg.isLibrary()) {
11790 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11791 "Shared library native lib extraction not supported");
11793 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
11797 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
11799 if (pkg.use32bitAbi) {
11800 pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
11801 pkg.applicationInfo.primaryCpuAbi = abi;
11803 pkg.applicationInfo.secondaryCpuAbi = abi;
11806 pkg.applicationInfo.primaryCpuAbi = abi;
11810 String[] abiList = (cpuAbiOverride != null) ?
11811 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
11813 // Enable gross and lame hacks for apps that are built with old
11814 // SDK tools. We must scan their APKs for renderscript bitcode and
11815 // not launch them if it's present. Don't bother checking on devices
11816 // that don't have 64 bit support.
11817 boolean needsRenderScriptOverride = false;
11818 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
11819 NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
11820 abiList = Build.SUPPORTED_32_BIT_ABIS;
11821 needsRenderScriptOverride = true;
11826 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11827 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11828 nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
11830 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11831 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
11833 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11835 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
11836 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11837 "Error unpackaging native libs for app, errorCode=" + copyRet);
11840 if (copyRet >= 0) {
11841 // Shared libraries that have native libs must be multi-architecture
11842 if (pkg.isLibrary()) {
11843 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11844 "Shared library with native libs must be multiarch");
11846 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
11847 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
11848 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
11849 } else if (needsRenderScriptOverride) {
11850 pkg.applicationInfo.primaryCpuAbi = abiList[0];
11853 } catch (IOException ioe) {
11854 Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
11856 IoUtils.closeQuietly(handle);
11859 // Now that we've calculated the ABIs and determined if it's an internal app,
11860 // we will go ahead and populate the nativeLibraryPath.
11861 setNativeLibraryPaths(pkg, sAppLib32InstallDir);
11865 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
11866 * i.e, so that all packages can be run inside a single process if required.
11868 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
11869 * this function will either try and make the ABI for all packages in {@code packagesForUser}
11870 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
11871 * the ABI selected for {@code packagesForUser}. This variant is used when installing or
11872 * updating a package that belongs to a shared user.
11874 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
11875 * adds unnecessary complexity.
11877 private static @Nullable List<String> adjustCpuAbisForSharedUserLPw(
11878 Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage) {
11879 List<String> changedAbiCodePath = null;
11880 String requiredInstructionSet = null;
11881 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
11882 requiredInstructionSet = VMRuntime.getInstructionSet(
11883 scannedPackage.applicationInfo.primaryCpuAbi);
11886 PackageSetting requirer = null;
11887 for (PackageSetting ps : packagesForUser) {
11888 // If packagesForUser contains scannedPackage, we skip it. This will happen
11889 // when scannedPackage is an update of an existing package. Without this check,
11890 // we will never be able to change the ABI of any package belonging to a shared
11891 // user, even if it's compatible with other packages.
11892 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11893 if (ps.primaryCpuAbiString == null) {
11897 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
11898 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
11899 // We have a mismatch between instruction sets (say arm vs arm64) warn about
11900 // this but there's not much we can do.
11901 String errorMessage = "Instruction set mismatch, "
11902 + ((requirer == null) ? "[caller]" : requirer)
11903 + " requires " + requiredInstructionSet + " whereas " + ps
11904 + " requires " + instructionSet;
11905 Slog.w(TAG, errorMessage);
11908 if (requiredInstructionSet == null) {
11909 requiredInstructionSet = instructionSet;
11915 if (requiredInstructionSet != null) {
11916 String adjustedAbi;
11917 if (requirer != null) {
11918 // requirer != null implies that either scannedPackage was null or that scannedPackage
11919 // did not require an ABI, in which case we have to adjust scannedPackage to match
11920 // the ABI of the set (which is the same as requirer's ABI)
11921 adjustedAbi = requirer.primaryCpuAbiString;
11922 if (scannedPackage != null) {
11923 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
11926 // requirer == null implies that we're updating all ABIs in the set to
11927 // match scannedPackage.
11928 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi;
11931 for (PackageSetting ps : packagesForUser) {
11932 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11933 if (ps.primaryCpuAbiString != null) {
11937 ps.primaryCpuAbiString = adjustedAbi;
11938 if (ps.pkg != null && ps.pkg.applicationInfo != null &&
11939 !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
11940 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
11941 if (DEBUG_ABI_SELECTION) {
11942 Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
11944 + (requirer != null ? requirer.pkg : "null")
11945 + ", scannedPackage="
11946 + (scannedPackage != null ? scannedPackage : "null")
11949 if (changedAbiCodePath == null) {
11950 changedAbiCodePath = new ArrayList<>();
11952 changedAbiCodePath.add(ps.codePathString);
11957 return changedAbiCodePath;
11960 private void setUpCustomResolverActivity(PackageParser.Package pkg) {
11961 synchronized (mPackages) {
11962 mResolverReplaced = true;
11963 // Set up information for custom user intent resolution activity.
11964 mResolveActivity.applicationInfo = pkg.applicationInfo;
11965 mResolveActivity.name = mCustomResolverComponentName.getClassName();
11966 mResolveActivity.packageName = pkg.applicationInfo.packageName;
11967 mResolveActivity.processName = pkg.applicationInfo.packageName;
11968 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11969 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
11970 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11971 mResolveActivity.theme = 0;
11972 mResolveActivity.exported = true;
11973 mResolveActivity.enabled = true;
11974 mResolveInfo.activityInfo = mResolveActivity;
11975 mResolveInfo.priority = 0;
11976 mResolveInfo.preferredOrder = 0;
11977 mResolveInfo.match = 0;
11978 mResolveComponentName = mCustomResolverComponentName;
11979 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
11980 mResolveComponentName);
11984 private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
11985 if (installerActivity == null) {
11986 if (DEBUG_INSTANT) {
11987 Slog.d(TAG, "Clear ephemeral installer activity");
11989 mInstantAppInstallerActivity = null;
11993 if (DEBUG_INSTANT) {
11994 Slog.d(TAG, "Set ephemeral installer activity: "
11995 + installerActivity.getComponentName());
11997 // Set up information for ephemeral installer activity
11998 mInstantAppInstallerActivity = installerActivity;
11999 mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
12000 | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
12001 mInstantAppInstallerActivity.exported = true;
12002 mInstantAppInstallerActivity.enabled = true;
12003 mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
12004 mInstantAppInstallerInfo.priority = 1;
12005 mInstantAppInstallerInfo.preferredOrder = 1;
12006 mInstantAppInstallerInfo.isDefault = true;
12007 mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
12008 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
12011 private static String calculateBundledApkRoot(final String codePathString) {
12012 final File codePath = new File(codePathString);
12013 final File codeRoot;
12014 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
12015 codeRoot = Environment.getRootDirectory();
12016 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
12017 codeRoot = Environment.getOemDirectory();
12018 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
12019 codeRoot = Environment.getVendorDirectory();
12020 } else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) {
12021 codeRoot = Environment.getOdmDirectory();
12022 } else if (FileUtils.contains(Environment.getProductDirectory(), codePath)) {
12023 codeRoot = Environment.getProductDirectory();
12025 // Unrecognized code path; take its top real segment as the apk root:
12026 // e.g. /something/app/blah.apk => /something
12028 File f = codePath.getCanonicalFile();
12029 File parent = f.getParentFile(); // non-null because codePath is a file
12031 while ((tmp = parent.getParentFile()) != null) {
12036 Slog.w(TAG, "Unrecognized code path "
12037 + codePath + " - using " + codeRoot);
12038 } catch (IOException e) {
12039 // Can't canonicalize the code path -- shenanigans?
12040 Slog.w(TAG, "Can't canonicalize code path " + codePath);
12041 return Environment.getRootDirectory().getPath();
12044 return codeRoot.getPath();
12048 * Derive and set the location of native libraries for the given package,
12049 * which varies depending on where and how the package was installed.
12051 private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
12052 final ApplicationInfo info = pkg.applicationInfo;
12053 final String codePath = pkg.codePath;
12054 final File codeFile = new File(codePath);
12055 final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
12056 final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
12058 info.nativeLibraryRootDir = null;
12059 info.nativeLibraryRootRequiresIsa = false;
12060 info.nativeLibraryDir = null;
12061 info.secondaryNativeLibraryDir = null;
12063 if (isApkFile(codeFile)) {
12064 // Monolithic install
12066 // If "/system/lib64/apkname" exists, assume that is the per-package
12067 // native library directory to use; otherwise use "/system/lib/apkname".
12068 final String apkRoot = calculateBundledApkRoot(info.sourceDir);
12069 final boolean is64Bit = VMRuntime.is64BitInstructionSet(
12070 getPrimaryInstructionSet(info));
12072 // This is a bundled system app so choose the path based on the ABI.
12073 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
12074 // is just the default path.
12075 final String apkName = deriveCodePathName(codePath);
12076 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
12077 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
12078 apkName).getAbsolutePath();
12080 if (info.secondaryCpuAbi != null) {
12081 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
12082 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
12083 secondaryLibDir, apkName).getAbsolutePath();
12085 } else if (asecApp) {
12086 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
12087 .getAbsolutePath();
12089 final String apkName = deriveCodePathName(codePath);
12090 info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
12091 .getAbsolutePath();
12094 info.nativeLibraryRootRequiresIsa = false;
12095 info.nativeLibraryDir = info.nativeLibraryRootDir;
12098 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
12099 info.nativeLibraryRootRequiresIsa = true;
12101 info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
12102 getPrimaryInstructionSet(info)).getAbsolutePath();
12104 if (info.secondaryCpuAbi != null) {
12105 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
12106 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
12112 * Calculate the abis and roots for a bundled app. These can uniquely
12113 * be determined from the contents of the system partition, i.e whether
12114 * it contains 64 or 32 bit shared libraries etc. We do not validate any
12115 * of this information, and instead assume that the system was built
12118 private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
12119 PackageSetting pkgSetting) {
12120 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
12122 // If "/system/lib64/apkname" exists, assume that is the per-package
12123 // native library directory to use; otherwise use "/system/lib/apkname".
12124 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
12125 setBundledAppAbi(pkg, apkRoot, apkName);
12126 // pkgSetting might be null during rescan following uninstall of updates
12127 // to a bundled app, so accommodate that possibility. The settings in
12128 // that case will be established later from the parsed package.
12130 // If the settings aren't null, sync them up with what we've just derived.
12131 // note that apkRoot isn't stored in the package settings.
12132 if (pkgSetting != null) {
12133 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
12134 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
12139 * Deduces the ABI of a bundled app and sets the relevant fields on the
12140 * parsed pkg object.
12142 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
12143 * under which system libraries are installed.
12144 * @param apkName the name of the installed package.
12146 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
12147 final File codeFile = new File(pkg.codePath);
12149 final boolean has64BitLibs;
12150 final boolean has32BitLibs;
12151 if (isApkFile(codeFile)) {
12152 // Monolithic install
12153 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
12154 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
12157 final File rootDir = new File(codeFile, LIB_DIR_NAME);
12158 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
12159 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
12160 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
12161 has64BitLibs = (new File(rootDir, isa)).exists();
12163 has64BitLibs = false;
12165 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
12166 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
12167 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
12168 has32BitLibs = (new File(rootDir, isa)).exists();
12170 has32BitLibs = false;
12174 if (has64BitLibs && !has32BitLibs) {
12175 // The package has 64 bit libs, but not 32 bit libs. Its primary
12176 // ABI should be 64 bit. We can safely assume here that the bundled
12177 // native libraries correspond to the most preferred ABI in the list.
12179 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12180 pkg.applicationInfo.secondaryCpuAbi = null;
12181 } else if (has32BitLibs && !has64BitLibs) {
12182 // The package has 32 bit libs but not 64 bit libs. Its primary
12183 // ABI should be 32 bit.
12185 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12186 pkg.applicationInfo.secondaryCpuAbi = null;
12187 } else if (has32BitLibs && has64BitLibs) {
12188 // The application has both 64 and 32 bit bundled libraries. We check
12189 // here that the app declares multiArch support, and warn if it doesn't.
12191 // We will be lenient here and record both ABIs. The primary will be the
12192 // ABI that's higher on the list, i.e, a device that's configured to prefer
12193 // 64 bit apps will see a 64 bit primary ABI,
12195 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
12196 Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
12199 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
12200 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12201 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12203 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12204 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12207 pkg.applicationInfo.primaryCpuAbi = null;
12208 pkg.applicationInfo.secondaryCpuAbi = null;
12212 private void killApplication(String pkgName, int appId, String reason) {
12213 killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
12216 private void killApplication(String pkgName, int appId, int userId, String reason) {
12217 // Request the ActivityManager to kill the process(only for existing packages)
12218 // so that we do not end up in a confused state while the user is still using the older
12219 // version of the application while the new one gets installed.
12220 final long token = Binder.clearCallingIdentity();
12222 IActivityManager am = ActivityManager.getService();
12225 am.killApplication(pkgName, appId, userId, reason);
12226 } catch (RemoteException e) {
12230 Binder.restoreCallingIdentity(token);
12234 private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
12235 // Remove the parent package setting
12236 PackageSetting ps = (PackageSetting) pkg.mExtras;
12238 removePackageLI(ps, chatty);
12240 // Remove the child package setting
12241 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12242 for (int i = 0; i < childCount; i++) {
12243 PackageParser.Package childPkg = pkg.childPackages.get(i);
12244 ps = (PackageSetting) childPkg.mExtras;
12246 removePackageLI(ps, chatty);
12251 void removePackageLI(PackageSetting ps, boolean chatty) {
12252 if (DEBUG_INSTALL) {
12254 Log.d(TAG, "Removing package " + ps.name);
12258 synchronized (mPackages) {
12259 mPackages.remove(ps.name);
12260 final PackageParser.Package pkg = ps.pkg;
12262 cleanPackageDataStructuresLILPw(pkg, chatty);
12267 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
12268 if (DEBUG_INSTALL) {
12270 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
12274 synchronized (mPackages) {
12275 // Remove the parent package
12276 mPackages.remove(pkg.applicationInfo.packageName);
12277 cleanPackageDataStructuresLILPw(pkg, chatty);
12279 // Remove the child packages
12280 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12281 for (int i = 0; i < childCount; i++) {
12282 PackageParser.Package childPkg = pkg.childPackages.get(i);
12283 mPackages.remove(childPkg.applicationInfo.packageName);
12284 cleanPackageDataStructuresLILPw(childPkg, chatty);
12289 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
12290 int N = pkg.providers.size();
12291 StringBuilder r = null;
12293 for (i=0; i<N; i++) {
12294 PackageParser.Provider p = pkg.providers.get(i);
12295 mProviders.removeProvider(p);
12296 if (p.info.authority == null) {
12298 /* There was another ContentProvider with this authority when
12299 * this app was installed so this authority is null,
12300 * Ignore it as we don't have to unregister the provider.
12304 String names[] = p.info.authority.split(";");
12305 for (int j = 0; j < names.length; j++) {
12306 if (mProvidersByAuthority.get(names[j]) == p) {
12307 mProvidersByAuthority.remove(names[j]);
12308 if (DEBUG_REMOVE) {
12310 Log.d(TAG, "Unregistered content provider: " + names[j]
12311 + ", className = " + p.info.name + ", isSyncable = "
12312 + p.info.isSyncable);
12316 if (DEBUG_REMOVE && chatty) {
12318 r = new StringBuilder(256);
12322 r.append(p.info.name);
12326 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r);
12329 N = pkg.services.size();
12331 for (i=0; i<N; i++) {
12332 PackageParser.Service s = pkg.services.get(i);
12333 mServices.removeService(s);
12336 r = new StringBuilder(256);
12340 r.append(s.info.name);
12344 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r);
12347 N = pkg.receivers.size();
12349 for (i=0; i<N; i++) {
12350 PackageParser.Activity a = pkg.receivers.get(i);
12351 mReceivers.removeActivity(a, "receiver");
12352 if (DEBUG_REMOVE && chatty) {
12354 r = new StringBuilder(256);
12358 r.append(a.info.name);
12362 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r);
12365 N = pkg.activities.size();
12367 for (i=0; i<N; i++) {
12368 PackageParser.Activity a = pkg.activities.get(i);
12369 mActivities.removeActivity(a, "activity");
12370 if (DEBUG_REMOVE && chatty) {
12372 r = new StringBuilder(256);
12376 r.append(a.info.name);
12380 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r);
12383 mPermissionManager.removeAllPermissions(pkg, chatty);
12385 N = pkg.instrumentation.size();
12387 for (i=0; i<N; i++) {
12388 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
12389 mInstrumentation.remove(a.getComponentName());
12390 if (DEBUG_REMOVE && chatty) {
12392 r = new StringBuilder(256);
12396 r.append(a.info.name);
12400 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r);
12404 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12405 // Only system apps can hold shared libraries.
12406 if (pkg.libraryNames != null) {
12407 for (i = 0; i < pkg.libraryNames.size(); i++) {
12408 String name = pkg.libraryNames.get(i);
12409 if (removeSharedLibraryLPw(name, 0)) {
12410 if (DEBUG_REMOVE && chatty) {
12412 r = new StringBuilder(256);
12425 // Any package can hold static shared libraries.
12426 if (pkg.staticSharedLibName != null) {
12427 if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
12428 if (DEBUG_REMOVE && chatty) {
12430 r = new StringBuilder(256);
12434 r.append(pkg.staticSharedLibName);
12440 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r);
12445 final class ActivityIntentResolver
12446 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
12447 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12448 boolean defaultOnly, int userId) {
12449 if (!sUserManager.exists(userId)) return null;
12450 mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
12451 return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12454 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12456 if (!sUserManager.exists(userId)) return null;
12458 return super.queryIntent(intent, resolvedType,
12459 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12463 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12464 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
12465 if (!sUserManager.exists(userId)) return null;
12466 if (packageActivities == null) {
12470 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
12471 final int N = packageActivities.size();
12472 ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
12473 new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
12475 ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
12476 for (int i = 0; i < N; ++i) {
12477 intentFilters = packageActivities.get(i).intents;
12478 if (intentFilters != null && intentFilters.size() > 0) {
12479 PackageParser.ActivityIntentInfo[] array =
12480 new PackageParser.ActivityIntentInfo[intentFilters.size()];
12481 intentFilters.toArray(array);
12482 listCut.add(array);
12485 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12489 * Finds a privileged activity that matches the specified activity names.
12491 private PackageParser.Activity findMatchingActivity(
12492 List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
12493 for (PackageParser.Activity sysActivity : activityList) {
12494 if (sysActivity.info.name.equals(activityInfo.name)) {
12495 return sysActivity;
12497 if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
12498 return sysActivity;
12500 if (sysActivity.info.targetActivity != null) {
12501 if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
12502 return sysActivity;
12504 if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
12505 return sysActivity;
12512 public class IterGenerator<E> {
12513 public Iterator<E> generate(ActivityIntentInfo info) {
12518 public class ActionIterGenerator extends IterGenerator<String> {
12520 public Iterator<String> generate(ActivityIntentInfo info) {
12521 return info.actionsIterator();
12525 public class CategoriesIterGenerator extends IterGenerator<String> {
12527 public Iterator<String> generate(ActivityIntentInfo info) {
12528 return info.categoriesIterator();
12532 public class SchemesIterGenerator extends IterGenerator<String> {
12534 public Iterator<String> generate(ActivityIntentInfo info) {
12535 return info.schemesIterator();
12539 public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
12541 public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
12542 return info.authoritiesIterator();
12547 * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
12548 * MODIFIED. Do not pass in a list that should not be changed.
12550 private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
12551 IterGenerator<T> generator, Iterator<T> searchIterator) {
12552 // loop through the set of actions; every one must be found in the intent filter
12553 while (searchIterator.hasNext()) {
12554 // we must have at least one filter in the list to consider a match
12555 if (intentList.size() == 0) {
12559 final T searchAction = searchIterator.next();
12561 // loop through the set of intent filters
12562 final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
12563 while (intentIter.hasNext()) {
12564 final ActivityIntentInfo intentInfo = intentIter.next();
12565 boolean selectionFound = false;
12567 // loop through the intent filter's selection criteria; at least one
12568 // of them must match the searched criteria
12569 final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
12570 while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
12571 final T intentSelection = intentSelectionIter.next();
12572 if (intentSelection != null && intentSelection.equals(searchAction)) {
12573 selectionFound = true;
12578 // the selection criteria wasn't found in this filter's set; this filter
12579 // is not a potential match
12580 if (!selectionFound) {
12581 intentIter.remove();
12587 private boolean isProtectedAction(ActivityIntentInfo filter) {
12588 final Iterator<String> actionsIter = filter.actionsIterator();
12589 while (actionsIter != null && actionsIter.hasNext()) {
12590 final String filterAction = actionsIter.next();
12591 if (PROTECTED_ACTIONS.contains(filterAction)) {
12599 * Adjusts the priority of the given intent filter according to policy.
12602 * <li>The priority for non privileged applications is capped to '0'</li>
12603 * <li>The priority for protected actions on privileged applications is capped to '0'</li>
12604 * <li>The priority for unbundled updates to privileged applications is capped to the
12605 * priority defined on the system partition</li>
12608 * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
12609 * allowed to obtain any priority on any action.
12611 private void adjustPriority(
12612 List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
12613 // nothing to do; priority is fine as-is
12614 if (intent.getPriority() <= 0) {
12618 final ActivityInfo activityInfo = intent.activity.info;
12619 final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
12621 final boolean privilegedApp =
12622 ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
12623 if (!privilegedApp) {
12624 // non-privileged applications can never define a priority >0
12625 if (DEBUG_FILTERS) {
12626 Slog.i(TAG, "Non-privileged app; cap priority to 0;"
12627 + " package: " + applicationInfo.packageName
12628 + " activity: " + intent.activity.className
12629 + " origPrio: " + intent.getPriority());
12631 intent.setPriority(0);
12635 if (systemActivities == null) {
12636 // the system package is not disabled; we're parsing the system partition
12637 if (isProtectedAction(intent)) {
12638 if (mDeferProtectedFilters) {
12639 // We can't deal with these just yet. No component should ever obtain a
12640 // >0 priority for a protected actions, with ONE exception -- the setup
12641 // wizard. The setup wizard, however, cannot be known until we're able to
12642 // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
12643 // until all intent filters have been processed. Chicken, meet egg.
12644 // Let the filter temporarily have a high priority and rectify the
12645 // priorities after all system packages have been scanned.
12646 mProtectedFilters.add(intent);
12647 if (DEBUG_FILTERS) {
12648 Slog.i(TAG, "Protected action; save for later;"
12649 + " package: " + applicationInfo.packageName
12650 + " activity: " + intent.activity.className
12651 + " origPrio: " + intent.getPriority());
12655 if (DEBUG_FILTERS && mSetupWizardPackage == null) {
12656 Slog.i(TAG, "No setup wizard;"
12657 + " All protected intents capped to priority 0");
12659 if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
12660 if (DEBUG_FILTERS) {
12661 Slog.i(TAG, "Found setup wizard;"
12662 + " allow priority " + intent.getPriority() + ";"
12663 + " package: " + intent.activity.info.packageName
12664 + " activity: " + intent.activity.className
12665 + " priority: " + intent.getPriority());
12667 // setup wizard gets whatever it wants
12670 if (DEBUG_FILTERS) {
12671 Slog.i(TAG, "Protected action; cap priority to 0;"
12672 + " package: " + intent.activity.info.packageName
12673 + " activity: " + intent.activity.className
12674 + " origPrio: " + intent.getPriority());
12676 intent.setPriority(0);
12680 // privileged apps on the system image get whatever priority they request
12684 // privileged app unbundled update ... try to find the same activity
12685 final PackageParser.Activity foundActivity =
12686 findMatchingActivity(systemActivities, activityInfo);
12687 if (foundActivity == null) {
12688 // this is a new activity; it cannot obtain >0 priority
12689 if (DEBUG_FILTERS) {
12690 Slog.i(TAG, "New activity; cap priority to 0;"
12691 + " package: " + applicationInfo.packageName
12692 + " activity: " + intent.activity.className
12693 + " origPrio: " + intent.getPriority());
12695 intent.setPriority(0);
12699 // found activity, now check for filter equivalence
12701 // a shallow copy is enough; we modify the list, not its contents
12702 final List<ActivityIntentInfo> intentListCopy =
12703 new ArrayList<>(foundActivity.intents);
12704 final List<ActivityIntentInfo> foundFilters = findFilters(intent);
12706 // find matching action subsets
12707 final Iterator<String> actionsIterator = intent.actionsIterator();
12708 if (actionsIterator != null) {
12709 getIntentListSubset(
12710 intentListCopy, new ActionIterGenerator(), actionsIterator);
12711 if (intentListCopy.size() == 0) {
12712 // no more intents to match; we're not equivalent
12713 if (DEBUG_FILTERS) {
12714 Slog.i(TAG, "Mismatched action; cap priority to 0;"
12715 + " package: " + applicationInfo.packageName
12716 + " activity: " + intent.activity.className
12717 + " origPrio: " + intent.getPriority());
12719 intent.setPriority(0);
12724 // find matching category subsets
12725 final Iterator<String> categoriesIterator = intent.categoriesIterator();
12726 if (categoriesIterator != null) {
12727 getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
12728 categoriesIterator);
12729 if (intentListCopy.size() == 0) {
12730 // no more intents to match; we're not equivalent
12731 if (DEBUG_FILTERS) {
12732 Slog.i(TAG, "Mismatched category; cap priority to 0;"
12733 + " package: " + applicationInfo.packageName
12734 + " activity: " + intent.activity.className
12735 + " origPrio: " + intent.getPriority());
12737 intent.setPriority(0);
12742 // find matching schemes subsets
12743 final Iterator<String> schemesIterator = intent.schemesIterator();
12744 if (schemesIterator != null) {
12745 getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
12747 if (intentListCopy.size() == 0) {
12748 // no more intents to match; we're not equivalent
12749 if (DEBUG_FILTERS) {
12750 Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
12751 + " package: " + applicationInfo.packageName
12752 + " activity: " + intent.activity.className
12753 + " origPrio: " + intent.getPriority());
12755 intent.setPriority(0);
12760 // find matching authorities subsets
12761 final Iterator<IntentFilter.AuthorityEntry>
12762 authoritiesIterator = intent.authoritiesIterator();
12763 if (authoritiesIterator != null) {
12764 getIntentListSubset(intentListCopy,
12765 new AuthoritiesIterGenerator(),
12766 authoritiesIterator);
12767 if (intentListCopy.size() == 0) {
12768 // no more intents to match; we're not equivalent
12769 if (DEBUG_FILTERS) {
12770 Slog.i(TAG, "Mismatched authority; cap priority to 0;"
12771 + " package: " + applicationInfo.packageName
12772 + " activity: " + intent.activity.className
12773 + " origPrio: " + intent.getPriority());
12775 intent.setPriority(0);
12780 // we found matching filter(s); app gets the max priority of all intents
12781 int cappedPriority = 0;
12782 for (int i = intentListCopy.size() - 1; i >= 0; --i) {
12783 cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
12785 if (intent.getPriority() > cappedPriority) {
12786 if (DEBUG_FILTERS) {
12787 Slog.i(TAG, "Found matching filter(s);"
12788 + " cap priority to " + cappedPriority + ";"
12789 + " package: " + applicationInfo.packageName
12790 + " activity: " + intent.activity.className
12791 + " origPrio: " + intent.getPriority());
12793 intent.setPriority(cappedPriority);
12796 // all this for nothing; the requested priority was <= what was on the system
12799 public final void addActivity(PackageParser.Activity a, String type) {
12800 mActivities.put(a.getComponentName(), a);
12801 if (DEBUG_SHOW_INFO)
12803 TAG, " " + type + " " +
12804 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
12805 if (DEBUG_SHOW_INFO)
12806 Log.v(TAG, " Class=" + a.info.name);
12807 final int NI = a.intents.size();
12808 for (int j=0; j<NI; j++) {
12809 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12810 if ("activity".equals(type)) {
12811 final PackageSetting ps =
12812 mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
12813 final List<PackageParser.Activity> systemActivities =
12814 ps != null && ps.pkg != null ? ps.pkg.activities : null;
12815 adjustPriority(systemActivities, intent);
12817 if (DEBUG_SHOW_INFO) {
12818 Log.v(TAG, " IntentFilter:");
12819 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
12821 if (!intent.debugCheck()) {
12822 Log.w(TAG, "==> For Activity " + a.info.name);
12828 public final void removeActivity(PackageParser.Activity a, String type) {
12829 mActivities.remove(a.getComponentName());
12830 if (DEBUG_SHOW_INFO) {
12831 Log.v(TAG, " " + type + " "
12832 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
12833 : a.info.name) + ":");
12834 Log.v(TAG, " Class=" + a.info.name);
12836 final int NI = a.intents.size();
12837 for (int j=0; j<NI; j++) {
12838 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12839 if (DEBUG_SHOW_INFO) {
12840 Log.v(TAG, " IntentFilter:");
12841 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
12843 removeFilter(intent);
12848 protected boolean allowFilterResult(
12849 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
12850 ActivityInfo filterAi = filter.activity.info;
12851 for (int i=dest.size()-1; i>=0; i--) {
12852 ActivityInfo destAi = dest.get(i).activityInfo;
12853 if (destAi.name == filterAi.name
12854 && destAi.packageName == filterAi.packageName) {
12862 protected ActivityIntentInfo[] newArray(int size) {
12863 return new ActivityIntentInfo[size];
12867 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
12868 if (!sUserManager.exists(userId)) return true;
12869 PackageParser.Package p = filter.activity.owner;
12871 PackageSetting ps = (PackageSetting)p.mExtras;
12873 // System apps are never considered stopped for purposes of
12874 // filtering, because there may be no way for the user to
12875 // actually re-launch them.
12876 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
12877 && ps.getStopped(userId);
12884 protected boolean isPackageForFilter(String packageName,
12885 PackageParser.ActivityIntentInfo info) {
12886 return packageName.equals(info.activity.owner.packageName);
12890 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
12891 int match, int userId) {
12892 if (!sUserManager.exists(userId)) return null;
12893 if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
12896 final PackageParser.Activity activity = info.activity;
12897 PackageSetting ps = (PackageSetting) activity.owner.mExtras;
12901 final PackageUserState userState = ps.readUserState(userId);
12903 PackageParser.generateActivityInfo(activity, mFlags, userState, userId);
12907 final boolean matchExplicitlyVisibleOnly =
12908 (mFlags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
12909 final boolean matchVisibleToInstantApp =
12910 (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12911 final boolean componentVisible =
12912 matchVisibleToInstantApp
12913 && info.isVisibleToInstantApp()
12914 && (!matchExplicitlyVisibleOnly || info.isExplicitlyVisibleToInstantApp());
12915 final boolean matchInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12916 // throw out filters that aren't visible to ephemeral apps
12917 if (matchVisibleToInstantApp && !(componentVisible || userState.instantApp)) {
12920 // throw out instant app filters if we're not explicitly requesting them
12921 if (!matchInstantApp && userState.instantApp) {
12924 // throw out instant app filters if updates are available; will trigger
12925 // instant app resolution
12926 if (userState.instantApp && ps.isUpdateAvailable()) {
12929 final ResolveInfo res = new ResolveInfo();
12930 res.activityInfo = ai;
12931 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12934 if (info != null) {
12935 res.handleAllWebDataURI = info.handleAllWebDataURI();
12937 res.priority = info.getPriority();
12938 res.preferredOrder = activity.owner.mPreferredOrder;
12939 //System.out.println("Result: " + res.activityInfo.className +
12940 // " = " + res.priority);
12942 res.isDefault = info.hasDefault;
12943 res.labelRes = info.labelRes;
12944 res.nonLocalizedLabel = info.nonLocalizedLabel;
12945 if (userNeedsBadging(userId)) {
12946 res.noResourceId = true;
12948 res.icon = info.icon;
12950 res.iconResourceId = info.icon;
12951 res.system = res.activityInfo.applicationInfo.isSystemApp();
12952 res.isInstantAppAvailable = userState.instantApp;
12957 protected void sortResults(List<ResolveInfo> results) {
12958 Collections.sort(results, mResolvePrioritySorter);
12962 protected void dumpFilter(PrintWriter out, String prefix,
12963 PackageParser.ActivityIntentInfo filter) {
12964 out.print(prefix); out.print(
12965 Integer.toHexString(System.identityHashCode(filter.activity)));
12967 filter.activity.printComponentShortName(out);
12968 out.print(" filter ");
12969 out.println(Integer.toHexString(System.identityHashCode(filter)));
12973 protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
12974 return filter.activity;
12977 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12978 PackageParser.Activity activity = (PackageParser.Activity)label;
12979 out.print(prefix); out.print(
12980 Integer.toHexString(System.identityHashCode(activity)));
12982 activity.printComponentShortName(out);
12984 out.print(" ("); out.print(count); out.print(" filters)");
12989 // Keys are String (activity class name), values are Activity.
12990 private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
12991 = new ArrayMap<ComponentName, PackageParser.Activity>();
12992 private int mFlags;
12995 private final class ServiceIntentResolver
12996 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
12997 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12998 boolean defaultOnly, int userId) {
12999 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
13000 return super.queryIntent(intent, resolvedType, defaultOnly, userId);
13003 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
13005 if (!sUserManager.exists(userId)) return null;
13007 return super.queryIntent(intent, resolvedType,
13008 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
13012 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
13013 int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
13014 if (!sUserManager.exists(userId)) return null;
13015 if (packageServices == null) {
13019 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
13020 final int N = packageServices.size();
13021 ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
13022 new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
13024 ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
13025 for (int i = 0; i < N; ++i) {
13026 intentFilters = packageServices.get(i).intents;
13027 if (intentFilters != null && intentFilters.size() > 0) {
13028 PackageParser.ServiceIntentInfo[] array =
13029 new PackageParser.ServiceIntentInfo[intentFilters.size()];
13030 intentFilters.toArray(array);
13031 listCut.add(array);
13034 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
13037 public final void addService(PackageParser.Service s) {
13038 mServices.put(s.getComponentName(), s);
13039 if (DEBUG_SHOW_INFO) {
13041 + (s.info.nonLocalizedLabel != null
13042 ? s.info.nonLocalizedLabel : s.info.name) + ":");
13043 Log.v(TAG, " Class=" + s.info.name);
13045 final int NI = s.intents.size();
13047 for (j=0; j<NI; j++) {
13048 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
13049 if (DEBUG_SHOW_INFO) {
13050 Log.v(TAG, " IntentFilter:");
13051 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
13053 if (!intent.debugCheck()) {
13054 Log.w(TAG, "==> For Service " + s.info.name);
13060 public final void removeService(PackageParser.Service s) {
13061 mServices.remove(s.getComponentName());
13062 if (DEBUG_SHOW_INFO) {
13063 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null
13064 ? s.info.nonLocalizedLabel : s.info.name) + ":");
13065 Log.v(TAG, " Class=" + s.info.name);
13067 final int NI = s.intents.size();
13069 for (j=0; j<NI; j++) {
13070 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
13071 if (DEBUG_SHOW_INFO) {
13072 Log.v(TAG, " IntentFilter:");
13073 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
13075 removeFilter(intent);
13080 protected boolean allowFilterResult(
13081 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
13082 ServiceInfo filterSi = filter.service.info;
13083 for (int i=dest.size()-1; i>=0; i--) {
13084 ServiceInfo destAi = dest.get(i).serviceInfo;
13085 if (destAi.name == filterSi.name
13086 && destAi.packageName == filterSi.packageName) {
13094 protected PackageParser.ServiceIntentInfo[] newArray(int size) {
13095 return new PackageParser.ServiceIntentInfo[size];
13099 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
13100 if (!sUserManager.exists(userId)) return true;
13101 PackageParser.Package p = filter.service.owner;
13103 PackageSetting ps = (PackageSetting)p.mExtras;
13105 // System apps are never considered stopped for purposes of
13106 // filtering, because there may be no way for the user to
13107 // actually re-launch them.
13108 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
13109 && ps.getStopped(userId);
13116 protected boolean isPackageForFilter(String packageName,
13117 PackageParser.ServiceIntentInfo info) {
13118 return packageName.equals(info.service.owner.packageName);
13122 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
13123 int match, int userId) {
13124 if (!sUserManager.exists(userId)) return null;
13125 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
13126 if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
13129 final PackageParser.Service service = info.service;
13130 PackageSetting ps = (PackageSetting) service.owner.mExtras;
13134 final PackageUserState userState = ps.readUserState(userId);
13135 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
13136 userState, userId);
13140 final boolean matchVisibleToInstantApp =
13141 (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
13142 final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
13143 // throw out filters that aren't visible to ephemeral apps
13144 if (matchVisibleToInstantApp
13145 && !(info.isVisibleToInstantApp() || userState.instantApp)) {
13148 // throw out ephemeral filters if we're not explicitly requesting them
13149 if (!isInstantApp && userState.instantApp) {
13152 // throw out instant app filters if updates are available; will trigger
13153 // instant app resolution
13154 if (userState.instantApp && ps.isUpdateAvailable()) {
13157 final ResolveInfo res = new ResolveInfo();
13158 res.serviceInfo = si;
13159 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
13160 res.filter = filter;
13162 res.priority = info.getPriority();
13163 res.preferredOrder = service.owner.mPreferredOrder;
13165 res.isDefault = info.hasDefault;
13166 res.labelRes = info.labelRes;
13167 res.nonLocalizedLabel = info.nonLocalizedLabel;
13168 res.icon = info.icon;
13169 res.system = res.serviceInfo.applicationInfo.isSystemApp();
13174 protected void sortResults(List<ResolveInfo> results) {
13175 Collections.sort(results, mResolvePrioritySorter);
13179 protected void dumpFilter(PrintWriter out, String prefix,
13180 PackageParser.ServiceIntentInfo filter) {
13181 out.print(prefix); out.print(
13182 Integer.toHexString(System.identityHashCode(filter.service)));
13184 filter.service.printComponentShortName(out);
13185 out.print(" filter ");
13186 out.print(Integer.toHexString(System.identityHashCode(filter)));
13187 if (filter.service.info.permission != null) {
13188 out.print(" permission "); out.println(filter.service.info.permission);
13195 protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
13196 return filter.service;
13199 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
13200 PackageParser.Service service = (PackageParser.Service)label;
13201 out.print(prefix); out.print(
13202 Integer.toHexString(System.identityHashCode(service)));
13204 service.printComponentShortName(out);
13206 out.print(" ("); out.print(count); out.print(" filters)");
13211 // List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
13212 // final Iterator<ResolveInfo> i = resolveInfoList.iterator();
13213 // final List<ResolveInfo> retList = Lists.newArrayList();
13214 // while (i.hasNext()) {
13215 // final ResolveInfo resolveInfo = (ResolveInfo) i;
13216 // if (isEnabledLP(resolveInfo.serviceInfo)) {
13217 // retList.add(resolveInfo);
13223 // Keys are String (activity class name), values are Activity.
13224 private final ArrayMap<ComponentName, PackageParser.Service> mServices
13225 = new ArrayMap<ComponentName, PackageParser.Service>();
13226 private int mFlags;
13229 private final class ProviderIntentResolver
13230 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
13231 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
13232 boolean defaultOnly, int userId) {
13233 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
13234 return super.queryIntent(intent, resolvedType, defaultOnly, userId);
13237 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
13239 if (!sUserManager.exists(userId))
13242 return super.queryIntent(intent, resolvedType,
13243 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
13247 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
13248 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
13249 if (!sUserManager.exists(userId))
13251 if (packageProviders == null) {
13255 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
13256 final int N = packageProviders.size();
13257 ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
13258 new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
13260 ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
13261 for (int i = 0; i < N; ++i) {
13262 intentFilters = packageProviders.get(i).intents;
13263 if (intentFilters != null && intentFilters.size() > 0) {
13264 PackageParser.ProviderIntentInfo[] array =
13265 new PackageParser.ProviderIntentInfo[intentFilters.size()];
13266 intentFilters.toArray(array);
13267 listCut.add(array);
13270 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
13273 public final void addProvider(PackageParser.Provider p) {
13274 if (mProviders.containsKey(p.getComponentName())) {
13275 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
13279 mProviders.put(p.getComponentName(), p);
13280 if (DEBUG_SHOW_INFO) {
13282 + (p.info.nonLocalizedLabel != null
13283 ? p.info.nonLocalizedLabel : p.info.name) + ":");
13284 Log.v(TAG, " Class=" + p.info.name);
13286 final int NI = p.intents.size();
13288 for (j = 0; j < NI; j++) {
13289 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
13290 if (DEBUG_SHOW_INFO) {
13291 Log.v(TAG, " IntentFilter:");
13292 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
13294 if (!intent.debugCheck()) {
13295 Log.w(TAG, "==> For Provider " + p.info.name);
13301 public final void removeProvider(PackageParser.Provider p) {
13302 mProviders.remove(p.getComponentName());
13303 if (DEBUG_SHOW_INFO) {
13304 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null
13305 ? p.info.nonLocalizedLabel : p.info.name) + ":");
13306 Log.v(TAG, " Class=" + p.info.name);
13308 final int NI = p.intents.size();
13310 for (j = 0; j < NI; j++) {
13311 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
13312 if (DEBUG_SHOW_INFO) {
13313 Log.v(TAG, " IntentFilter:");
13314 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
13316 removeFilter(intent);
13321 protected boolean allowFilterResult(
13322 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
13323 ProviderInfo filterPi = filter.provider.info;
13324 for (int i = dest.size() - 1; i >= 0; i--) {
13325 ProviderInfo destPi = dest.get(i).providerInfo;
13326 if (destPi.name == filterPi.name
13327 && destPi.packageName == filterPi.packageName) {
13335 protected PackageParser.ProviderIntentInfo[] newArray(int size) {
13336 return new PackageParser.ProviderIntentInfo[size];
13340 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
13341 if (!sUserManager.exists(userId))
13343 PackageParser.Package p = filter.provider.owner;
13345 PackageSetting ps = (PackageSetting) p.mExtras;
13347 // System apps are never considered stopped for purposes of
13348 // filtering, because there may be no way for the user to
13349 // actually re-launch them.
13350 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
13351 && ps.getStopped(userId);
13358 protected boolean isPackageForFilter(String packageName,
13359 PackageParser.ProviderIntentInfo info) {
13360 return packageName.equals(info.provider.owner.packageName);
13364 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
13365 int match, int userId) {
13366 if (!sUserManager.exists(userId))
13368 final PackageParser.ProviderIntentInfo info = filter;
13369 if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
13372 final PackageParser.Provider provider = info.provider;
13373 PackageSetting ps = (PackageSetting) provider.owner.mExtras;
13377 final PackageUserState userState = ps.readUserState(userId);
13378 final boolean matchVisibleToInstantApp =
13379 (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
13380 final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
13381 // throw out filters that aren't visible to instant applications
13382 if (matchVisibleToInstantApp
13383 && !(info.isVisibleToInstantApp() || userState.instantApp)) {
13386 // throw out instant application filters if we're not explicitly requesting them
13387 if (!isInstantApp && userState.instantApp) {
13390 // throw out instant application filters if updates are available; will trigger
13391 // instant application resolution
13392 if (userState.instantApp && ps.isUpdateAvailable()) {
13395 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
13396 userState, userId);
13400 final ResolveInfo res = new ResolveInfo();
13401 res.providerInfo = pi;
13402 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
13403 res.filter = filter;
13405 res.priority = info.getPriority();
13406 res.preferredOrder = provider.owner.mPreferredOrder;
13408 res.isDefault = info.hasDefault;
13409 res.labelRes = info.labelRes;
13410 res.nonLocalizedLabel = info.nonLocalizedLabel;
13411 res.icon = info.icon;
13412 res.system = res.providerInfo.applicationInfo.isSystemApp();
13417 protected void sortResults(List<ResolveInfo> results) {
13418 Collections.sort(results, mResolvePrioritySorter);
13422 protected void dumpFilter(PrintWriter out, String prefix,
13423 PackageParser.ProviderIntentInfo filter) {
13426 Integer.toHexString(System.identityHashCode(filter.provider)));
13428 filter.provider.printComponentShortName(out);
13429 out.print(" filter ");
13430 out.println(Integer.toHexString(System.identityHashCode(filter)));
13434 protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
13435 return filter.provider;
13438 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
13439 PackageParser.Provider provider = (PackageParser.Provider)label;
13440 out.print(prefix); out.print(
13441 Integer.toHexString(System.identityHashCode(provider)));
13443 provider.printComponentShortName(out);
13445 out.print(" ("); out.print(count); out.print(" filters)");
13450 private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
13451 = new ArrayMap<ComponentName, PackageParser.Provider>();
13452 private int mFlags;
13455 static final class InstantAppIntentResolver
13456 extends IntentResolver<AuxiliaryResolveInfo.AuxiliaryFilter,
13457 AuxiliaryResolveInfo.AuxiliaryFilter> {
13459 * The result that has the highest defined order. Ordering applies on a
13460 * per-package basis. Mapping is from package name to Pair of order and
13461 * EphemeralResolveInfo.
13463 * NOTE: This is implemented as a field variable for convenience and efficiency.
13464 * By having a field variable, we're able to track filter ordering as soon as
13465 * a non-zero order is defined. Otherwise, multiple loops across the result set
13466 * would be needed to apply ordering. If the intent resolver becomes re-entrant,
13467 * this needs to be contained entirely within {@link #filterResults}.
13469 final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
13472 protected AuxiliaryResolveInfo.AuxiliaryFilter[] newArray(int size) {
13473 return new AuxiliaryResolveInfo.AuxiliaryFilter[size];
13477 protected boolean isPackageForFilter(String packageName,
13478 AuxiliaryResolveInfo.AuxiliaryFilter responseObj) {
13483 protected AuxiliaryResolveInfo.AuxiliaryFilter newResult(
13484 AuxiliaryResolveInfo.AuxiliaryFilter responseObj, int match, int userId) {
13485 if (!sUserManager.exists(userId)) {
13488 final String packageName = responseObj.resolveInfo.getPackageName();
13489 final Integer order = responseObj.getOrder();
13490 final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
13491 mOrderResult.get(packageName);
13492 // ordering is enabled and this item's order isn't high enough
13493 if (lastOrderResult != null && lastOrderResult.first >= order) {
13496 final InstantAppResolveInfo res = responseObj.resolveInfo;
13498 // non-zero order, enable ordering
13499 mOrderResult.put(packageName, new Pair<>(order, res));
13501 return responseObj;
13505 protected void filterResults(List<AuxiliaryResolveInfo.AuxiliaryFilter> results) {
13506 // only do work if ordering is enabled [most of the time it won't be]
13507 if (mOrderResult.size() == 0) {
13510 int resultSize = results.size();
13511 for (int i = 0; i < resultSize; i++) {
13512 final InstantAppResolveInfo info = results.get(i).resolveInfo;
13513 final String packageName = info.getPackageName();
13514 final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName);
13515 if (savedInfo == null) {
13516 // package doesn't having ordering
13519 if (savedInfo.second == info) {
13520 // circled back to the highest ordered item; remove from order list
13521 mOrderResult.remove(packageName);
13522 if (mOrderResult.size() == 0) {
13523 // no more ordered items
13528 // item has a worse order, remove it from the result list
13536 private static final Comparator<ResolveInfo> mResolvePrioritySorter =
13537 new Comparator<ResolveInfo>() {
13538 public int compare(ResolveInfo r1, ResolveInfo r2) {
13539 int v1 = r1.priority;
13540 int v2 = r2.priority;
13541 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
13543 return (v1 > v2) ? -1 : 1;
13545 v1 = r1.preferredOrder;
13546 v2 = r2.preferredOrder;
13548 return (v1 > v2) ? -1 : 1;
13550 if (r1.isDefault != r2.isDefault) {
13551 return r1.isDefault ? -1 : 1;
13555 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
13557 return (v1 > v2) ? -1 : 1;
13559 if (r1.system != r2.system) {
13560 return r1.system ? -1 : 1;
13562 if (r1.activityInfo != null) {
13563 return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
13565 if (r1.serviceInfo != null) {
13566 return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
13568 if (r1.providerInfo != null) {
13569 return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
13575 private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
13576 new Comparator<ProviderInfo>() {
13577 public int compare(ProviderInfo p1, ProviderInfo p2) {
13578 final int v1 = p1.initOrder;
13579 final int v2 = p2.initOrder;
13580 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
13585 public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
13586 final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
13587 final int[] userIds, int[] instantUserIds) {
13588 mHandler.post(new Runnable() {
13590 public void run() {
13592 final IActivityManager am = ActivityManager.getService();
13593 if (am == null) return;
13594 final int[] resolvedUserIds;
13595 if (userIds == null) {
13596 resolvedUserIds = am.getRunningUserIds();
13598 resolvedUserIds = userIds;
13600 doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
13601 resolvedUserIds, false);
13602 if (instantUserIds != null && instantUserIds != EMPTY_INT_ARRAY) {
13603 doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
13604 instantUserIds, true);
13606 } catch (RemoteException ex) {
13613 public void notifyPackageAdded(String packageName) {
13614 final PackageListObserver[] observers;
13615 synchronized (mPackages) {
13616 if (mPackageListObservers.size() == 0) {
13619 observers = (PackageListObserver[]) mPackageListObservers.toArray();
13621 for (int i = observers.length - 1; i >= 0; --i) {
13622 observers[i].onPackageAdded(packageName);
13627 public void notifyPackageRemoved(String packageName) {
13628 final PackageListObserver[] observers;
13629 synchronized (mPackages) {
13630 if (mPackageListObservers.size() == 0) {
13633 observers = (PackageListObserver[]) mPackageListObservers.toArray();
13635 for (int i = observers.length - 1; i >= 0; --i) {
13636 observers[i].onPackageRemoved(packageName);
13641 * Sends a broadcast for the given action.
13642 * <p>If {@code isInstantApp} is {@code true}, then the broadcast is protected with
13643 * the {@link android.Manifest.permission#ACCESS_INSTANT_APPS} permission. This allows
13644 * the system and applications allowed to see instant applications to receive package
13645 * lifecycle events for instant applications.
13647 private void doSendBroadcast(IActivityManager am, String action, String pkg, Bundle extras,
13648 int flags, String targetPkg, IIntentReceiver finishedReceiver,
13649 int[] userIds, boolean isInstantApp)
13650 throws RemoteException {
13651 for (int id : userIds) {
13652 final Intent intent = new Intent(action,
13653 pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
13654 final String[] requiredPermissions =
13655 isInstantApp ? INSTANT_APP_BROADCAST_PERMISSION : null;
13656 if (extras != null) {
13657 intent.putExtras(extras);
13659 if (targetPkg != null) {
13660 intent.setPackage(targetPkg);
13662 // Modify the UID when posting to other users
13663 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
13664 if (uid > 0 && UserHandle.getUserId(uid) != id) {
13665 uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
13666 intent.putExtra(Intent.EXTRA_UID, uid);
13668 intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
13669 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
13670 if (DEBUG_BROADCASTS) {
13671 RuntimeException here = new RuntimeException("here");
13672 here.fillInStackTrace();
13673 Slog.d(TAG, "Sending to user " + id + ": "
13674 + intent.toShortString(false, true, false, false)
13675 + " " + intent.getExtras(), here);
13677 am.broadcastIntent(null, intent, null, finishedReceiver,
13678 0, null, null, requiredPermissions, android.app.AppOpsManager.OP_NONE,
13679 null, finishedReceiver != null, false, id);
13684 * Check if the external storage media is available. This is true if there
13685 * is a mounted external storage medium or if the external storage is
13688 private boolean isExternalMediaAvailable() {
13689 return mMediaMounted || Environment.isExternalStorageEmulated();
13693 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
13694 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
13697 if (!isExternalMediaAvailable()) {
13698 // If the external storage is no longer mounted at this point,
13699 // the caller may not have been able to delete all of this
13700 // packages files and can not delete any more. Bail.
13703 synchronized (mPackages) {
13704 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
13705 if (lastPackage != null) {
13706 pkgs.remove(lastPackage);
13708 if (pkgs.size() > 0) {
13709 return pkgs.get(0);
13715 void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
13716 final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
13717 userId, andCode ? 1 : 0, packageName);
13718 if (mSystemReady) {
13719 msg.sendToTarget();
13721 if (mPostSystemReadyMessages == null) {
13722 mPostSystemReadyMessages = new ArrayList<>();
13724 mPostSystemReadyMessages.add(msg);
13728 void startCleaningPackages() {
13730 if (!isExternalMediaAvailable()) {
13733 synchronized (mPackages) {
13734 if (mSettings.mPackagesToBeCleaned.isEmpty()) {
13738 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
13739 intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
13740 IActivityManager am = ActivityManager.getService();
13743 synchronized (mPackages) {
13744 if (!mDefaultContainerWhitelisted) {
13745 mDefaultContainerWhitelisted = true;
13746 PackageSetting ps = mSettings.mPackages.get(DEFAULT_CONTAINER_PACKAGE);
13747 dcsUid = UserHandle.getUid(UserHandle.USER_SYSTEM, ps.appId);
13752 am.backgroundWhitelistUid(dcsUid);
13754 am.startService(null, intent, null, false, mContext.getOpPackageName(),
13755 UserHandle.USER_SYSTEM);
13756 } catch (RemoteException e) {
13762 * Ensure that the install reason matches what we know about the package installer (e.g. whether
13763 * it is acting on behalf on an enterprise or the user).
13765 * Note that the ordering of the conditionals in this method is important. The checks we perform
13766 * are as follows, in this order:
13768 * 1) If the install is being performed by a system app, we can trust the app to have set the
13769 * install reason correctly. Thus, we pass through the install reason unchanged, no matter
13771 * 2) If the install is being performed by a device or profile owner app, the install reason
13772 * should be enterprise policy. However, we cannot be sure that the device or profile owner
13773 * set the install reason correctly. If the app targets an older SDK version where install
13774 * reasons did not exist yet, or if the app author simply forgot, the install reason may be
13775 * unset or wrong. Thus, we force the install reason to be enterprise policy.
13776 * 3) In all other cases, the install is being performed by a regular app that is neither part
13777 * of the system nor a device or profile owner. We have no reason to believe that this app is
13778 * acting on behalf of the enterprise admin. Thus, we check whether the install reason was
13779 * set to enterprise policy and if so, change it to unknown instead.
13781 private int fixUpInstallReason(String installerPackageName, int installerUid,
13782 int installReason) {
13783 if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
13784 == PERMISSION_GRANTED) {
13785 // If the install is being performed by a system app, we trust that app to have set the
13786 // install reason correctly.
13787 return installReason;
13789 final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(
13790 UserHandle.getUserId(installerUid));
13791 if (ownerPackage != null && ownerPackage.equals(installerPackageName)) {
13792 // If the install is being performed by a device or profile owner, the install
13793 // reason should be enterprise policy.
13794 return PackageManager.INSTALL_REASON_POLICY;
13798 if (installReason == PackageManager.INSTALL_REASON_POLICY) {
13799 // If the install is being performed by a regular app (i.e. neither system app nor
13800 // device or profile owner), we have no reason to believe that the app is acting on
13801 // behalf of an enterprise. If the app set the install reason to enterprise policy,
13802 // change it to unknown instead.
13803 return PackageManager.INSTALL_REASON_UNKNOWN;
13806 // If the install is being performed by a regular app and the install reason was set to any
13807 // value but enterprise policy, leave the install reason unchanged.
13808 return installReason;
13812 * Attempts to bind to the default container service explicitly instead of doing so lazily on
13815 void earlyBindToDefContainer() {
13816 mHandler.sendMessage(mHandler.obtainMessage(DEF_CONTAINER_BIND));
13819 void installStage(String packageName, File stagedDir,
13820 IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
13821 String installerPackageName, int installerUid, UserHandle user,
13822 PackageParser.SigningDetails signingDetails) {
13823 if (DEBUG_INSTANT) {
13824 if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
13825 Slog.d(TAG, "Ephemeral install of " + packageName);
13828 final VerificationInfo verificationInfo = new VerificationInfo(
13829 sessionParams.originatingUri, sessionParams.referrerUri,
13830 sessionParams.originatingUid, installerUid);
13832 final OriginInfo origin = OriginInfo.fromStagedFile(stagedDir);
13834 final Message msg = mHandler.obtainMessage(INIT_COPY);
13835 final int installReason = fixUpInstallReason(installerPackageName, installerUid,
13836 sessionParams.installReason);
13837 final InstallParams params = new InstallParams(origin, null, observer,
13838 sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
13839 verificationInfo, user, sessionParams.abiOverride,
13840 sessionParams.grantedRuntimePermissions, signingDetails, installReason);
13841 params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
13844 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
13845 System.identityHashCode(msg.obj));
13846 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
13847 System.identityHashCode(msg.obj));
13849 mHandler.sendMessage(msg);
13852 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
13854 final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
13855 final boolean isInstantApp = pkgSetting.getInstantApp(userId);
13856 final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
13857 final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
13858 sendPackageAddedForNewUsers(packageName, isSystem /*sendBootCompleted*/,
13859 false /*startReceiver*/, pkgSetting.appId, userIds, instantUserIds);
13861 // Send a session commit broadcast
13862 final PackageInstaller.SessionInfo info = new PackageInstaller.SessionInfo();
13863 info.installReason = pkgSetting.getInstallReason(userId);
13864 info.appPackageName = packageName;
13865 sendSessionCommitBroadcast(info, userId);
13869 public void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
13870 boolean includeStopped, int appId, int[] userIds, int[] instantUserIds) {
13871 if (ArrayUtils.isEmpty(userIds) && ArrayUtils.isEmpty(instantUserIds)) {
13874 Bundle extras = new Bundle(1);
13875 // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
13876 final int uid = UserHandle.getUid(
13877 (ArrayUtils.isEmpty(userIds) ? instantUserIds[0] : userIds[0]), appId);
13878 extras.putInt(Intent.EXTRA_UID, uid);
13880 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
13881 packageName, extras, 0, null, null, userIds, instantUserIds);
13882 if (sendBootCompleted && !ArrayUtils.isEmpty(userIds)) {
13883 mHandler.post(() -> {
13884 for (int userId : userIds) {
13885 sendBootCompletedBroadcastToSystemApp(
13886 packageName, includeStopped, userId);
13894 * The just-installed/enabled app is bundled on the system, so presumed to be able to run
13895 * automatically without needing an explicit launch.
13896 * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
13898 private void sendBootCompletedBroadcastToSystemApp(String packageName, boolean includeStopped,
13900 // If user is not running, the app didn't miss any broadcast
13901 if (!mUserManagerInternal.isUserRunning(userId)) {
13904 final IActivityManager am = ActivityManager.getService();
13906 // Deliver LOCKED_BOOT_COMPLETED first
13907 Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
13908 .setPackage(packageName);
13909 if (includeStopped) {
13910 lockedBcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
13912 final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
13913 am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
13914 android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13916 // Deliver BOOT_COMPLETED only if user is unlocked
13917 if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
13918 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
13919 if (includeStopped) {
13920 bcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
13922 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
13923 android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13925 } catch (RemoteException e) {
13926 throw e.rethrowFromSystemServer();
13931 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
13933 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13934 PackageSetting pkgSetting;
13935 final int callingUid = Binder.getCallingUid();
13936 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13937 true /* requireFullPermission */, true /* checkShell */,
13938 "setApplicationHiddenSetting for user " + userId);
13940 if (hidden && isPackageDeviceAdmin(packageName, userId)) {
13941 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
13945 long callingId = Binder.clearCallingIdentity();
13947 boolean sendAdded = false;
13948 boolean sendRemoved = false;
13950 synchronized (mPackages) {
13951 pkgSetting = mSettings.mPackages.get(packageName);
13952 if (pkgSetting == null) {
13955 if (filterAppAccessLPr(pkgSetting, callingUid, userId)) {
13958 // Do not allow "android" is being disabled
13959 if ("android".equals(packageName)) {
13960 Slog.w(TAG, "Cannot hide package: android");
13963 // Cannot hide static shared libs as they are considered
13964 // a part of the using app (emulating static linking). Also
13965 // static libs are installed always on internal storage.
13966 PackageParser.Package pkg = mPackages.get(packageName);
13967 if (pkg != null && pkg.staticSharedLibName != null) {
13968 Slog.w(TAG, "Cannot hide package: " + packageName
13969 + " providing static shared library: "
13970 + pkg.staticSharedLibName);
13973 // Only allow protected packages to hide themselves.
13974 if (hidden && !UserHandle.isSameApp(callingUid, pkgSetting.appId)
13975 && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13976 Slog.w(TAG, "Not hiding protected package: " + packageName);
13980 if (pkgSetting.getHidden(userId) != hidden) {
13981 pkgSetting.setHidden(hidden, userId);
13982 mSettings.writePackageRestrictionsLPr(userId);
13984 sendRemoved = true;
13991 sendPackageAddedForUser(packageName, pkgSetting, userId);
13995 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
13997 sendApplicationHiddenForUser(packageName, pkgSetting, userId);
14001 Binder.restoreCallingIdentity(callingId);
14007 public void setSystemAppHiddenUntilInstalled(String packageName, boolean hidden) {
14008 enforceSystemOrPhoneCaller("setSystemAppHiddenUntilInstalled");
14009 synchronized (mPackages) {
14010 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
14011 if (pkgSetting == null || !pkgSetting.isSystem()) {
14014 PackageParser.Package pkg = pkgSetting.pkg;
14015 if (pkg != null && pkg.applicationInfo != null) {
14016 pkg.applicationInfo.hiddenUntilInstalled = hidden;
14018 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(packageName);
14019 if (disabledPs == null) {
14022 pkg = disabledPs.pkg;
14023 if (pkg != null && pkg.applicationInfo != null) {
14024 pkg.applicationInfo.hiddenUntilInstalled = hidden;
14030 public boolean setSystemAppInstallState(String packageName, boolean installed, int userId) {
14031 enforceSystemOrPhoneCaller("setSystemAppInstallState");
14032 synchronized (mPackages) {
14033 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
14034 // The target app should always be in system
14035 if (pkgSetting == null || !pkgSetting.isSystem()) {
14038 // Check if the install state is the same
14039 if (pkgSetting.getInstalled(userId) == installed) {
14044 final long callingId = Binder.clearCallingIdentity();
14047 // install the app from uninstalled state
14048 installExistingPackageAsUser(
14051 0 /*installFlags*/,
14052 PackageManager.INSTALL_REASON_DEVICE_SETUP);
14056 // uninstall the app from installed state
14057 deletePackageVersioned(
14058 new VersionedPackage(packageName, PackageManager.VERSION_CODE_HIGHEST),
14059 new LegacyPackageDeleteObserver(null).getBinder(),
14061 PackageManager.DELETE_SYSTEM_APP);
14064 Binder.restoreCallingIdentity(callingId);
14068 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
14070 final PackageRemovedInfo info = new PackageRemovedInfo(this);
14071 info.removedPackage = packageName;
14072 info.installerPackageName = pkgSetting.installerPackageName;
14073 info.removedUsers = new int[] {userId};
14074 info.broadcastUsers = new int[] {userId};
14075 info.uid = UserHandle.getUid(userId, pkgSetting.appId);
14076 info.sendPackageRemovedBroadcasts(true /*killApp*/);
14079 private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended,
14080 PersistableBundle launcherExtras) {
14081 if (pkgList.length > 0) {
14082 Bundle extras = new Bundle(1);
14083 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
14084 if (launcherExtras != null) {
14085 extras.putBundle(Intent.EXTRA_LAUNCHER_EXTRAS,
14086 new Bundle(launcherExtras.deepCopy()));
14088 sendPackageBroadcast(
14089 suspended ? Intent.ACTION_PACKAGES_SUSPENDED
14090 : Intent.ACTION_PACKAGES_UNSUSPENDED,
14091 null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
14092 new int[] {userId}, null);
14097 * Returns true if application is not found or there was an error. Otherwise it returns
14098 * the hidden state of the package for the given user.
14101 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
14102 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
14103 final int callingUid = Binder.getCallingUid();
14104 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
14105 true /* requireFullPermission */, false /* checkShell */,
14106 "getApplicationHidden for user " + userId);
14108 long callingId = Binder.clearCallingIdentity();
14111 synchronized (mPackages) {
14112 ps = mSettings.mPackages.get(packageName);
14116 if (filterAppAccessLPr(ps, callingUid, userId)) {
14119 return ps.getHidden(userId);
14122 Binder.restoreCallingIdentity(callingId);
14130 public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
14131 int installReason) {
14132 final int callingUid = Binder.getCallingUid();
14133 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES)
14134 != PackageManager.PERMISSION_GRANTED
14135 && mContext.checkCallingOrSelfPermission(
14136 android.Manifest.permission.INSTALL_EXISTING_PACKAGES)
14137 != PackageManager.PERMISSION_GRANTED) {
14138 throw new SecurityException("Neither user " + callingUid + " nor current process has "
14139 + android.Manifest.permission.INSTALL_PACKAGES + ".");
14141 PackageSetting pkgSetting;
14142 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
14143 true /* requireFullPermission */, true /* checkShell */,
14144 "installExistingPackage for user " + userId);
14145 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
14146 return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
14149 long callingId = Binder.clearCallingIdentity();
14151 boolean installed = false;
14152 final boolean instantApp =
14153 (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
14154 final boolean fullApp =
14155 (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
14158 synchronized (mPackages) {
14159 pkgSetting = mSettings.mPackages.get(packageName);
14160 if (pkgSetting == null) {
14161 return PackageManager.INSTALL_FAILED_INVALID_URI;
14163 if (!canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
14164 // only allow the existing package to be used if it's installed as a full
14165 // application for at least one user
14166 boolean installAllowed = false;
14167 for (int checkUserId : sUserManager.getUserIds()) {
14168 installAllowed = !pkgSetting.getInstantApp(checkUserId);
14169 if (installAllowed) {
14173 if (!installAllowed) {
14174 return PackageManager.INSTALL_FAILED_INVALID_URI;
14177 if (!pkgSetting.getInstalled(userId)) {
14178 pkgSetting.setInstalled(true, userId);
14179 pkgSetting.setHidden(false, userId);
14180 pkgSetting.setInstallReason(installReason, userId);
14181 mSettings.writePackageRestrictionsLPr(userId);
14182 mSettings.writeKernelMappingLPr(pkgSetting);
14184 } else if (fullApp && pkgSetting.getInstantApp(userId)) {
14185 // upgrade app from instant to full; we don't allow app downgrade
14188 setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
14192 if (pkgSetting.pkg != null) {
14193 synchronized (mInstallLock) {
14194 // We don't need to freeze for a brand new install
14195 prepareAppDataAfterInstallLIF(pkgSetting.pkg);
14198 sendPackageAddedForUser(packageName, pkgSetting, userId);
14199 synchronized (mPackages) {
14200 updateSequenceNumberLP(pkgSetting, new int[]{ userId });
14204 Binder.restoreCallingIdentity(callingId);
14207 return PackageManager.INSTALL_SUCCEEDED;
14210 static void setInstantAppForUser(PackageSetting pkgSetting, int userId,
14211 boolean instantApp, boolean fullApp) {
14212 // no state specified; do nothing
14213 if (!instantApp && !fullApp) {
14216 if (userId != UserHandle.USER_ALL) {
14217 if (instantApp && !pkgSetting.getInstantApp(userId)) {
14218 pkgSetting.setInstantApp(true /*instantApp*/, userId);
14219 } else if (fullApp && pkgSetting.getInstantApp(userId)) {
14220 pkgSetting.setInstantApp(false /*instantApp*/, userId);
14223 for (int currentUserId : sUserManager.getUserIds()) {
14224 if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
14225 pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
14226 } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
14227 pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
14233 boolean isUserRestricted(int userId, String restrictionKey) {
14234 Bundle restrictions = sUserManager.getUserRestrictions(userId);
14235 if (restrictions.getBoolean(restrictionKey, false)) {
14236 Log.w(TAG, "User is restricted: " + restrictionKey);
14243 public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
14244 PersistableBundle appExtras, PersistableBundle launcherExtras, String dialogMessage,
14245 String callingPackage, int userId) {
14246 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS,
14247 "setPackagesSuspendedAsUser");
14249 final int callingUid = Binder.getCallingUid();
14250 if (callingUid != Process.ROOT_UID && callingUid != Process.SYSTEM_UID
14251 && getPackageUid(callingPackage, 0, userId) != callingUid) {
14252 throw new SecurityException("Calling package " + callingPackage + " in user "
14253 + userId + " does not belong to calling uid " + callingUid);
14255 if (!PLATFORM_PACKAGE_NAME.equals(callingPackage)
14256 && mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(userId) != null) {
14257 throw new UnsupportedOperationException("Cannot suspend/unsuspend packages. User "
14258 + userId + " has an active DO or PO");
14260 if (ArrayUtils.isEmpty(packageNames)) {
14261 return packageNames;
14264 final List<String> changedPackagesList = new ArrayList<>(packageNames.length);
14265 final List<String> unactionedPackages = new ArrayList<>(packageNames.length);
14266 final long callingId = Binder.clearCallingIdentity();
14268 synchronized (mPackages) {
14269 for (int i = 0; i < packageNames.length; i++) {
14270 final String packageName = packageNames[i];
14271 if (callingPackage.equals(packageName)) {
14272 Slog.w(TAG, "Calling package: " + callingPackage + " trying to "
14273 + (suspended ? "" : "un") + "suspend itself. Ignoring");
14274 unactionedPackages.add(packageName);
14277 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
14278 if (pkgSetting == null
14279 || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
14280 Slog.w(TAG, "Could not find package setting for package: " + packageName
14281 + ". Skipping suspending/un-suspending.");
14282 unactionedPackages.add(packageName);
14285 if (suspended && !canSuspendPackageForUserLocked(packageName, userId)) {
14286 unactionedPackages.add(packageName);
14289 pkgSetting.setSuspended(suspended, callingPackage, dialogMessage, appExtras,
14290 launcherExtras, userId);
14291 changedPackagesList.add(packageName);
14295 Binder.restoreCallingIdentity(callingId);
14297 if (!changedPackagesList.isEmpty()) {
14298 final String[] changedPackages = changedPackagesList.toArray(
14299 new String[changedPackagesList.size()]);
14300 sendPackagesSuspendedForUser(changedPackages, userId, suspended, launcherExtras);
14301 sendMyPackageSuspendedOrUnsuspended(changedPackages, suspended, appExtras, userId);
14302 synchronized (mPackages) {
14303 scheduleWritePackageRestrictionsLocked(userId);
14306 return unactionedPackages.toArray(new String[unactionedPackages.size()]);
14310 public PersistableBundle getSuspendedPackageAppExtras(String packageName, int userId) {
14311 final int callingUid = Binder.getCallingUid();
14312 if (getPackageUid(packageName, 0, userId) != callingUid) {
14313 throw new SecurityException("Calling package " + packageName
14314 + " does not belong to calling uid " + callingUid);
14316 synchronized (mPackages) {
14317 final PackageSetting ps = mSettings.mPackages.get(packageName);
14318 if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
14319 throw new IllegalArgumentException("Unknown target package: " + packageName);
14321 final PackageUserState packageUserState = ps.readUserState(userId);
14322 if (packageUserState.suspended) {
14323 return packageUserState.suspendedAppExtras;
14329 private void sendMyPackageSuspendedOrUnsuspended(String[] affectedPackages, boolean suspended,
14330 PersistableBundle appExtras, int userId) {
14331 final String action;
14332 final Bundle intentExtras = new Bundle();
14334 action = Intent.ACTION_MY_PACKAGE_SUSPENDED;
14335 if (appExtras != null) {
14336 final Bundle bundledAppExtras = new Bundle(appExtras.deepCopy());
14337 intentExtras.putBundle(Intent.EXTRA_SUSPENDED_PACKAGE_EXTRAS, bundledAppExtras);
14340 action = Intent.ACTION_MY_PACKAGE_UNSUSPENDED;
14342 mHandler.post(new Runnable() {
14344 public void run() {
14346 final IActivityManager am = ActivityManager.getService();
14348 Slog.wtf(TAG, "IActivityManager null. Cannot send MY_PACKAGE_ "
14349 + (suspended ? "" : "UN") + "SUSPENDED broadcasts");
14352 final int[] targetUserIds = new int[] {userId};
14353 for (String packageName : affectedPackages) {
14354 doSendBroadcast(am, action, null, intentExtras,
14355 Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, packageName, null,
14356 targetUserIds, false);
14358 } catch (RemoteException ex) {
14359 // Shouldn't happen as AMS is in the same process.
14366 public boolean isPackageSuspendedForUser(String packageName, int userId) {
14367 final int callingUid = Binder.getCallingUid();
14368 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
14369 true /* requireFullPermission */, false /* checkShell */,
14370 "isPackageSuspendedForUser for user " + userId);
14371 synchronized (mPackages) {
14372 final PackageSetting ps = mSettings.mPackages.get(packageName);
14373 if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
14374 throw new IllegalArgumentException("Unknown target package: " + packageName);
14376 return ps.getSuspended(userId);
14381 * Immediately unsuspends any packages suspended by the given package. To be called
14382 * when such a package's data is cleared or it is removed from the device.
14384 * <p><b>Should not be used on a frequent code path</b> as it flushes state to disk
14387 * @param packageName The package holding {@link Manifest.permission#SUSPEND_APPS} permission
14388 * @param affectedUser The user for which the changes are taking place.
14390 void unsuspendForSuspendingPackage(final String packageName, int affectedUser) {
14391 final int[] userIds = (affectedUser == UserHandle.USER_ALL) ? sUserManager.getUserIds()
14392 : new int[] {affectedUser};
14393 for (int userId : userIds) {
14394 unsuspendForSuspendingPackages(packageName::equals, userId);
14399 * Immediately unsuspends any packages in the given users not suspended by the platform or root.
14400 * To be called when a profile owner or a device owner is added.
14402 * <p><b>Should not be used on a frequent code path</b> as it flushes state to disk
14405 * @param userIds The users for which to unsuspend packages
14407 void unsuspendForNonSystemSuspendingPackages(ArraySet<Integer> userIds) {
14408 final int sz = userIds.size();
14409 for (int i = 0; i < sz; i++) {
14410 unsuspendForSuspendingPackages(
14411 (suspendingPackage) -> !PLATFORM_PACKAGE_NAME.equals(suspendingPackage),
14412 userIds.valueAt(i));
14416 private void unsuspendForSuspendingPackages(Predicate<String> packagePredicate, int userId) {
14417 final List<String> affectedPackages = new ArrayList<>();
14418 synchronized (mPackages) {
14419 for (PackageSetting ps : mSettings.mPackages.values()) {
14420 final PackageUserState pus = ps.readUserState(userId);
14421 if (pus.suspended && packagePredicate.test(pus.suspendingPackage)) {
14422 ps.setSuspended(false, null, null, null, null, userId);
14423 affectedPackages.add(ps.name);
14427 if (!affectedPackages.isEmpty()) {
14428 final String[] packageArray = affectedPackages.toArray(
14429 new String[affectedPackages.size()]);
14430 sendMyPackageSuspendedOrUnsuspended(packageArray, false, null, userId);
14431 sendPackagesSuspendedForUser(packageArray, userId, false, null);
14432 // Write package restrictions immediately to avoid an inconsistent state.
14433 mSettings.writePackageRestrictionsLPr(userId);
14437 @GuardedBy("mPackages")
14438 private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
14439 if (isPackageDeviceAdmin(packageName, userId)) {
14440 Slog.w(TAG, "Cannot suspend package \"" + packageName
14441 + "\": has an active device admin");
14445 String activeLauncherPackageName = getActiveLauncherPackageName(userId);
14446 if (packageName.equals(activeLauncherPackageName)) {
14447 Slog.w(TAG, "Cannot suspend package \"" + packageName
14448 + "\": contains the active launcher");
14452 if (packageName.equals(mRequiredInstallerPackage)) {
14453 Slog.w(TAG, "Cannot suspend package \"" + packageName
14454 + "\": required for package installation");
14458 if (packageName.equals(mRequiredUninstallerPackage)) {
14459 Slog.w(TAG, "Cannot suspend package \"" + packageName
14460 + "\": required for package uninstallation");
14464 if (packageName.equals(mRequiredVerifierPackage)) {
14465 Slog.w(TAG, "Cannot suspend package \"" + packageName
14466 + "\": required for package verification");
14470 if (packageName.equals(getDefaultDialerPackageName(userId))) {
14471 Slog.w(TAG, "Cannot suspend package \"" + packageName
14472 + "\": is the default dialer");
14476 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
14477 Slog.w(TAG, "Cannot suspend package \"" + packageName
14478 + "\": protected package");
14482 // Cannot suspend static shared libs as they are considered
14483 // a part of the using app (emulating static linking). Also
14484 // static libs are installed always on internal storage.
14485 PackageParser.Package pkg = mPackages.get(packageName);
14486 if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
14487 Slog.w(TAG, "Cannot suspend package: " + packageName
14488 + " providing static shared library: "
14489 + pkg.staticSharedLibName);
14493 if (PLATFORM_PACKAGE_NAME.equals(packageName)) {
14494 Slog.w(TAG, "Cannot suspend package: " + packageName);
14501 private String getActiveLauncherPackageName(int userId) {
14502 Intent intent = new Intent(Intent.ACTION_MAIN);
14503 intent.addCategory(Intent.CATEGORY_HOME);
14504 ResolveInfo resolveInfo = resolveIntent(
14506 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
14507 PackageManager.MATCH_DEFAULT_ONLY,
14510 return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
14513 private String getDefaultDialerPackageName(int userId) {
14514 synchronized (mPackages) {
14515 return mSettings.getDefaultDialerPackageNameLPw(userId);
14520 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
14521 mContext.enforceCallingOrSelfPermission(
14522 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14523 "Only package verification agents can verify applications");
14525 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
14526 final PackageVerificationResponse response = new PackageVerificationResponse(
14527 verificationCode, Binder.getCallingUid());
14529 msg.obj = response;
14530 mHandler.sendMessage(msg);
14534 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
14535 long millisecondsToDelay) {
14536 mContext.enforceCallingOrSelfPermission(
14537 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14538 "Only package verification agents can extend verification timeouts");
14540 final PackageVerificationState state = mPendingVerification.get(id);
14541 final PackageVerificationResponse response = new PackageVerificationResponse(
14542 verificationCodeAtTimeout, Binder.getCallingUid());
14544 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
14545 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
14547 if (millisecondsToDelay < 0) {
14548 millisecondsToDelay = 0;
14550 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
14551 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
14552 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
14555 if ((state != null) && !state.timeoutExtended()) {
14556 state.extendTimeout();
14558 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
14560 msg.obj = response;
14561 mHandler.sendMessageDelayed(msg, millisecondsToDelay);
14565 private void broadcastPackageVerified(int verificationId, Uri packageUri,
14566 int verificationCode, UserHandle user) {
14567 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
14568 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
14569 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
14570 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
14571 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
14573 mContext.sendBroadcastAsUser(intent, user,
14574 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
14577 private ComponentName matchComponentForVerifier(String packageName,
14578 List<ResolveInfo> receivers) {
14579 ActivityInfo targetReceiver = null;
14581 final int NR = receivers.size();
14582 for (int i = 0; i < NR; i++) {
14583 final ResolveInfo info = receivers.get(i);
14584 if (info.activityInfo == null) {
14588 if (packageName.equals(info.activityInfo.packageName)) {
14589 targetReceiver = info.activityInfo;
14594 if (targetReceiver == null) {
14598 return new ComponentName(targetReceiver.packageName, targetReceiver.name);
14601 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
14602 List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
14603 if (pkgInfo.verifiers.length == 0) {
14607 final int N = pkgInfo.verifiers.length;
14608 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
14609 for (int i = 0; i < N; i++) {
14610 final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
14612 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
14614 if (comp == null) {
14618 final int verifierUid = getUidForVerifier(verifierInfo);
14619 if (verifierUid == -1) {
14623 if (DEBUG_VERIFY) {
14624 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
14625 + " with the correct signature");
14627 sufficientVerifiers.add(comp);
14628 verificationState.addSufficientVerifier(verifierUid);
14631 return sufficientVerifiers;
14634 private int getUidForVerifier(VerifierInfo verifierInfo) {
14635 synchronized (mPackages) {
14636 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
14639 } else if (pkg.mSigningDetails.signatures.length != 1) {
14640 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
14641 + " has more than one signature; ignoring");
14646 * If the public key of the package's signature does not match
14647 * our expected public key, then this is a different package and
14651 final byte[] expectedPublicKey;
14653 final Signature verifierSig = pkg.mSigningDetails.signatures[0];
14654 final PublicKey publicKey = verifierSig.getPublicKey();
14655 expectedPublicKey = publicKey.getEncoded();
14656 } catch (CertificateException e) {
14660 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
14662 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
14663 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
14664 + " does not have the expected public key; ignoring");
14668 return pkg.applicationInfo.uid;
14673 public void finishPackageInstall(int token, boolean didLaunch) {
14674 enforceSystemOrRoot("Only the system is allowed to finish installs");
14676 if (DEBUG_INSTALL) {
14677 Slog.v(TAG, "BM finishing package install for " + token);
14679 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
14681 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
14682 mHandler.sendMessage(msg);
14686 * Get the verification agent timeout. Used for both the APK verifier and the
14687 * intent filter verifier.
14689 * @return verification timeout in milliseconds
14691 private long getVerificationTimeout() {
14692 return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
14693 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
14694 DEFAULT_VERIFICATION_TIMEOUT);
14698 * Get the default verification agent response code.
14700 * @return default verification response code
14702 private int getDefaultVerificationResponse(UserHandle user) {
14703 if (sUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS, user.getIdentifier())) {
14704 return PackageManager.VERIFICATION_REJECT;
14706 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14707 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
14708 DEFAULT_VERIFICATION_RESPONSE);
14712 * Check whether or not package verification has been enabled.
14714 * @return true if verification should be performed
14716 private boolean isVerificationEnabled(int userId, int installFlags, int installerUid) {
14717 if (!DEFAULT_VERIFY_ENABLE) {
14721 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
14723 // Check if installing from ADB
14724 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
14725 // Do not run verification in a test harness environment
14726 if (ActivityManager.isRunningInTestHarness()) {
14729 if (ensureVerifyAppsEnabled) {
14732 // Check if the developer does not want package verification for ADB installs
14733 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14734 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
14738 // only when not installed from ADB, skip verification for instant apps when
14739 // the installer and verifier are the same.
14740 if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
14741 if (mInstantAppInstallerActivity != null
14742 && mInstantAppInstallerActivity.packageName.equals(
14743 mRequiredVerifierPackage)) {
14745 mContext.getSystemService(AppOpsManager.class)
14746 .checkPackage(installerUid, mRequiredVerifierPackage);
14747 if (DEBUG_VERIFY) {
14748 Slog.i(TAG, "disable verification for instant app");
14751 } catch (SecurityException ignore) { }
14756 if (ensureVerifyAppsEnabled) {
14760 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14761 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
14765 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
14766 throws RemoteException {
14767 mContext.enforceCallingOrSelfPermission(
14768 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
14769 "Only intentfilter verification agents can verify applications");
14771 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
14772 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
14773 Binder.getCallingUid(), verificationCode, failedDomains);
14775 msg.obj = response;
14776 mHandler.sendMessage(msg);
14780 public int getIntentVerificationStatus(String packageName, int userId) {
14781 final int callingUid = Binder.getCallingUid();
14782 if (UserHandle.getUserId(callingUid) != userId) {
14783 mContext.enforceCallingOrSelfPermission(
14784 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
14785 "getIntentVerificationStatus" + userId);
14787 if (getInstantAppPackageName(callingUid) != null) {
14788 return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
14790 synchronized (mPackages) {
14791 final PackageSetting ps = mSettings.mPackages.get(packageName);
14793 || filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
14794 return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
14796 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
14801 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
14802 mContext.enforceCallingOrSelfPermission(
14803 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14805 boolean result = false;
14806 synchronized (mPackages) {
14807 final PackageSetting ps = mSettings.mPackages.get(packageName);
14808 if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
14811 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
14814 scheduleWritePackageRestrictionsLocked(userId);
14820 public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
14821 String packageName) {
14822 final int callingUid = Binder.getCallingUid();
14823 if (getInstantAppPackageName(callingUid) != null) {
14824 return ParceledListSlice.emptyList();
14826 synchronized (mPackages) {
14827 final PackageSetting ps = mSettings.mPackages.get(packageName);
14828 if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
14829 return ParceledListSlice.emptyList();
14831 return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
14836 public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
14837 if (TextUtils.isEmpty(packageName)) {
14838 return ParceledListSlice.emptyList();
14840 final int callingUid = Binder.getCallingUid();
14841 final int callingUserId = UserHandle.getUserId(callingUid);
14842 synchronized (mPackages) {
14843 PackageParser.Package pkg = mPackages.get(packageName);
14844 if (pkg == null || pkg.activities == null) {
14845 return ParceledListSlice.emptyList();
14847 if (pkg.mExtras == null) {
14848 return ParceledListSlice.emptyList();
14850 final PackageSetting ps = (PackageSetting) pkg.mExtras;
14851 if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
14852 return ParceledListSlice.emptyList();
14854 final int count = pkg.activities.size();
14855 ArrayList<IntentFilter> result = new ArrayList<>();
14856 for (int n=0; n<count; n++) {
14857 PackageParser.Activity activity = pkg.activities.get(n);
14858 if (activity.intents != null && activity.intents.size() > 0) {
14859 result.addAll(activity.intents);
14862 return new ParceledListSlice<>(result);
14867 public boolean setDefaultBrowserPackageName(String packageName, int userId) {
14868 mContext.enforceCallingOrSelfPermission(
14869 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14870 if (UserHandle.getCallingUserId() != userId) {
14871 mContext.enforceCallingOrSelfPermission(
14872 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
14875 synchronized (mPackages) {
14876 boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
14877 if (packageName != null) {
14878 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowser(
14879 packageName, userId);
14886 public String getDefaultBrowserPackageName(int userId) {
14887 if (UserHandle.getCallingUserId() != userId) {
14888 mContext.enforceCallingOrSelfPermission(
14889 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
14891 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14894 synchronized (mPackages) {
14895 return mSettings.getDefaultBrowserPackageNameLPw(userId);
14900 * Get the "allow unknown sources" setting.
14902 * @return the current "allow unknown sources" setting
14904 private int getUnknownSourcesSettings() {
14905 return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
14906 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
14911 public void setInstallerPackageName(String targetPackage, String installerPackageName) {
14912 final int callingUid = Binder.getCallingUid();
14913 if (getInstantAppPackageName(callingUid) != null) {
14917 synchronized (mPackages) {
14918 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
14919 if (targetPackageSetting == null
14920 || filterAppAccessLPr(
14921 targetPackageSetting, callingUid, UserHandle.getUserId(callingUid))) {
14922 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
14925 PackageSetting installerPackageSetting;
14926 if (installerPackageName != null) {
14927 installerPackageSetting = mSettings.mPackages.get(installerPackageName);
14928 if (installerPackageSetting == null) {
14929 throw new IllegalArgumentException("Unknown installer package: "
14930 + installerPackageName);
14933 installerPackageSetting = null;
14936 Signature[] callerSignature;
14937 Object obj = mSettings.getUserIdLPr(callingUid);
14939 if (obj instanceof SharedUserSetting) {
14941 ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
14942 } else if (obj instanceof PackageSetting) {
14943 callerSignature = ((PackageSetting)obj).signatures.mSigningDetails.signatures;
14945 throw new SecurityException("Bad object " + obj + " for uid " + callingUid);
14948 throw new SecurityException("Unknown calling UID: " + callingUid);
14951 // Verify: can't set installerPackageName to a package that is
14952 // not signed with the same cert as the caller.
14953 if (installerPackageSetting != null) {
14954 if (compareSignatures(callerSignature,
14955 installerPackageSetting.signatures.mSigningDetails.signatures)
14956 != PackageManager.SIGNATURE_MATCH) {
14957 throw new SecurityException(
14958 "Caller does not have same cert as new installer package "
14959 + installerPackageName);
14963 // Verify: if target already has an installer package, it must
14964 // be signed with the same cert as the caller.
14965 if (targetPackageSetting.installerPackageName != null) {
14966 PackageSetting setting = mSettings.mPackages.get(
14967 targetPackageSetting.installerPackageName);
14968 // If the currently set package isn't valid, then it's always
14969 // okay to change it.
14970 if (setting != null) {
14971 if (compareSignatures(callerSignature,
14972 setting.signatures.mSigningDetails.signatures)
14973 != PackageManager.SIGNATURE_MATCH) {
14974 throw new SecurityException(
14975 "Caller does not have same cert as old installer package "
14976 + targetPackageSetting.installerPackageName);
14982 targetPackageSetting.installerPackageName = installerPackageName;
14983 if (installerPackageName != null) {
14984 mSettings.mInstallerPackages.add(installerPackageName);
14986 scheduleWriteSettingsLocked();
14991 public void setApplicationCategoryHint(String packageName, int categoryHint,
14992 String callerPackageName) {
14993 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14994 throw new SecurityException("Instant applications don't have access to this method");
14996 mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
14997 callerPackageName);
14998 synchronized (mPackages) {
14999 PackageSetting ps = mSettings.mPackages.get(packageName);
15001 throw new IllegalArgumentException("Unknown target package " + packageName);
15003 if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
15004 throw new IllegalArgumentException("Unknown target package " + packageName);
15006 if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
15007 throw new IllegalArgumentException("Calling package " + callerPackageName
15008 + " is not installer for " + packageName);
15011 if (ps.categoryHint != categoryHint) {
15012 ps.categoryHint = categoryHint;
15013 scheduleWriteSettingsLocked();
15018 private void processPendingInstall(final InstallArgs args, final int currentStatus) {
15019 // Queue up an async operation since the package installation may take a little while.
15020 mHandler.post(new Runnable() {
15021 public void run() {
15022 mHandler.removeCallbacks(this);
15023 // Result object to be returned
15024 PackageInstalledInfo res = new PackageInstalledInfo();
15025 res.setReturnCode(currentStatus);
15028 res.removedInfo = null;
15029 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
15030 args.doPreInstall(res.returnCode);
15031 synchronized (mInstallLock) {
15032 installPackageTracedLI(args, res);
15034 args.doPostInstall(res.returnCode, res.uid);
15037 // A restore should be performed at this point if (a) the install
15038 // succeeded, (b) the operation is not an update, and (c) the new
15039 // package has not opted out of backup participation.
15040 final boolean update = res.removedInfo != null
15041 && res.removedInfo.removedPackage != null;
15042 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
15043 boolean doRestore = !update
15044 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
15046 // Set up the post-install work request bookkeeping. This will be used
15047 // and cleaned up by the post-install event handling regardless of whether
15048 // there's a restore pass performed. Token values are >= 1.
15050 if (mNextInstallToken < 0) mNextInstallToken = 1;
15051 token = mNextInstallToken++;
15053 PostInstallData data = new PostInstallData(args, res);
15054 mRunningInstalls.put(token, data);
15055 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
15057 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
15058 // Pass responsibility to the Backup Manager. It will perform a
15059 // restore if appropriate, then pass responsibility back to the
15060 // Package Manager to run the post-install observer callbacks
15062 IBackupManager bm = IBackupManager.Stub.asInterface(
15063 ServiceManager.getService(Context.BACKUP_SERVICE));
15065 if (DEBUG_INSTALL) Log.v(TAG, "token " + token
15066 + " to BM for possible restore");
15067 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
15069 // TODO: http://b/22388012
15070 if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
15071 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
15075 } catch (RemoteException e) {
15076 // can't happen; the backup manager is local
15077 } catch (Exception e) {
15078 Slog.e(TAG, "Exception trying to enqueue restore", e);
15082 Slog.e(TAG, "Backup Manager not found!");
15088 // No restore possible, or the Backup Manager was mysteriously not
15089 // available -- just fire the post-install work request directly.
15090 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
15092 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
15094 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
15095 mHandler.sendMessage(msg);
15102 * Callback from PackageSettings whenever an app is first transitioned out of the
15103 * 'stopped' state. Normally we just issue the broadcast, but we can't do that if
15104 * the app was "launched" for a restoreAtInstall operation. Therefore we check
15105 * here whether the app is the target of an ongoing install, and only send the
15106 * broadcast immediately if it is not in that state. If it *is* undergoing a restore,
15107 * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
15110 void notifyFirstLaunch(final String packageName, final String installerPackage,
15111 final int userId) {
15112 // Serialize this with the rest of the install-process message chain. In the
15113 // restore-at-install case, this Runnable will necessarily run before the
15114 // POST_INSTALL message is processed, so the contents of mRunningInstalls
15115 // are coherent. In the non-restore case, the app has already completed install
15116 // and been launched through some other means, so it is not in a problematic
15117 // state for observers to see the FIRST_LAUNCH signal.
15118 mHandler.post(new Runnable() {
15120 public void run() {
15121 for (int i = 0; i < mRunningInstalls.size(); i++) {
15122 final PostInstallData data = mRunningInstalls.valueAt(i);
15123 if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
15126 if (packageName.equals(data.res.pkg.applicationInfo.packageName)) {
15127 // right package; but is it for the right user?
15128 for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
15129 if (userId == data.res.newUsers[uIndex]) {
15130 if (DEBUG_BACKUP) {
15131 Slog.i(TAG, "Package " + packageName
15132 + " being restored so deferring FIRST_LAUNCH");
15139 // didn't find it, so not being restored
15140 if (DEBUG_BACKUP) {
15141 Slog.i(TAG, "Package " + packageName + " sending normal FIRST_LAUNCH");
15143 final boolean isInstantApp = isInstantApp(packageName, userId);
15144 final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
15145 final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
15146 sendFirstLaunchBroadcast(packageName, installerPackage, userIds, instantUserIds);
15151 private void sendFirstLaunchBroadcast(String pkgName, String installerPkg,
15152 int[] userIds, int[] instantUserIds) {
15153 sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
15154 installerPkg, null, userIds, instantUserIds);
15157 private abstract class HandlerParams {
15158 private static final int MAX_RETRIES = 4;
15161 * Number of times startCopy() has been attempted and had a non-fatal
15164 private int mRetries = 0;
15166 /** User handle for the user requesting the information or installation. */
15167 private final UserHandle mUser;
15168 String traceMethod;
15171 HandlerParams(UserHandle user) {
15175 UserHandle getUser() {
15179 HandlerParams setTraceMethod(String traceMethod) {
15180 this.traceMethod = traceMethod;
15184 HandlerParams setTraceCookie(int traceCookie) {
15185 this.traceCookie = traceCookie;
15189 final boolean startCopy() {
15192 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
15194 if (++mRetries > MAX_RETRIES) {
15195 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
15196 mHandler.sendEmptyMessage(MCS_GIVE_UP);
15197 handleServiceError();
15203 } catch (RemoteException e) {
15204 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
15205 mHandler.sendEmptyMessage(MCS_RECONNECT);
15208 handleReturnCode();
15212 final void serviceError() {
15213 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
15214 handleServiceError();
15215 handleReturnCode();
15218 abstract void handleStartCopy() throws RemoteException;
15219 abstract void handleServiceError();
15220 abstract void handleReturnCode();
15223 private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
15224 for (File path : paths) {
15226 mcs.clearDirectory(path.getAbsolutePath());
15227 } catch (RemoteException e) {
15232 static class OriginInfo {
15234 * Location where install is coming from, before it has been
15235 * copied/renamed into place. This could be a single monolithic APK
15236 * file, or a cluster directory. This location may be untrusted.
15241 * Flag indicating that {@link #file} or {@link #cid} has already been
15242 * staged, meaning downstream users don't need to defensively copy the
15245 final boolean staged;
15248 * Flag indicating that {@link #file} or {@link #cid} is an already
15249 * installed app that is being moved.
15251 final boolean existing;
15253 final String resolvedPath;
15254 final File resolvedFile;
15256 static OriginInfo fromNothing() {
15257 return new OriginInfo(null, false, false);
15260 static OriginInfo fromUntrustedFile(File file) {
15261 return new OriginInfo(file, false, false);
15264 static OriginInfo fromExistingFile(File file) {
15265 return new OriginInfo(file, false, true);
15268 static OriginInfo fromStagedFile(File file) {
15269 return new OriginInfo(file, true, false);
15272 private OriginInfo(File file, boolean staged, boolean existing) {
15274 this.staged = staged;
15275 this.existing = existing;
15277 if (file != null) {
15278 resolvedPath = file.getAbsolutePath();
15279 resolvedFile = file;
15281 resolvedPath = null;
15282 resolvedFile = null;
15287 static class MoveInfo {
15289 final String fromUuid;
15290 final String toUuid;
15291 final String packageName;
15292 final String dataAppName;
15294 final String seinfo;
15295 final int targetSdkVersion;
15297 public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
15298 String dataAppName, int appId, String seinfo, int targetSdkVersion) {
15299 this.moveId = moveId;
15300 this.fromUuid = fromUuid;
15301 this.toUuid = toUuid;
15302 this.packageName = packageName;
15303 this.dataAppName = dataAppName;
15304 this.appId = appId;
15305 this.seinfo = seinfo;
15306 this.targetSdkVersion = targetSdkVersion;
15310 static class VerificationInfo {
15311 /** A constant used to indicate that a uid value is not present. */
15312 public static final int NO_UID = -1;
15314 /** URI referencing where the package was downloaded from. */
15315 final Uri originatingUri;
15317 /** HTTP referrer URI associated with the originatingURI. */
15318 final Uri referrer;
15320 /** UID of the application that the install request originated from. */
15321 final int originatingUid;
15323 /** UID of application requesting the install */
15324 final int installerUid;
15326 VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
15327 this.originatingUri = originatingUri;
15328 this.referrer = referrer;
15329 this.originatingUid = originatingUid;
15330 this.installerUid = installerUid;
15334 class InstallParams extends HandlerParams {
15335 final OriginInfo origin;
15336 final MoveInfo move;
15337 final IPackageInstallObserver2 observer;
15339 final String installerPackageName;
15340 final String volumeUuid;
15341 private InstallArgs mArgs;
15343 final String packageAbiOverride;
15344 final String[] grantedRuntimePermissions;
15345 final VerificationInfo verificationInfo;
15346 final PackageParser.SigningDetails signingDetails;
15347 final int installReason;
15349 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
15350 int installFlags, String installerPackageName, String volumeUuid,
15351 VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
15352 String[] grantedPermissions, PackageParser.SigningDetails signingDetails, int installReason) {
15354 this.origin = origin;
15356 this.observer = observer;
15357 this.installFlags = installFlags;
15358 this.installerPackageName = installerPackageName;
15359 this.volumeUuid = volumeUuid;
15360 this.verificationInfo = verificationInfo;
15361 this.packageAbiOverride = packageAbiOverride;
15362 this.grantedRuntimePermissions = grantedPermissions;
15363 this.signingDetails = signingDetails;
15364 this.installReason = installReason;
15368 public String toString() {
15369 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
15370 + " file=" + origin.file + "}";
15373 private int installLocationPolicy(PackageInfoLite pkgLite) {
15374 String packageName = pkgLite.packageName;
15375 int installLocation = pkgLite.installLocation;
15376 boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15378 synchronized (mPackages) {
15379 // Currently installed package which the new package is attempting to replace or
15380 // null if no such package is installed.
15381 PackageParser.Package installedPkg = mPackages.get(packageName);
15382 // Package which currently owns the data which the new package will own if installed.
15383 // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
15384 // will be null whereas dataOwnerPkg will contain information about the package
15385 // which was uninstalled while keeping its data.
15386 PackageParser.Package dataOwnerPkg = installedPkg;
15387 if (dataOwnerPkg == null) {
15388 PackageSetting ps = mSettings.mPackages.get(packageName);
15390 dataOwnerPkg = ps.pkg;
15394 if (dataOwnerPkg != null) {
15395 // If installed, the package will get access to data left on the device by its
15396 // predecessor. As a security measure, this is permited only if this is not a
15397 // version downgrade or if the predecessor package is marked as debuggable and
15398 // a downgrade is explicitly requested.
15400 // On debuggable platform builds, downgrades are permitted even for
15401 // non-debuggable packages to make testing easier. Debuggable platform builds do
15402 // not offer security guarantees and thus it's OK to disable some security
15403 // mechanisms to make debugging/testing easier on those builds. However, even on
15404 // debuggable builds downgrades of packages are permitted only if requested via
15405 // installFlags. This is because we aim to keep the behavior of debuggable
15406 // platform builds as close as possible to the behavior of non-debuggable
15407 // platform builds.
15408 final boolean downgradeRequested =
15409 (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
15410 final boolean packageDebuggable =
15411 (dataOwnerPkg.applicationInfo.flags
15412 & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
15413 final boolean downgradePermitted =
15414 (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
15415 if (!downgradePermitted) {
15417 checkDowngrade(dataOwnerPkg, pkgLite);
15418 } catch (PackageManagerException e) {
15419 Slog.w(TAG, "Downgrade detected: " + e.getMessage());
15420 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
15425 if (installedPkg != null) {
15426 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
15427 // Check for updated system application.
15428 if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
15430 Slog.w(TAG, "Cannot install update to system app on sdcard");
15431 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
15433 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15436 // Install flag overrides everything.
15437 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15439 // If current upgrade specifies particular preference
15440 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
15441 // Application explicitly specified internal.
15442 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15443 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
15444 // App explictly prefers external. Let policy decide
15446 // Prefer previous location
15447 if (isExternal(installedPkg)) {
15448 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15450 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15454 // Invalid install. Return error code
15455 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
15459 // All the special cases have been taken care of.
15460 // Return result based on recommended install location.
15462 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15464 return pkgLite.recommendedInstallLocation;
15468 * Invoke remote method to get package information and install
15469 * location values. Override install location based on default
15470 * policy if needed and then create install arguments based
15471 * on the install location.
15473 public void handleStartCopy() throws RemoteException {
15474 int ret = PackageManager.INSTALL_SUCCEEDED;
15476 // If we're already staged, we've firmly committed to an install location
15477 if (origin.staged) {
15478 if (origin.file != null) {
15479 installFlags |= PackageManager.INSTALL_INTERNAL;
15480 installFlags &= ~PackageManager.INSTALL_EXTERNAL;
15482 throw new IllegalStateException("Invalid stage location");
15486 final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15487 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
15488 final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15489 PackageInfoLite pkgLite = null;
15491 if (onInt && onSd) {
15492 // Check if both bits are set.
15493 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
15494 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15495 } else if (onSd && ephemeral) {
15496 Slog.w(TAG, "Conflicting flags specified for installing ephemeral on external");
15497 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15499 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
15500 packageAbiOverride);
15502 if (DEBUG_INSTANT && ephemeral) {
15503 Slog.v(TAG, "pkgLite for install: " + pkgLite);
15507 * If we have too little free space, try to free cache
15508 * before giving up.
15510 if (!origin.staged && pkgLite.recommendedInstallLocation
15511 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
15512 // TODO: focus freeing disk space on the target device
15513 final StorageManager storage = StorageManager.from(mContext);
15514 final long lowThreshold = storage.getStorageLowBytes(
15515 Environment.getDataDirectory());
15517 final long sizeBytes = mContainerService.calculateInstalledSize(
15518 origin.resolvedPath, packageAbiOverride);
15521 mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);
15522 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
15523 installFlags, packageAbiOverride);
15524 } catch (InstallerException e) {
15525 Slog.w(TAG, "Failed to free cache", e);
15529 * The cache free must have deleted the file we
15530 * downloaded to install.
15532 * TODO: fix the "freeCache" call to not delete
15533 * the file we care about.
15535 if (pkgLite.recommendedInstallLocation
15536 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
15537 pkgLite.recommendedInstallLocation
15538 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
15543 if (ret == PackageManager.INSTALL_SUCCEEDED) {
15544 int loc = pkgLite.recommendedInstallLocation;
15545 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
15546 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15547 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
15548 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
15549 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
15550 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15551 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
15552 ret = PackageManager.INSTALL_FAILED_INVALID_APK;
15553 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
15554 ret = PackageManager.INSTALL_FAILED_INVALID_URI;
15555 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
15556 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
15558 // Override with defaults if needed.
15559 loc = installLocationPolicy(pkgLite);
15560 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
15561 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
15562 } else if (!onSd && !onInt) {
15563 // Override install location with flags
15564 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
15565 // Set the flag to install on external media.
15566 installFlags |= PackageManager.INSTALL_EXTERNAL;
15567 installFlags &= ~PackageManager.INSTALL_INTERNAL;
15568 } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
15569 if (DEBUG_INSTANT) {
15570 Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
15572 installFlags |= PackageManager.INSTALL_INSTANT_APP;
15573 installFlags &= ~(PackageManager.INSTALL_EXTERNAL
15574 |PackageManager.INSTALL_INTERNAL);
15576 // Make sure the flag for installing on external
15578 installFlags |= PackageManager.INSTALL_INTERNAL;
15579 installFlags &= ~PackageManager.INSTALL_EXTERNAL;
15585 final InstallArgs args = createInstallArgs(this);
15588 if (ret == PackageManager.INSTALL_SUCCEEDED) {
15589 // TODO: http://b/22976637
15590 // Apps installed for "all" users use the device owner to verify the app
15591 UserHandle verifierUser = getUser();
15592 if (verifierUser == UserHandle.ALL) {
15593 verifierUser = UserHandle.SYSTEM;
15597 * Determine if we have any installed package verifiers. If we
15598 * do, then we'll defer to them to verify the packages.
15600 final int requiredUid = mRequiredVerifierPackage == null ? -1
15601 : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
15602 verifierUser.getIdentifier());
15603 final int installerUid =
15604 verificationInfo == null ? -1 : verificationInfo.installerUid;
15605 if (!origin.existing && requiredUid != -1
15606 && isVerificationEnabled(
15607 verifierUser.getIdentifier(), installFlags, installerUid)) {
15608 final Intent verification = new Intent(
15609 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
15610 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15611 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
15612 PACKAGE_MIME_TYPE);
15613 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
15615 // Query all live verifiers based on current user state
15616 final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
15617 PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier(),
15618 false /*allowDynamicSplits*/);
15620 if (DEBUG_VERIFY) {
15621 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
15622 + verification.toString() + " with " + pkgLite.verifiers.length
15623 + " optional verifiers");
15626 final int verificationId = mPendingVerificationToken++;
15628 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
15630 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
15631 installerPackageName);
15633 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
15636 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
15637 pkgLite.packageName);
15639 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
15640 pkgLite.versionCode);
15642 verification.putExtra(PackageManager.EXTRA_VERIFICATION_LONG_VERSION_CODE,
15643 pkgLite.getLongVersionCode());
15645 if (verificationInfo != null) {
15646 if (verificationInfo.originatingUri != null) {
15647 verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
15648 verificationInfo.originatingUri);
15650 if (verificationInfo.referrer != null) {
15651 verification.putExtra(Intent.EXTRA_REFERRER,
15652 verificationInfo.referrer);
15654 if (verificationInfo.originatingUid >= 0) {
15655 verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
15656 verificationInfo.originatingUid);
15658 if (verificationInfo.installerUid >= 0) {
15659 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
15660 verificationInfo.installerUid);
15664 final PackageVerificationState verificationState = new PackageVerificationState(
15665 requiredUid, args);
15667 mPendingVerification.append(verificationId, verificationState);
15669 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
15670 receivers, verificationState);
15672 DeviceIdleController.LocalService idleController = getDeviceIdleController();
15673 final long idleDuration = getVerificationTimeout();
15676 * If any sufficient verifiers were listed in the package
15677 * manifest, attempt to ask them.
15679 if (sufficientVerifiers != null) {
15680 final int N = sufficientVerifiers.size();
15682 Slog.i(TAG, "Additional verifiers required, but none installed.");
15683 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
15685 for (int i = 0; i < N; i++) {
15686 final ComponentName verifierComponent = sufficientVerifiers.get(i);
15687 idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
15688 verifierComponent.getPackageName(), idleDuration,
15689 verifierUser.getIdentifier(), false, "package verifier");
15691 final Intent sufficientIntent = new Intent(verification);
15692 sufficientIntent.setComponent(verifierComponent);
15693 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
15698 final ComponentName requiredVerifierComponent = matchComponentForVerifier(
15699 mRequiredVerifierPackage, receivers);
15700 if (ret == PackageManager.INSTALL_SUCCEEDED
15701 && mRequiredVerifierPackage != null) {
15702 Trace.asyncTraceBegin(
15703 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
15705 * Send the intent to the required verification agent,
15706 * but only start the verification timeout after the
15707 * target BroadcastReceivers have run.
15709 verification.setComponent(requiredVerifierComponent);
15710 idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
15711 mRequiredVerifierPackage, idleDuration,
15712 verifierUser.getIdentifier(), false, "package verifier");
15713 mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
15714 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
15715 new BroadcastReceiver() {
15717 public void onReceive(Context context, Intent intent) {
15718 final Message msg = mHandler
15719 .obtainMessage(CHECK_PENDING_VERIFICATION);
15720 msg.arg1 = verificationId;
15721 mHandler.sendMessageDelayed(msg, getVerificationTimeout());
15723 }, null, 0, null, null);
15726 * We don't want the copy to proceed until verification
15727 * succeeds, so null out this field.
15733 * No package verification is enabled, so immediately start
15734 * the remote call to initiate copy using temporary file.
15736 ret = args.copyApk(mContainerService, true);
15744 void handleReturnCode() {
15745 // If mArgs is null, then MCS couldn't be reached. When it
15746 // reconnects, it will try again to install. At that point, this
15748 if (mArgs != null) {
15749 processPendingInstall(mArgs, mRet);
15754 void handleServiceError() {
15755 mArgs = createInstallArgs(this);
15756 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15760 private InstallArgs createInstallArgs(InstallParams params) {
15761 if (params.move != null) {
15762 return new MoveInstallArgs(params);
15764 return new FileInstallArgs(params);
15769 * Create args that describe an existing installed package. Typically used
15770 * when cleaning up old installs, or used as a move source.
15772 private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
15773 String resourcePath, String[] instructionSets) {
15774 return new FileInstallArgs(codePath, resourcePath, instructionSets);
15777 static abstract class InstallArgs {
15778 /** @see InstallParams#origin */
15779 final OriginInfo origin;
15780 /** @see InstallParams#move */
15781 final MoveInfo move;
15783 final IPackageInstallObserver2 observer;
15784 // Always refers to PackageManager flags only
15785 final int installFlags;
15786 final String installerPackageName;
15787 final String volumeUuid;
15788 final UserHandle user;
15789 final String abiOverride;
15790 final String[] installGrantPermissions;
15791 /** If non-null, drop an async trace when the install completes */
15792 final String traceMethod;
15793 final int traceCookie;
15794 final PackageParser.SigningDetails signingDetails;
15795 final int installReason;
15797 // The list of instruction sets supported by this app. This is currently
15798 // only used during the rmdex() phase to clean up resources. We can get rid of this
15799 // if we move dex files under the common app path.
15800 /* nullable */ String[] instructionSets;
15802 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
15803 int installFlags, String installerPackageName, String volumeUuid,
15804 UserHandle user, String[] instructionSets,
15805 String abiOverride, String[] installGrantPermissions,
15806 String traceMethod, int traceCookie, PackageParser.SigningDetails signingDetails,
15807 int installReason) {
15808 this.origin = origin;
15810 this.installFlags = installFlags;
15811 this.observer = observer;
15812 this.installerPackageName = installerPackageName;
15813 this.volumeUuid = volumeUuid;
15815 this.instructionSets = instructionSets;
15816 this.abiOverride = abiOverride;
15817 this.installGrantPermissions = installGrantPermissions;
15818 this.traceMethod = traceMethod;
15819 this.traceCookie = traceCookie;
15820 this.signingDetails = signingDetails;
15821 this.installReason = installReason;
15824 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
15825 abstract int doPreInstall(int status);
15828 * Rename package into final resting place. All paths on the given
15829 * scanned package should be updated to reflect the rename.
15831 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
15832 abstract int doPostInstall(int status, int uid);
15834 /** @see PackageSettingBase#codePathString */
15835 abstract String getCodePath();
15836 /** @see PackageSettingBase#resourcePathString */
15837 abstract String getResourcePath();
15839 // Need installer lock especially for dex file removal.
15840 abstract void cleanUpResourcesLI();
15841 abstract boolean doPostDeleteLI(boolean delete);
15844 * Called before the source arguments are copied. This is used mostly
15845 * for MoveParams when it needs to read the source file to put it in the
15849 return PackageManager.INSTALL_SUCCEEDED;
15853 * Called after the source arguments are copied. This is used mostly for
15854 * MoveParams when it needs to read the source file to put it in the
15857 int doPostCopy(int uid) {
15858 return PackageManager.INSTALL_SUCCEEDED;
15861 protected boolean isFwdLocked() {
15862 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15865 protected boolean isExternalAsec() {
15866 return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15869 protected boolean isEphemeral() {
15870 return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15873 UserHandle getUser() {
15878 void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
15879 if (!allCodePaths.isEmpty()) {
15880 if (instructionSets == null) {
15881 throw new IllegalStateException("instructionSet == null");
15883 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
15884 for (String codePath : allCodePaths) {
15885 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
15887 mInstaller.rmdex(codePath, dexCodeInstructionSet);
15888 } catch (InstallerException ignored) {
15896 * Logic to handle installation of non-ASEC applications, including copying
15897 * and renaming logic.
15899 class FileInstallArgs extends InstallArgs {
15900 private File codeFile;
15901 private File resourceFile;
15903 // Example topology:
15904 // /data/app/com.example/base.apk
15905 // /data/app/com.example/split_foo.apk
15906 // /data/app/com.example/lib/arm/libfoo.so
15907 // /data/app/com.example/lib/arm64/libfoo.so
15908 // /data/app/com.example/dalvik/arm/base.apk@classes.dex
15911 FileInstallArgs(InstallParams params) {
15912 super(params.origin, params.move, params.observer, params.installFlags,
15913 params.installerPackageName, params.volumeUuid,
15914 params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
15915 params.grantedRuntimePermissions,
15916 params.traceMethod, params.traceCookie, params.signingDetails,
15917 params.installReason);
15918 if (isFwdLocked()) {
15919 throw new IllegalArgumentException("Forward locking only supported in ASEC");
15923 /** Existing install */
15924 FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
15925 super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
15926 null, null, null, 0, PackageParser.SigningDetails.UNKNOWN,
15927 PackageManager.INSTALL_REASON_UNKNOWN);
15928 this.codeFile = (codePath != null) ? new File(codePath) : null;
15929 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
15932 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15933 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
15935 return doCopyApk(imcs, temp);
15937 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15941 private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15942 if (origin.staged) {
15943 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
15944 codeFile = origin.file;
15945 resourceFile = origin.file;
15946 return PackageManager.INSTALL_SUCCEEDED;
15950 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15951 final File tempDir =
15952 mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
15953 codeFile = tempDir;
15954 resourceFile = tempDir;
15955 } catch (IOException e) {
15956 Slog.w(TAG, "Failed to create copy file: " + e);
15957 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15960 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
15962 public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
15963 if (!FileUtils.isValidExtFilename(name)) {
15964 throw new IllegalArgumentException("Invalid filename: " + name);
15967 final File file = new File(codeFile, name);
15968 final FileDescriptor fd = Os.open(file.getAbsolutePath(),
15969 O_RDWR | O_CREAT, 0644);
15970 Os.chmod(file.getAbsolutePath(), 0644);
15971 return new ParcelFileDescriptor(fd);
15972 } catch (ErrnoException e) {
15973 throw new RemoteException("Failed to open: " + e.getMessage());
15978 int ret = PackageManager.INSTALL_SUCCEEDED;
15979 ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
15980 if (ret != PackageManager.INSTALL_SUCCEEDED) {
15981 Slog.e(TAG, "Failed to copy package");
15985 final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
15986 NativeLibraryHelper.Handle handle = null;
15988 handle = NativeLibraryHelper.Handle.create(codeFile);
15989 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
15991 } catch (IOException e) {
15992 Slog.e(TAG, "Copying native libraries failed", e);
15993 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15995 IoUtils.closeQuietly(handle);
16001 int doPreInstall(int status) {
16002 if (status != PackageManager.INSTALL_SUCCEEDED) {
16008 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
16009 if (status != PackageManager.INSTALL_SUCCEEDED) {
16014 final File targetDir = codeFile.getParentFile();
16015 final File beforeCodeFile = codeFile;
16016 final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
16018 if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
16020 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
16021 } catch (ErrnoException e) {
16022 Slog.w(TAG, "Failed to rename", e);
16026 if (!SELinux.restoreconRecursive(afterCodeFile)) {
16027 Slog.w(TAG, "Failed to restorecon");
16031 // Reflect the rename internally
16032 codeFile = afterCodeFile;
16033 resourceFile = afterCodeFile;
16035 // Reflect the rename in scanned details
16037 pkg.setCodePath(afterCodeFile.getCanonicalPath());
16038 } catch (IOException e) {
16039 Slog.e(TAG, "Failed to get path: " + afterCodeFile, e);
16042 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
16043 afterCodeFile, pkg.baseCodePath));
16044 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
16045 afterCodeFile, pkg.splitCodePaths));
16047 // Reflect the rename in app info
16048 pkg.setApplicationVolumeUuid(pkg.volumeUuid);
16049 pkg.setApplicationInfoCodePath(pkg.codePath);
16050 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
16051 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
16052 pkg.setApplicationInfoResourcePath(pkg.codePath);
16053 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
16054 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
16059 int doPostInstall(int status, int uid) {
16060 if (status != PackageManager.INSTALL_SUCCEEDED) {
16067 String getCodePath() {
16068 return (codeFile != null) ? codeFile.getAbsolutePath() : null;
16072 String getResourcePath() {
16073 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
16076 private boolean cleanUp() {
16077 if (codeFile == null || !codeFile.exists()) {
16081 removeCodePathLI(codeFile);
16083 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
16084 resourceFile.delete();
16090 void cleanUpResourcesLI() {
16091 // Try enumerating all code paths before deleting
16092 List<String> allCodePaths = Collections.EMPTY_LIST;
16093 if (codeFile != null && codeFile.exists()) {
16095 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
16096 allCodePaths = pkg.getAllCodePaths();
16097 } catch (PackageParserException e) {
16098 // Ignored; we tried our best
16103 removeDexFiles(allCodePaths, instructionSets);
16106 boolean doPostDeleteLI(boolean delete) {
16107 // XXX err, shouldn't we respect the delete flag?
16108 cleanUpResourcesLI();
16113 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
16114 PackageManagerException {
16116 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
16117 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
16118 throw new PackageManagerException(copyRet, message);
16124 * Extract the StorageManagerService "container ID" from the full code path of an
16127 static String cidFromCodePath(String fullCodePath) {
16128 int eidx = fullCodePath.lastIndexOf("/");
16129 String subStr1 = fullCodePath.substring(0, eidx);
16130 int sidx = subStr1.lastIndexOf("/");
16131 return subStr1.substring(sidx+1, eidx);
16135 * Logic to handle movement of existing installed applications.
16137 class MoveInstallArgs extends InstallArgs {
16138 private File codeFile;
16139 private File resourceFile;
16142 MoveInstallArgs(InstallParams params) {
16143 super(params.origin, params.move, params.observer, params.installFlags,
16144 params.installerPackageName, params.volumeUuid,
16145 params.getUser(), null /* instruction sets */, params.packageAbiOverride,
16146 params.grantedRuntimePermissions,
16147 params.traceMethod, params.traceCookie, params.signingDetails,
16148 params.installReason);
16151 int copyApk(IMediaContainerService imcs, boolean temp) {
16152 if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
16153 + move.fromUuid + " to " + move.toUuid);
16154 synchronized (mInstaller) {
16156 mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
16157 move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
16158 } catch (InstallerException e) {
16159 Slog.w(TAG, "Failed to move app", e);
16160 return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
16164 codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
16165 resourceFile = codeFile;
16166 if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
16168 return PackageManager.INSTALL_SUCCEEDED;
16171 int doPreInstall(int status) {
16172 if (status != PackageManager.INSTALL_SUCCEEDED) {
16173 cleanUp(move.toUuid);
16178 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
16179 if (status != PackageManager.INSTALL_SUCCEEDED) {
16180 cleanUp(move.toUuid);
16184 // Reflect the move in app info
16185 pkg.setApplicationVolumeUuid(pkg.volumeUuid);
16186 pkg.setApplicationInfoCodePath(pkg.codePath);
16187 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
16188 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
16189 pkg.setApplicationInfoResourcePath(pkg.codePath);
16190 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
16191 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
16196 int doPostInstall(int status, int uid) {
16197 if (status == PackageManager.INSTALL_SUCCEEDED) {
16198 cleanUp(move.fromUuid);
16200 cleanUp(move.toUuid);
16206 String getCodePath() {
16207 return (codeFile != null) ? codeFile.getAbsolutePath() : null;
16211 String getResourcePath() {
16212 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
16215 private boolean cleanUp(String volumeUuid) {
16216 final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
16218 Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
16219 final int[] userIds = sUserManager.getUserIds();
16220 synchronized (mInstallLock) {
16221 // Clean up both app data and code
16222 // All package moves are frozen until finished
16223 for (int userId : userIds) {
16225 mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
16226 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
16227 } catch (InstallerException e) {
16228 Slog.w(TAG, String.valueOf(e));
16231 removeCodePathLI(codeFile);
16236 void cleanUpResourcesLI() {
16237 throw new UnsupportedOperationException();
16240 boolean doPostDeleteLI(boolean delete) {
16241 throw new UnsupportedOperationException();
16245 static String getAsecPackageName(String packageCid) {
16246 int idx = packageCid.lastIndexOf("-");
16250 return packageCid.substring(0, idx);
16253 // Utility method used to create code paths based on package name and available index.
16254 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
16255 String idxStr = "";
16257 // Fall back to default value of idx=1 if prefix is not
16258 // part of oldCodePath
16259 if (oldCodePath != null) {
16260 String subStr = oldCodePath;
16261 // Drop the suffix right away
16262 if (suffix != null && subStr.endsWith(suffix)) {
16263 subStr = subStr.substring(0, subStr.length() - suffix.length());
16265 // If oldCodePath already contains prefix find out the
16266 // ending index to either increment or decrement.
16267 int sidx = subStr.lastIndexOf(prefix);
16269 subStr = subStr.substring(sidx + prefix.length());
16270 if (subStr != null) {
16271 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
16272 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
16275 idx = Integer.parseInt(subStr);
16281 } catch(NumberFormatException e) {
16286 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
16287 return prefix + idxStr;
16290 private File getNextCodePath(File targetDir, String packageName) {
16292 SecureRandom random = new SecureRandom();
16293 byte[] bytes = new byte[16];
16295 random.nextBytes(bytes);
16296 String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
16297 result = new File(targetDir, packageName + "-" + suffix);
16298 } while (result.exists());
16302 // Utility method that returns the relative package path with respect
16303 // to the installation directory. Like say for /data/data/com.test-1.apk
16304 // string com.test-1 is returned.
16305 static String deriveCodePathName(String codePath) {
16306 if (codePath == null) {
16309 final File codeFile = new File(codePath);
16310 final String name = codeFile.getName();
16311 if (codeFile.isDirectory()) {
16313 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
16314 final int lastDot = name.lastIndexOf('.');
16315 return name.substring(0, lastDot);
16317 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
16322 static class PackageInstalledInfo {
16325 // The set of users that originally had this package installed.
16327 // The set of users that now have this package installed.
16329 PackageParser.Package pkg;
16332 String installerPackageName;
16333 PackageRemovedInfo removedInfo;
16334 ArrayMap<String, PackageInstalledInfo> addedChildPackages;
16336 public void setError(int code, String msg) {
16337 setReturnCode(code);
16338 setReturnMessage(msg);
16342 public void setError(String msg, PackageParserException e) {
16343 setReturnCode(e.error);
16344 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
16345 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
16346 for (int i = 0; i < childCount; i++) {
16347 addedChildPackages.valueAt(i).setError(msg, e);
16349 Slog.w(TAG, msg, e);
16352 public void setError(String msg, PackageManagerException e) {
16353 returnCode = e.error;
16354 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
16355 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
16356 for (int i = 0; i < childCount; i++) {
16357 addedChildPackages.valueAt(i).setError(msg, e);
16359 Slog.w(TAG, msg, e);
16362 public void setReturnCode(int returnCode) {
16363 this.returnCode = returnCode;
16364 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
16365 for (int i = 0; i < childCount; i++) {
16366 addedChildPackages.valueAt(i).returnCode = returnCode;
16370 private void setReturnMessage(String returnMsg) {
16371 this.returnMsg = returnMsg;
16372 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
16373 for (int i = 0; i < childCount; i++) {
16374 addedChildPackages.valueAt(i).returnMsg = returnMsg;
16378 // In some error cases we want to convey more info back to the observer
16379 String origPackage;
16380 String origPermission;
16384 * Install a non-existing package.
16386 private void installNewPackageLIF(PackageParser.Package pkg, final @ParseFlags int parseFlags,
16387 final @ScanFlags int scanFlags, UserHandle user, String installerPackageName,
16388 String volumeUuid, PackageInstalledInfo res, int installReason) {
16389 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
16391 // Remember this for later, in case we need to rollback this install
16392 String pkgName = pkg.packageName;
16394 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
16396 synchronized(mPackages) {
16397 final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName);
16398 if (renamedPackage != null) {
16399 // A package with the same name is already installed, though
16400 // it has been renamed to an older name. The package we
16401 // are trying to install should be installed as an update to
16402 // the existing one, but that has not been requested, so bail.
16403 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
16404 + " without first uninstalling package running as "
16408 if (mPackages.containsKey(pkgName)) {
16409 // Don't allow installation over an existing package with the same name.
16410 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
16411 + " without first uninstalling.");
16417 PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags,
16418 System.currentTimeMillis(), user);
16420 updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
16422 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16423 prepareAppDataAfterInstallLIF(newPackage);
16426 // Remove package from internal structures, but keep around any
16427 // data that might have already existed
16428 deletePackageLIF(pkgName, UserHandle.ALL, false, null,
16429 PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
16431 } catch (PackageManagerException e) {
16432 res.setError("Package couldn't be installed in " + pkg.codePath, e);
16435 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16438 private static void updateDigest(MessageDigest digest, File file) throws IOException {
16439 try (DigestInputStream digestStream =
16440 new DigestInputStream(new FileInputStream(file), digest)) {
16441 while (digestStream.read() != -1) {} // nothing to do; just plow through the file
16445 private void replacePackageLIF(PackageParser.Package pkg, final @ParseFlags int parseFlags,
16446 final @ScanFlags int scanFlags, UserHandle user, String installerPackageName,
16447 PackageInstalledInfo res, int installReason) {
16448 final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
16450 final PackageParser.Package oldPackage;
16451 final PackageSetting ps;
16452 final String pkgName = pkg.packageName;
16453 final int[] allUsers;
16454 final int[] installedUsers;
16456 synchronized(mPackages) {
16457 oldPackage = mPackages.get(pkgName);
16458 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
16460 // don't allow upgrade to target a release SDK from a pre-release SDK
16461 final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
16462 == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
16463 final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
16464 == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
16465 if (oldTargetsPreRelease
16466 && !newTargetsPreRelease
16467 && ((parseFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
16468 Slog.w(TAG, "Can't install package targeting released sdk");
16469 res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
16473 ps = mSettings.mPackages.get(pkgName);
16475 // verify signatures are valid
16476 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
16477 if (ksms.shouldCheckUpgradeKeySetLocked(ps, scanFlags)) {
16478 if (!ksms.checkUpgradeKeySetLocked(ps, pkg)) {
16479 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16480 "New package not signed by keys specified by upgrade-keysets: "
16486 // default to original signature matching
16487 if (!pkg.mSigningDetails.checkCapability(oldPackage.mSigningDetails,
16488 PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA)
16489 && !oldPackage.mSigningDetails.checkCapability(
16490 pkg.mSigningDetails,
16491 PackageParser.SigningDetails.CertCapabilities.ROLLBACK)) {
16492 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16493 "New package has a different signature: " + pkgName);
16498 // don't allow a system upgrade unless the upgrade hash matches
16499 if (oldPackage.restrictUpdateHash != null && oldPackage.isSystem()) {
16500 byte[] digestBytes = null;
16502 final MessageDigest digest = MessageDigest.getInstance("SHA-512");
16503 updateDigest(digest, new File(pkg.baseCodePath));
16504 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
16505 for (String path : pkg.splitCodePaths) {
16506 updateDigest(digest, new File(path));
16509 digestBytes = digest.digest();
16510 } catch (NoSuchAlgorithmException | IOException e) {
16511 res.setError(INSTALL_FAILED_INVALID_APK,
16512 "Could not compute hash: " + pkgName);
16515 if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
16516 res.setError(INSTALL_FAILED_INVALID_APK,
16517 "New package fails restrict-update check: " + pkgName);
16520 // retain upgrade restriction
16521 pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
16524 // Check for shared user id changes
16525 String invalidPackageName =
16526 getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
16527 if (invalidPackageName != null) {
16528 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
16529 "Package " + invalidPackageName + " tried to change user "
16530 + oldPackage.mSharedUserId);
16534 // check if the new package supports all of the abis which the old package supports
16535 boolean oldPkgSupportMultiArch = oldPackage.applicationInfo.secondaryCpuAbi != null;
16536 boolean newPkgSupportMultiArch = pkg.applicationInfo.secondaryCpuAbi != null;
16537 if (isSystemApp(oldPackage) && oldPkgSupportMultiArch && !newPkgSupportMultiArch) {
16538 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16539 "Update to package " + pkgName + " doesn't support multi arch");
16543 // In case of rollback, remember per-user/profile install state
16544 allUsers = sUserManager.getUserIds();
16545 installedUsers = ps.queryInstalledUsers(allUsers, true);
16547 // don't allow an upgrade from full to ephemeral
16548 if (isInstantApp) {
16549 if (user == null || user.getIdentifier() == UserHandle.USER_ALL) {
16550 for (int currentUser : allUsers) {
16551 if (!ps.getInstantApp(currentUser)) {
16552 // can't downgrade from full to instant
16553 Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
16554 + " for user: " + currentUser);
16555 res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16559 } else if (!ps.getInstantApp(user.getIdentifier())) {
16560 // can't downgrade from full to instant
16561 Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
16562 + " for user: " + user.getIdentifier());
16563 res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16569 // Update what is removed
16570 res.removedInfo = new PackageRemovedInfo(this);
16571 res.removedInfo.uid = oldPackage.applicationInfo.uid;
16572 res.removedInfo.removedPackage = oldPackage.packageName;
16573 res.removedInfo.installerPackageName = ps.installerPackageName;
16574 res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
16575 res.removedInfo.isUpdate = true;
16576 res.removedInfo.origUsers = installedUsers;
16577 res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
16578 for (int i = 0; i < installedUsers.length; i++) {
16579 final int userId = installedUsers[i];
16580 res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
16583 final int childCount = (oldPackage.childPackages != null)
16584 ? oldPackage.childPackages.size() : 0;
16585 for (int i = 0; i < childCount; i++) {
16586 boolean childPackageUpdated = false;
16587 PackageParser.Package childPkg = oldPackage.childPackages.get(i);
16588 final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16589 if (res.addedChildPackages != null) {
16590 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
16591 if (childRes != null) {
16592 childRes.removedInfo.uid = childPkg.applicationInfo.uid;
16593 childRes.removedInfo.removedPackage = childPkg.packageName;
16594 if (childPs != null) {
16595 childRes.removedInfo.installerPackageName = childPs.installerPackageName;
16597 childRes.removedInfo.isUpdate = true;
16598 childRes.removedInfo.installReasons = res.removedInfo.installReasons;
16599 childPackageUpdated = true;
16602 if (!childPackageUpdated) {
16603 PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
16604 childRemovedRes.removedPackage = childPkg.packageName;
16605 if (childPs != null) {
16606 childRemovedRes.installerPackageName = childPs.installerPackageName;
16608 childRemovedRes.isUpdate = false;
16609 childRemovedRes.dataRemoved = true;
16610 synchronized (mPackages) {
16611 if (childPs != null) {
16612 childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
16615 if (res.removedInfo.removedChildPackages == null) {
16616 res.removedInfo.removedChildPackages = new ArrayMap<>();
16618 res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
16622 boolean sysPkg = (isSystemApp(oldPackage));
16624 // Set the system/privileged/oem/vendor/product flags as needed
16625 final boolean privileged =
16626 (oldPackage.applicationInfo.privateFlags
16627 & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
16628 final boolean oem =
16629 (oldPackage.applicationInfo.privateFlags
16630 & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
16631 final boolean vendor =
16632 (oldPackage.applicationInfo.privateFlags
16633 & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
16634 final boolean product =
16635 (oldPackage.applicationInfo.privateFlags
16636 & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0;
16637 final @ParseFlags int systemParseFlags = parseFlags;
16638 final @ScanFlags int systemScanFlags = scanFlags
16640 | (privileged ? SCAN_AS_PRIVILEGED : 0)
16641 | (oem ? SCAN_AS_OEM : 0)
16642 | (vendor ? SCAN_AS_VENDOR : 0)
16643 | (product ? SCAN_AS_PRODUCT : 0);
16645 replaceSystemPackageLIF(oldPackage, pkg, systemParseFlags, systemScanFlags,
16646 user, allUsers, installerPackageName, res, installReason);
16648 replaceNonSystemPackageLIF(oldPackage, pkg, parseFlags, scanFlags,
16649 user, allUsers, installerPackageName, res, installReason);
16653 private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
16654 PackageParser.Package pkg, final @ParseFlags int parseFlags,
16655 final @ScanFlags int scanFlags, UserHandle user, int[] allUsers,
16656 String installerPackageName, PackageInstalledInfo res, int installReason) {
16657 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
16660 String pkgName = deletedPackage.packageName;
16661 boolean deletedPkg = true;
16662 boolean addedPkg = false;
16663 boolean updatedSettings = false;
16664 final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
16665 final int deleteFlags = PackageManager.DELETE_KEEP_DATA
16666 | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
16668 final long origUpdateTime = (pkg.mExtras != null)
16669 ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
16671 // First delete the existing package while retaining the data directory
16672 if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
16673 res.removedInfo, true, pkg)) {
16674 // If the existing package wasn't successfully deleted
16675 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
16676 deletedPkg = false;
16678 // Successfully deleted the old package; proceed with replace.
16680 // If deleted package lived in a container, give users a chance to
16681 // relinquish resources before killing.
16682 if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
16683 if (DEBUG_INSTALL) {
16684 Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
16686 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
16687 final ArrayList<String> pkgList = new ArrayList<String>(1);
16688 pkgList.add(deletedPackage.applicationInfo.packageName);
16689 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
16692 clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
16693 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16696 final PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags,
16697 scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
16698 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16701 // Update the in-memory copy of the previous code paths.
16702 PackageSetting ps = mSettings.mPackages.get(pkgName);
16704 if (ps.oldCodePaths == null) {
16705 ps.oldCodePaths = new ArraySet<>();
16707 Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
16708 if (deletedPackage.splitCodePaths != null) {
16709 Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
16712 ps.oldCodePaths = null;
16714 if (ps.childPackageNames != null) {
16715 for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
16716 final String childPkgName = ps.childPackageNames.get(i);
16717 final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
16718 childPs.oldCodePaths = ps.oldCodePaths;
16721 prepareAppDataAfterInstallLIF(newPackage);
16723 mDexManager.notifyPackageUpdated(newPackage.packageName,
16724 newPackage.baseCodePath, newPackage.splitCodePaths);
16725 } catch (PackageManagerException e) {
16726 res.setError("Package couldn't be installed in " + pkg.codePath, e);
16730 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16731 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
16733 // Revert all internal state mutations and added folders for the failed install
16735 deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
16736 res.removedInfo, true, null);
16739 // Restore the old package
16741 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
16742 File restoreFile = new File(deletedPackage.codePath);
16743 // Parse old package
16744 boolean oldExternal = isExternal(deletedPackage);
16745 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY |
16746 (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
16747 (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
16748 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
16750 scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
16752 } catch (PackageManagerException e) {
16753 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
16758 synchronized (mPackages) {
16759 // Ensure the installer package name up to date
16760 setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16762 // Update permissions for restored package
16763 mPermissionManager.updatePermissions(
16764 deletedPackage.packageName, deletedPackage, false, mPackages.values(),
16765 mPermissionCallback);
16767 mSettings.writeLPr();
16770 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
16773 synchronized (mPackages) {
16774 PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);
16776 res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
16777 if (res.removedInfo.removedChildPackages != null) {
16778 final int childCount = res.removedInfo.removedChildPackages.size();
16779 // Iterate in reverse as we may modify the collection
16780 for (int i = childCount - 1; i >= 0; i--) {
16781 String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
16782 if (res.addedChildPackages.containsKey(childPackageName)) {
16783 res.removedInfo.removedChildPackages.removeAt(i);
16785 PackageRemovedInfo childInfo = res.removedInfo
16786 .removedChildPackages.valueAt(i);
16787 childInfo.removedForAllUsers = mPackages.get(
16788 childInfo.removedPackage) == null;
16797 private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
16798 PackageParser.Package pkg, final @ParseFlags int parseFlags,
16799 final @ScanFlags int scanFlags, UserHandle user,
16800 int[] allUsers, String installerPackageName, PackageInstalledInfo res,
16801 int installReason) {
16802 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
16803 + ", old=" + deletedPackage);
16805 final boolean disabledSystem;
16807 // Remove existing system package
16808 removePackageLI(deletedPackage, true);
16810 synchronized (mPackages) {
16811 disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
16813 if (!disabledSystem) {
16814 // We didn't need to disable the .apk as a current system package,
16815 // which means we are replacing another update that is already
16816 // installed. We need to make sure to delete the older one's .apk.
16817 res.removedInfo.args = createInstallArgsForExisting(0,
16818 deletedPackage.applicationInfo.getCodePath(),
16819 deletedPackage.applicationInfo.getResourcePath(),
16820 getAppDexInstructionSets(deletedPackage.applicationInfo));
16822 res.removedInfo.args = null;
16825 // Successfully disabled the old package. Now proceed with re-installation
16826 clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
16827 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16829 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16830 pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
16831 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
16833 PackageParser.Package newPackage = null;
16835 // Add the package to the internal data structures
16836 newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 0, user);
16838 // Set the update and install times
16839 PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
16840 setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
16841 System.currentTimeMillis());
16843 // Update the package dynamic state if succeeded
16844 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16845 // Now that the install succeeded make sure we remove data
16846 // directories for any child package the update removed.
16847 final int deletedChildCount = (deletedPackage.childPackages != null)
16848 ? deletedPackage.childPackages.size() : 0;
16849 final int newChildCount = (newPackage.childPackages != null)
16850 ? newPackage.childPackages.size() : 0;
16851 for (int i = 0; i < deletedChildCount; i++) {
16852 PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
16853 boolean childPackageDeleted = true;
16854 for (int j = 0; j < newChildCount; j++) {
16855 PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
16856 if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
16857 childPackageDeleted = false;
16861 if (childPackageDeleted) {
16862 PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
16863 deletedChildPkg.packageName);
16864 if (ps != null && res.removedInfo.removedChildPackages != null) {
16865 PackageRemovedInfo removedChildRes = res.removedInfo
16866 .removedChildPackages.get(deletedChildPkg.packageName);
16867 removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
16868 removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
16873 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16875 prepareAppDataAfterInstallLIF(newPackage);
16877 mDexManager.notifyPackageUpdated(newPackage.packageName,
16878 newPackage.baseCodePath, newPackage.splitCodePaths);
16880 } catch (PackageManagerException e) {
16881 res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
16882 res.setError("Package couldn't be installed in " + pkg.codePath, e);
16885 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16886 // Re installation failed. Restore old information
16887 // Remove new pkg information
16888 if (newPackage != null) {
16889 removeInstalledPackageLI(newPackage, true);
16891 // Add back the old system package
16893 scanPackageTracedLI(deletedPackage, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
16894 } catch (PackageManagerException e) {
16895 Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
16898 synchronized (mPackages) {
16899 if (disabledSystem) {
16900 enableSystemPackageLPw(deletedPackage);
16903 // Ensure the installer package name up to date
16904 setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16906 // Update permissions for restored package
16907 mPermissionManager.updatePermissions(
16908 deletedPackage.packageName, deletedPackage, false, mPackages.values(),
16909 mPermissionCallback);
16911 mSettings.writeLPr();
16914 Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
16915 + " after failed upgrade");
16920 * Checks whether the parent or any of the child packages have a change shared
16921 * user. For a package to be a valid update the shred users of the parent and
16922 * the children should match. We may later support changing child shared users.
16923 * @param oldPkg The updated package.
16924 * @param newPkg The update package.
16925 * @return The shared user that change between the versions.
16927 private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
16928 PackageParser.Package newPkg) {
16929 // Check parent shared user
16930 if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
16931 return newPkg.packageName;
16933 // Check child shared users
16934 final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16935 final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
16936 for (int i = 0; i < newChildCount; i++) {
16937 PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
16938 // If this child was present, did it have the same shared user?
16939 for (int j = 0; j < oldChildCount; j++) {
16940 PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
16941 if (newChildPkg.packageName.equals(oldChildPkg.packageName)
16942 && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
16943 return newChildPkg.packageName;
16950 private void removeNativeBinariesLI(PackageSetting ps) {
16951 // Remove the lib path for the parent package
16953 NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
16954 // Remove the lib path for the child packages
16955 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
16956 for (int i = 0; i < childCount; i++) {
16957 PackageSetting childPs = null;
16958 synchronized (mPackages) {
16959 childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
16961 if (childPs != null) {
16962 NativeLibraryHelper.removeNativeBinariesLI(childPs
16963 .legacyNativeLibraryPathString);
16969 private void enableSystemPackageLPw(PackageParser.Package pkg) {
16970 // Enable the parent package
16971 mSettings.enableSystemPackageLPw(pkg.packageName);
16972 // Enable the child packages
16973 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16974 for (int i = 0; i < childCount; i++) {
16975 PackageParser.Package childPkg = pkg.childPackages.get(i);
16976 mSettings.enableSystemPackageLPw(childPkg.packageName);
16980 private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
16981 PackageParser.Package newPkg) {
16982 // Disable the parent package (parent always replaced)
16983 boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
16984 // Disable the child packages
16985 final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16986 for (int i = 0; i < childCount; i++) {
16987 PackageParser.Package childPkg = oldPkg.childPackages.get(i);
16988 final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
16989 disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
16994 private void setInstallerPackageNameLPw(PackageParser.Package pkg,
16995 String installerPackageName) {
16996 // Enable the parent package
16997 mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
16998 // Enable the child packages
16999 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17000 for (int i = 0; i < childCount; i++) {
17001 PackageParser.Package childPkg = pkg.childPackages.get(i);
17002 mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
17006 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
17007 int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
17008 // Update the parent package setting
17009 updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
17010 res, user, installReason);
17011 // Update the child packages setting
17012 final int childCount = (newPackage.childPackages != null)
17013 ? newPackage.childPackages.size() : 0;
17014 for (int i = 0; i < childCount; i++) {
17015 PackageParser.Package childPackage = newPackage.childPackages.get(i);
17016 PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
17017 updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
17018 childRes.origUsers, childRes, user, installReason);
17022 private void updateSettingsInternalLI(PackageParser.Package pkg,
17023 String installerPackageName, int[] allUsers, int[] installedForUsers,
17024 PackageInstalledInfo res, UserHandle user, int installReason) {
17025 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
17027 final String pkgName = pkg.packageName;
17029 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.codePath);
17030 synchronized (mPackages) {
17031 // NOTE: This changes slightly to include UPDATE_PERMISSIONS_ALL regardless of the size of pkg.permissions
17032 mPermissionManager.updatePermissions(pkg.packageName, pkg, true, mPackages.values(),
17033 mPermissionCallback);
17034 // For system-bundled packages, we assume that installing an upgraded version
17035 // of the package implies that the user actually wants to run that new code,
17036 // so we enable the package.
17037 PackageSetting ps = mSettings.mPackages.get(pkgName);
17038 final int userId = user.getIdentifier();
17040 if (isSystemApp(pkg)) {
17041 if (DEBUG_INSTALL) {
17042 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
17044 // Enable system package for requested users
17045 if (res.origUsers != null) {
17046 for (int origUserId : res.origUsers) {
17047 if (userId == UserHandle.USER_ALL || userId == origUserId) {
17048 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
17049 origUserId, installerPackageName);
17053 // Also convey the prior install/uninstall state
17054 if (allUsers != null && installedForUsers != null) {
17055 for (int currentUserId : allUsers) {
17056 final boolean installed = ArrayUtils.contains(
17057 installedForUsers, currentUserId);
17058 if (DEBUG_INSTALL) {
17059 Slog.d(TAG, " user " + currentUserId + " => " + installed);
17061 ps.setInstalled(installed, currentUserId);
17063 // these install state changes will be persisted in the
17064 // upcoming call to mSettings.writeLPr().
17067 // It's implied that when a user requests installation, they want the app to be
17068 // installed and enabled.
17069 if (userId != UserHandle.USER_ALL) {
17070 ps.setInstalled(true, userId);
17071 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
17074 // When replacing an existing package, preserve the original install reason for all
17075 // users that had the package installed before.
17076 final Set<Integer> previousUserIds = new ArraySet<>();
17077 if (res.removedInfo != null && res.removedInfo.installReasons != null) {
17078 final int installReasonCount = res.removedInfo.installReasons.size();
17079 for (int i = 0; i < installReasonCount; i++) {
17080 final int previousUserId = res.removedInfo.installReasons.keyAt(i);
17081 final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
17082 ps.setInstallReason(previousInstallReason, previousUserId);
17083 previousUserIds.add(previousUserId);
17087 // Set install reason for users that are having the package newly installed.
17088 if (userId == UserHandle.USER_ALL) {
17089 for (int currentUserId : sUserManager.getUserIds()) {
17090 if (!previousUserIds.contains(currentUserId)) {
17091 ps.setInstallReason(installReason, currentUserId);
17094 } else if (!previousUserIds.contains(userId)) {
17095 ps.setInstallReason(installReason, userId);
17097 mSettings.writeKernelMappingLPr(ps);
17099 res.name = pkgName;
17100 res.uid = pkg.applicationInfo.uid;
17102 mSettings.setInstallerPackageName(pkgName, installerPackageName);
17103 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17104 //to update install status
17105 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
17106 mSettings.writeLPr();
17107 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17110 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17113 private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
17115 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
17116 installPackageLI(args, res);
17118 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17122 private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
17123 final int installFlags = args.installFlags;
17124 final String installerPackageName = args.installerPackageName;
17125 final String volumeUuid = args.volumeUuid;
17126 final File tmpPackageFile = new File(args.getCodePath());
17127 final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
17128 final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
17129 || (args.volumeUuid != null));
17130 final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
17131 final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
17132 final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
17133 final boolean virtualPreload =
17134 ((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
17135 boolean replace = false;
17136 @ScanFlags int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
17137 if (args.move != null) {
17138 // moving a complete application; perform an initial scan on the new install location
17139 scanFlags |= SCAN_INITIAL;
17141 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
17142 scanFlags |= SCAN_DONT_KILL_APP;
17145 scanFlags |= SCAN_AS_INSTANT_APP;
17148 scanFlags |= SCAN_AS_FULL_APP;
17150 if (virtualPreload) {
17151 scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
17154 // Result object to be returned
17155 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17156 res.installerPackageName = installerPackageName;
17158 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
17161 if (instantApp && (forwardLocked || onExternal)) {
17162 Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
17163 + " external=" + onExternal);
17164 res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
17168 // Retrieve PackageSettings and parse package
17169 @ParseFlags final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
17170 | PackageParser.PARSE_ENFORCE_CODE
17171 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
17172 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
17173 | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
17174 PackageParser pp = new PackageParser();
17175 pp.setSeparateProcesses(mSeparateProcesses);
17176 pp.setDisplayMetrics(mMetrics);
17177 pp.setCallback(mPackageParserCallback);
17179 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
17180 final PackageParser.Package pkg;
17182 pkg = pp.parsePackage(tmpPackageFile, parseFlags);
17183 DexMetadataHelper.validatePackageDexMetadata(pkg);
17184 } catch (PackageParserException e) {
17185 res.setError("Failed parse during installPackageLI", e);
17188 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17191 // Instant apps have several additional install-time checks.
17193 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
17195 "Instant app package " + pkg.packageName + " does not target at least O");
17196 res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
17197 "Instant app package must target at least O");
17200 if (pkg.applicationInfo.targetSandboxVersion != 2) {
17201 Slog.w(TAG, "Instant app package " + pkg.packageName
17202 + " does not target targetSandboxVersion 2");
17203 res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
17204 "Instant app package must use targetSandboxVersion 2");
17207 if (pkg.mSharedUserId != null) {
17208 Slog.w(TAG, "Instant app package " + pkg.packageName
17209 + " may not declare sharedUserId.");
17210 res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
17211 "Instant app package may not declare a sharedUserId");
17216 if (pkg.applicationInfo.isStaticSharedLibrary()) {
17217 // Static shared libraries have synthetic package names
17218 renameStaticSharedLibraryPackage(pkg);
17220 // No static shared libs on external storage
17222 Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
17223 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
17224 "Packages declaring static-shared libs cannot be updated");
17229 // If we are installing a clustered package add results for the children
17230 if (pkg.childPackages != null) {
17231 synchronized (mPackages) {
17232 final int childCount = pkg.childPackages.size();
17233 for (int i = 0; i < childCount; i++) {
17234 PackageParser.Package childPkg = pkg.childPackages.get(i);
17235 PackageInstalledInfo childRes = new PackageInstalledInfo();
17236 childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17237 childRes.pkg = childPkg;
17238 childRes.name = childPkg.packageName;
17239 PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17240 if (childPs != null) {
17241 childRes.origUsers = childPs.queryInstalledUsers(
17242 sUserManager.getUserIds(), true);
17244 if ((mPackages.containsKey(childPkg.packageName))) {
17245 childRes.removedInfo = new PackageRemovedInfo(this);
17246 childRes.removedInfo.removedPackage = childPkg.packageName;
17247 childRes.removedInfo.installerPackageName = childPs.installerPackageName;
17249 if (res.addedChildPackages == null) {
17250 res.addedChildPackages = new ArrayMap<>();
17252 res.addedChildPackages.put(childPkg.packageName, childRes);
17257 // If package doesn't declare API override, mark that we have an install
17258 // time CPU ABI override.
17259 if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
17260 pkg.cpuAbiOverride = args.abiOverride;
17263 String pkgName = res.name = pkg.packageName;
17264 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
17265 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
17266 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
17272 // either use what we've been given or parse directly from the APK
17273 if (args.signingDetails != PackageParser.SigningDetails.UNKNOWN) {
17274 pkg.setSigningDetails(args.signingDetails);
17276 PackageParser.collectCertificates(pkg, false /* skipVerify */);
17278 } catch (PackageParserException e) {
17279 res.setError("Failed collect during installPackageLI", e);
17283 if (instantApp && pkg.mSigningDetails.signatureSchemeVersion
17284 < SignatureSchemeVersion.SIGNING_BLOCK_V2) {
17285 Slog.w(TAG, "Instant app package " + pkg.packageName
17286 + " is not signed with at least APK Signature Scheme v2");
17287 res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
17288 "Instant app package must be signed with APK Signature Scheme v2 or greater");
17292 // Get rid of all references to package scan path via parser.
17294 String oldCodePath = null;
17295 boolean systemApp = false;
17296 synchronized (mPackages) {
17297 // Check if installing already existing package
17298 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
17299 String oldName = mSettings.getRenamedPackageLPr(pkgName);
17300 if (pkg.mOriginalPackages != null
17301 && pkg.mOriginalPackages.contains(oldName)
17302 && mPackages.containsKey(oldName)) {
17303 // This package is derived from an original package,
17304 // and this device has been updating from that original
17305 // name. We must continue using the original name, so
17306 // rename the new package here.
17307 pkg.setPackageName(oldName);
17308 pkgName = pkg.packageName;
17310 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
17311 + oldName + " pkgName=" + pkgName);
17312 } else if (mPackages.containsKey(pkgName)) {
17313 // This package, under its official name, already exists
17314 // on the device; we should replace it.
17316 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
17319 // Child packages are installed through the parent package
17320 if (pkg.parentPackage != null) {
17321 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
17322 "Package " + pkg.packageName + " is child of package "
17323 + pkg.parentPackage.parentPackage + ". Child packages "
17324 + "can be updated only through the parent package.");
17329 // Prevent apps opting out from runtime permissions
17330 PackageParser.Package oldPackage = mPackages.get(pkgName);
17331 final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
17332 final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
17333 if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
17334 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
17335 res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
17336 "Package " + pkg.packageName + " new target SDK " + newTargetSdk
17337 + " doesn't support runtime permissions but the old"
17338 + " target SDK " + oldTargetSdk + " does.");
17341 // Prevent persistent apps from being updated
17342 if ((oldPackage.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0) {
17343 res.setError(PackageManager.INSTALL_FAILED_INVALID_APK,
17344 "Package " + oldPackage.packageName + " is a persistent app. "
17345 + "Persistent apps are not updateable.");
17348 // Prevent installing of child packages
17349 if (oldPackage.parentPackage != null) {
17350 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
17351 "Package " + pkg.packageName + " is child of package "
17352 + oldPackage.parentPackage + ". Child packages "
17353 + "can be updated only through the parent package.");
17359 PackageSetting ps = mSettings.mPackages.get(pkgName);
17361 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
17363 // Static shared libs have same package with different versions where
17364 // we internally use a synthetic package name to allow multiple versions
17365 // of the same package, therefore we need to compare signatures against
17366 // the package setting for the latest library version.
17367 PackageSetting signatureCheckPs = ps;
17368 if (pkg.applicationInfo.isStaticSharedLibrary()) {
17369 SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
17370 if (libraryEntry != null) {
17371 signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
17375 // Quick sanity check that we're signed correctly if updating;
17376 // we'll check this again later when scanning, but we want to
17377 // bail early here before tripping over redefined permissions.
17378 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
17379 if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
17380 if (!ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) {
17381 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
17382 + pkg.packageName + " upgrade keys do not match the "
17383 + "previously installed version");
17388 final boolean compareCompat = isCompatSignatureUpdateNeeded(pkg);
17389 final boolean compareRecover = isRecoverSignatureUpdateNeeded(pkg);
17390 // We don't care about disabledPkgSetting on install for now.
17391 final boolean compatMatch = verifySignatures(
17392 signatureCheckPs, null, pkg.mSigningDetails, compareCompat,
17394 // The new KeySets will be re-added later in the scanning process.
17396 synchronized (mPackages) {
17397 ksms.removeAppKeySetDataLPw(pkg.packageName);
17400 } catch (PackageManagerException e) {
17401 res.setError(e.error, e.getMessage());
17406 oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
17407 if (ps.pkg != null && ps.pkg.applicationInfo != null) {
17408 systemApp = (ps.pkg.applicationInfo.flags &
17409 ApplicationInfo.FLAG_SYSTEM) != 0;
17411 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
17414 int N = pkg.permissions.size();
17415 for (int i = N-1; i >= 0; i--) {
17416 final PackageParser.Permission perm = pkg.permissions.get(i);
17417 final BasePermission bp =
17418 (BasePermission) mPermissionManager.getPermissionTEMP(perm.info.name);
17420 // Don't allow anyone but the system to define ephemeral permissions.
17421 if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0
17423 Slog.w(TAG, "Non-System package " + pkg.packageName
17424 + " attempting to delcare ephemeral permission "
17425 + perm.info.name + "; Removing ephemeral.");
17426 perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_INSTANT;
17429 // Check whether the newly-scanned package wants to define an already-defined perm
17431 // If the defining package is signed with our cert, it's okay. This
17432 // also includes the "updating the same package" case, of course.
17433 // "updating same package" could also involve key-rotation.
17434 final boolean sigsOk;
17435 final String sourcePackageName = bp.getSourcePackageName();
17436 final PackageSettingBase sourcePackageSetting = bp.getSourcePackageSetting();
17437 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
17438 if (sourcePackageName.equals(pkg.packageName)
17439 && (ksms.shouldCheckUpgradeKeySetLocked(
17440 sourcePackageSetting, scanFlags))) {
17441 sigsOk = ksms.checkUpgradeKeySetLocked(sourcePackageSetting, pkg);
17444 // in the event of signing certificate rotation, we need to see if the
17445 // package's certificate has rotated from the current one, or if it is an
17446 // older certificate with which the current is ok with sharing permissions
17447 if (sourcePackageSetting.signatures.mSigningDetails.checkCapability(
17448 pkg.mSigningDetails,
17449 PackageParser.SigningDetails.CertCapabilities.PERMISSION)) {
17451 } else if (pkg.mSigningDetails.checkCapability(
17452 sourcePackageSetting.signatures.mSigningDetails,
17453 PackageParser.SigningDetails.CertCapabilities.PERMISSION)) {
17455 // the scanned package checks out, has signing certificate rotation
17456 // history, and is newer; bring it over
17457 sourcePackageSetting.signatures.mSigningDetails = pkg.mSigningDetails;
17464 // If the owning package is the system itself, we log but allow
17465 // install to proceed; we fail the install on all other permission
17467 if (!sourcePackageName.equals("android")) {
17468 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
17469 + pkg.packageName + " attempting to redeclare permission "
17470 + perm.info.name + " already owned by " + sourcePackageName);
17471 res.origPermission = perm.info.name;
17472 res.origPackage = sourcePackageName;
17475 Slog.w(TAG, "Package " + pkg.packageName
17476 + " attempting to redeclare system permission "
17477 + perm.info.name + "; ignoring new declaration");
17478 pkg.permissions.remove(i);
17480 } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
17481 // Prevent apps to change protection level to dangerous from any other
17482 // type as this would allow a privilege escalation where an app adds a
17483 // normal/signature permission in other app's group and later redefines
17484 // it as dangerous leading to the group auto-grant.
17485 if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
17486 == PermissionInfo.PROTECTION_DANGEROUS) {
17487 if (bp != null && !bp.isRuntime()) {
17488 Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
17489 + "non-runtime permission " + perm.info.name
17490 + " to runtime; keeping old protection level");
17491 perm.info.protectionLevel = bp.getProtectionLevel();
17501 // Abort update; system app can't be replaced with app on sdcard
17502 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
17503 "Cannot install updates to system apps on sdcard");
17505 } else if (instantApp) {
17506 // Abort update; system app can't be replaced with an instant app
17507 res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
17508 "Cannot update a system app with an instant app");
17513 if (args.move != null) {
17514 // We did an in-place move, so dex is ready to roll
17515 scanFlags |= SCAN_NO_DEX;
17516 scanFlags |= SCAN_MOVE;
17518 synchronized (mPackages) {
17519 final PackageSetting ps = mSettings.mPackages.get(pkgName);
17521 res.setError(INSTALL_FAILED_INTERNAL_ERROR,
17522 "Missing settings for moved package " + pkgName);
17525 // We moved the entire application as-is, so bring over the
17526 // previously derived ABI information.
17527 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
17528 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
17531 } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
17532 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
17533 scanFlags |= SCAN_NO_DEX;
17536 String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
17537 args.abiOverride : pkg.cpuAbiOverride);
17538 final boolean extractNativeLibs = !pkg.isLibrary();
17539 derivePackageAbi(pkg, abiOverride, extractNativeLibs);
17540 } catch (PackageManagerException pme) {
17541 Slog.e(TAG, "Error deriving application ABI", pme);
17542 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
17546 // Shared libraries for the package need to be updated.
17547 synchronized (mPackages) {
17549 updateSharedLibrariesLPr(pkg, null);
17550 } catch (PackageManagerException e) {
17551 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
17556 if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
17557 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
17561 if (PackageManagerServiceUtils.isApkVerityEnabled()) {
17562 String apkPath = null;
17563 synchronized (mPackages) {
17564 // Note that if the attacker managed to skip verify setup, for example by tampering
17565 // with the package settings, upon reboot we will do full apk verification when
17566 // verity is not detected.
17567 final PackageSetting ps = mSettings.mPackages.get(pkgName);
17568 if (ps != null && ps.isPrivileged()) {
17569 apkPath = pkg.baseCodePath;
17573 if (apkPath != null) {
17574 final VerityUtils.SetupResult result =
17575 VerityUtils.generateApkVeritySetupData(apkPath);
17576 if (result.isOk()) {
17577 if (Build.IS_DEBUGGABLE) Slog.i(TAG, "Enabling apk verity to " + apkPath);
17578 FileDescriptor fd = result.getUnownedFileDescriptor();
17580 final byte[] signedRootHash = VerityUtils.generateFsverityRootHash(apkPath);
17581 mInstaller.installApkVerity(apkPath, fd, result.getContentSize());
17582 mInstaller.assertFsverityRootHashMatches(apkPath, signedRootHash);
17583 } catch (InstallerException | IOException | DigestException |
17584 NoSuchAlgorithmException e) {
17585 res.setError(INSTALL_FAILED_INTERNAL_ERROR,
17586 "Failed to set up verity: " + e);
17589 IoUtils.closeQuietly(fd);
17591 } else if (result.isFailed()) {
17592 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Failed to generate verity");
17595 // Do nothing if verity is skipped. Will fall back to full apk verification on
17602 startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
17604 if (DEBUG_DOMAIN_VERIFICATION) {
17605 Slog.d(TAG, "Not verifying instant app install for app links: " + pkgName);
17609 try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
17610 "installPackageLI")) {
17612 if (pkg.applicationInfo.isStaticSharedLibrary()) {
17613 // Static libs have a synthetic package name containing the version
17614 // and cannot be updated as an update would get a new package name,
17615 // unless this is the exact same version code which is useful for
17617 PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
17618 if (existingPkg != null &&
17619 existingPkg.getLongVersionCode() != pkg.getLongVersionCode()) {
17620 res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
17621 + "static-shared libs cannot be updated");
17625 replacePackageLIF(pkg, parseFlags, scanFlags, args.user,
17626 installerPackageName, res, args.installReason);
17628 installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
17629 args.user, installerPackageName, volumeUuid, res, args.installReason);
17633 // Prepare the application profiles for the new code paths.
17634 // This needs to be done before invoking dexopt so that any install-time profile
17635 // can be used for optimizations.
17636 mArtManagerService.prepareAppProfiles(pkg, resolveUserIds(args.user.getIdentifier()));
17638 // Check whether we need to dexopt the app.
17640 // NOTE: it is IMPORTANT to call dexopt:
17641 // - after doRename which will sync the package data from PackageParser.Package and its
17642 // corresponding ApplicationInfo.
17643 // - after installNewPackageLIF or replacePackageLIF which will update result with the
17644 // uid of the application (pkg.applicationInfo.uid).
17645 // This update happens in place!
17647 // We only need to dexopt if the package meets ALL of the following conditions:
17648 // 1) it is not forward locked.
17649 // 2) it is not on on an external ASEC container.
17650 // 3) it is not an instant app or if it is then dexopt is enabled via gservices.
17651 // 4) it is not debuggable.
17653 // Note that we do not dexopt instant apps by default. dexopt can take some time to
17654 // complete, so we skip this step during installation. Instead, we'll take extra time
17655 // the first time the instant app starts. It's preferred to do it this way to provide
17656 // continuous progress to the useur instead of mysteriously blocking somewhere in the
17657 // middle of running an instant app. The default behaviour can be overridden
17659 final boolean performDexopt = (res.returnCode == PackageManager.INSTALL_SUCCEEDED)
17661 && !pkg.applicationInfo.isExternalAsec()
17662 && (!instantApp || Global.getInt(mContext.getContentResolver(),
17663 Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0)
17664 && ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0);
17666 if (performDexopt) {
17667 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
17668 // Do not run PackageDexOptimizer through the local performDexOpt
17669 // method because `pkg` may not be in `mPackages` yet.
17671 // Also, don't fail application installs if the dexopt step fails.
17672 DexoptOptions dexoptOptions = new DexoptOptions(pkg.packageName,
17674 DexoptOptions.DEXOPT_BOOT_COMPLETE |
17675 DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE);
17676 mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
17677 null /* instructionSets */,
17678 getOrCreateCompilerPackageStats(pkg),
17679 mDexManager.getPackageUseInfoOrDefault(pkg.packageName),
17681 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17684 // Notify BackgroundDexOptService that the package has been changed.
17685 // If this is an update of a package which used to fail to compile,
17686 // BackgroundDexOptService will remove it from its blacklist.
17687 // TODO: Layering violation
17688 BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
17690 synchronized (mPackages) {
17691 final PackageSetting ps = mSettings.mPackages.get(pkgName);
17693 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
17694 ps.setUpdateAvailable(false /*updateAvailable*/);
17697 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17698 for (int i = 0; i < childCount; i++) {
17699 PackageParser.Package childPkg = pkg.childPackages.get(i);
17700 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
17701 PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17702 if (childPs != null) {
17703 childRes.newUsers = childPs.queryInstalledUsers(
17704 sUserManager.getUserIds(), true);
17708 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
17709 updateSequenceNumberLP(ps, res.newUsers);
17710 updateInstantAppInstallerLocked(pkgName);
17715 private void startIntentFilterVerifications(int userId, boolean replacing,
17716 PackageParser.Package pkg) {
17717 if (mIntentFilterVerifierComponent == null) {
17718 Slog.w(TAG, "No IntentFilter verification will not be done as "
17719 + "there is no IntentFilterVerifier available!");
17723 final int verifierUid = getPackageUid(
17724 mIntentFilterVerifierComponent.getPackageName(),
17725 MATCH_DEBUG_TRIAGED_MISSING,
17726 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
17728 Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
17729 msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
17730 mHandler.sendMessage(msg);
17732 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17733 for (int i = 0; i < childCount; i++) {
17734 PackageParser.Package childPkg = pkg.childPackages.get(i);
17735 msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
17736 msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
17737 mHandler.sendMessage(msg);
17741 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
17742 PackageParser.Package pkg) {
17743 int size = pkg.activities.size();
17745 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17746 "No activity, so no need to verify any IntentFilter!");
17750 final boolean hasDomainURLs = hasDomainURLs(pkg);
17751 if (!hasDomainURLs) {
17752 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17753 "No domain URLs, so no need to verify any IntentFilter!");
17757 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
17758 + " if any IntentFilter from the " + size
17759 + " Activities needs verification ...");
17762 final String packageName = pkg.packageName;
17763 boolean handlesWebUris = false;
17764 ArraySet<String> domains = new ArraySet<>();
17765 final boolean previouslyVerified;
17766 boolean hostSetExpanded = false;
17767 boolean needToRunVerify = false;
17768 synchronized (mPackages) {
17769 // If this is a new install and we see that we've already run verification for this
17770 // package, we have nothing to do: it means the state was restored from backup.
17771 IntentFilterVerificationInfo ivi =
17772 mSettings.getIntentFilterVerificationLPr(packageName);
17773 previouslyVerified = (ivi != null);
17774 if (!replacing && previouslyVerified) {
17775 if (DEBUG_DOMAIN_VERIFICATION) {
17776 Slog.i(TAG, "Package " + packageName + " already verified: status="
17777 + ivi.getStatusString());
17782 if (DEBUG_DOMAIN_VERIFICATION) {
17783 Slog.i(TAG, " Previous verified hosts: "
17784 + (ivi == null ? "[none]" : ivi.getDomainsString()));
17787 // If any filters need to be verified, then all need to be. In addition, we need to
17788 // know whether an updating app has any web navigation intent filters, to re-
17789 // examine handling policy even if not re-verifying.
17790 final boolean needsVerification = needsNetworkVerificationLPr(packageName);
17791 for (PackageParser.Activity a : pkg.activities) {
17792 for (ActivityIntentInfo filter : a.intents) {
17793 if (filter.handlesWebUris(true)) {
17794 handlesWebUris = true;
17796 if (needsVerification && filter.needsVerification()) {
17797 if (DEBUG_DOMAIN_VERIFICATION) {
17798 Slog.d(TAG, "autoVerify requested, processing all filters");
17800 needToRunVerify = true;
17801 // It's safe to break out here because filter.needsVerification()
17802 // can only be true if filter.handlesWebUris(true) returned true, so
17803 // we've already noted that.
17809 // Compare the new set of recognized hosts if the app is either requesting
17810 // autoVerify or has previously used autoVerify but no longer does.
17811 if (needToRunVerify || previouslyVerified) {
17812 final int verificationId = mIntentFilterVerificationToken++;
17813 for (PackageParser.Activity a : pkg.activities) {
17814 for (ActivityIntentInfo filter : a.intents) {
17815 // Run verification against hosts mentioned in any web-nav intent filter,
17816 // even if the filter matches non-web schemes as well
17817 if (filter.handlesWebUris(false /*onlyWebSchemes*/)) {
17818 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17819 "Verification needed for IntentFilter:" + filter.toString());
17820 mIntentFilterVerifier.addOneIntentFilterVerification(
17821 verifierUid, userId, verificationId, filter, packageName);
17822 domains.addAll(filter.getHostsList());
17829 if (DEBUG_DOMAIN_VERIFICATION) {
17830 Slog.i(TAG, " Update published hosts: " + domains.toString());
17833 // If we've previously verified this same host set (or a subset), we can trust that
17834 // a current ALWAYS policy is still applicable. If this is the case, we're done.
17835 // (If we aren't in ALWAYS, we want to reverify to allow for apps that had failing
17836 // hosts in their intent filters, then pushed a new apk that removed them and now
17840 // + still autoVerify (needToRunVerify):
17841 // - preserve current state if all of: unexpanded, in always
17842 // - otherwise rerun as usual (fall through)
17843 // + no longer autoVerify (alreadyVerified && !needToRunVerify)
17844 // - wipe verification history always
17845 // - preserve current state if all of: unexpanded, in always
17846 hostSetExpanded = !previouslyVerified
17847 || (ivi != null && !ivi.getDomains().containsAll(domains));
17848 final int currentPolicy =
17849 mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
17850 final boolean keepCurState = !hostSetExpanded
17851 && currentPolicy == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
17853 if (needToRunVerify && keepCurState) {
17854 if (DEBUG_DOMAIN_VERIFICATION) {
17855 Slog.i(TAG, "Host set not expanding + ALWAYS -> no need to reverify");
17857 ivi.setDomains(domains);
17858 scheduleWriteSettingsLocked();
17860 } else if (previouslyVerified && !needToRunVerify) {
17861 // Prior autoVerify state but not requesting it now. Clear autoVerify history,
17862 // and preserve the always policy iff the host set is not expanding.
17863 clearIntentFilterVerificationsLPw(packageName, userId, !keepCurState);
17868 if (needToRunVerify && count > 0) {
17869 // app requested autoVerify and has at least one matching intent filter
17870 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
17871 + " IntentFilter verification" + (count > 1 ? "s" : "")
17872 + " for userId:" + userId);
17873 mIntentFilterVerifier.startVerifications(userId);
17875 if (DEBUG_DOMAIN_VERIFICATION) {
17876 Slog.d(TAG, "No web filters or no new host policy for " + packageName);
17881 private boolean needsNetworkVerificationLPr(String packageName) {
17882 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
17887 int status = ivi.getStatus();
17889 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
17890 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS:
17891 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
17900 private static boolean isMultiArch(ApplicationInfo info) {
17901 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
17904 private static boolean isExternal(PackageParser.Package pkg) {
17905 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17908 private static boolean isExternal(PackageSetting ps) {
17909 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17912 private static boolean isSystemApp(PackageParser.Package pkg) {
17913 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
17916 private static boolean isPrivilegedApp(PackageParser.Package pkg) {
17917 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
17920 private static boolean isOemApp(PackageParser.Package pkg) {
17921 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
17924 private static boolean isVendorApp(PackageParser.Package pkg) {
17925 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
17928 private static boolean isProductApp(PackageParser.Package pkg) {
17929 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0;
17932 private static boolean hasDomainURLs(PackageParser.Package pkg) {
17933 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
17936 private static boolean isSystemApp(PackageSetting ps) {
17937 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
17940 private static boolean isUpdatedSystemApp(PackageSetting ps) {
17941 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
17944 private int packageFlagsToInstallFlags(PackageSetting ps) {
17945 int installFlags = 0;
17946 if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
17947 // This existing package was an external ASEC install when we have
17948 // the external flag without a UUID
17949 installFlags |= PackageManager.INSTALL_EXTERNAL;
17951 if (ps.isForwardLocked()) {
17952 installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
17954 return installFlags;
17957 private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
17958 if (isExternal(pkg)) {
17959 if (TextUtils.isEmpty(pkg.volumeUuid)) {
17960 return mSettings.getExternalVersion();
17962 return mSettings.findOrCreateVersion(pkg.volumeUuid);
17965 return mSettings.getInternalVersion();
17969 private void deleteTempPackageFiles() {
17970 final FilenameFilter filter = new FilenameFilter() {
17971 public boolean accept(File dir, String name) {
17972 return name.startsWith("vmdl") && name.endsWith(".tmp");
17975 for (File file : sDrmAppPrivateInstallDir.listFiles(filter)) {
17981 public void deletePackageAsUser(String packageName, int versionCode,
17982 IPackageDeleteObserver observer, int userId, int flags) {
17983 deletePackageVersioned(new VersionedPackage(packageName, versionCode),
17984 new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
17988 public void deletePackageVersioned(VersionedPackage versionedPackage,
17989 final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
17990 final int callingUid = Binder.getCallingUid();
17991 mContext.enforceCallingOrSelfPermission(
17992 android.Manifest.permission.DELETE_PACKAGES, null);
17993 final boolean canViewInstantApps = canViewInstantApps(callingUid, userId);
17994 Preconditions.checkNotNull(versionedPackage);
17995 Preconditions.checkNotNull(observer);
17996 Preconditions.checkArgumentInRange(versionedPackage.getLongVersionCode(),
17997 PackageManager.VERSION_CODE_HIGHEST,
17998 Long.MAX_VALUE, "versionCode must be >= -1");
18000 final String packageName = versionedPackage.getPackageName();
18001 final long versionCode = versionedPackage.getLongVersionCode();
18002 final String internalPackageName;
18003 synchronized (mPackages) {
18004 // Normalize package name to handle renamed packages and static libs
18005 internalPackageName = resolveInternalPackageNameLPr(packageName, versionCode);
18008 final int uid = Binder.getCallingUid();
18009 if (!isOrphaned(internalPackageName)
18010 && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
18012 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
18013 intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
18014 intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
18015 observer.onUserActionRequired(intent);
18016 } catch (RemoteException re) {
18020 final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
18021 final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
18022 if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
18023 mContext.enforceCallingOrSelfPermission(
18024 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
18025 "deletePackage for user " + userId);
18028 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
18030 observer.onPackageDeleted(packageName,
18031 PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
18032 } catch (RemoteException re) {
18037 if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
18039 observer.onPackageDeleted(packageName,
18040 PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
18041 } catch (RemoteException re) {
18046 if (DEBUG_REMOVE) {
18047 Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
18048 + " deleteAllUsers: " + deleteAllUsers + " version="
18049 + (versionCode == PackageManager.VERSION_CODE_HIGHEST
18050 ? "VERSION_CODE_HIGHEST" : versionCode));
18052 // Queue up an async operation since the package deletion may take a little while.
18053 mHandler.post(new Runnable() {
18054 public void run() {
18055 mHandler.removeCallbacks(this);
18057 final PackageSetting ps = mSettings.mPackages.get(internalPackageName);
18058 boolean doDeletePackage = true;
18060 final boolean targetIsInstantApp =
18061 ps.getInstantApp(UserHandle.getUserId(callingUid));
18062 doDeletePackage = !targetIsInstantApp
18063 || canViewInstantApps;
18065 if (doDeletePackage) {
18066 if (!deleteAllUsers) {
18067 returnCode = deletePackageX(internalPackageName, versionCode,
18068 userId, deleteFlags);
18070 int[] blockUninstallUserIds = getBlockUninstallForUsers(
18071 internalPackageName, users);
18072 // If nobody is blocking uninstall, proceed with delete for all users
18073 if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
18074 returnCode = deletePackageX(internalPackageName, versionCode,
18075 userId, deleteFlags);
18077 // Otherwise uninstall individually for users with blockUninstalls=false
18078 final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
18079 for (int userId : users) {
18080 if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
18081 returnCode = deletePackageX(internalPackageName, versionCode,
18082 userId, userFlags);
18083 if (returnCode != PackageManager.DELETE_SUCCEEDED) {
18084 Slog.w(TAG, "Package delete failed for user " + userId
18085 + ", returnCode " + returnCode);
18089 // The app has only been marked uninstalled for certain users.
18090 // We still need to report that delete was blocked
18091 returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
18095 returnCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18098 observer.onPackageDeleted(packageName, returnCode, null);
18099 } catch (RemoteException e) {
18100 Log.i(TAG, "Observer no longer exists.");
18106 private String resolveExternalPackageNameLPr(PackageParser.Package pkg) {
18107 if (pkg.staticSharedLibName != null) {
18108 return pkg.manifestPackageName;
18110 return pkg.packageName;
18113 private String resolveInternalPackageNameLPr(String packageName, long versionCode) {
18114 // Handle renamed packages
18115 String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
18116 packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
18118 // Is this a static library?
18119 LongSparseArray<SharedLibraryEntry> versionedLib =
18120 mStaticLibsByDeclaringPackage.get(packageName);
18121 if (versionedLib == null || versionedLib.size() <= 0) {
18122 return packageName;
18125 // Figure out which lib versions the caller can see
18126 LongSparseLongArray versionsCallerCanSee = null;
18127 final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
18128 if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
18129 && callingAppId != Process.ROOT_UID) {
18130 versionsCallerCanSee = new LongSparseLongArray();
18131 String libName = versionedLib.valueAt(0).info.getName();
18132 String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
18133 if (uidPackages != null) {
18134 for (String uidPackage : uidPackages) {
18135 PackageSetting ps = mSettings.getPackageLPr(uidPackage);
18136 final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
18138 final long libVersion = ps.usesStaticLibrariesVersions[libIdx];
18139 versionsCallerCanSee.append(libVersion, libVersion);
18145 // Caller can see nothing - done
18146 if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
18147 return packageName;
18150 // Find the version the caller can see and the app version code
18151 SharedLibraryEntry highestVersion = null;
18152 final int versionCount = versionedLib.size();
18153 for (int i = 0; i < versionCount; i++) {
18154 SharedLibraryEntry libEntry = versionedLib.valueAt(i);
18155 if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
18156 libEntry.info.getLongVersion()) < 0) {
18159 final long libVersionCode = libEntry.info.getDeclaringPackage().getLongVersionCode();
18160 if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
18161 if (libVersionCode == versionCode) {
18162 return libEntry.apk;
18164 } else if (highestVersion == null) {
18165 highestVersion = libEntry;
18166 } else if (libVersionCode > highestVersion.info
18167 .getDeclaringPackage().getLongVersionCode()) {
18168 highestVersion = libEntry;
18172 if (highestVersion != null) {
18173 return highestVersion.apk;
18176 return packageName;
18179 boolean isCallerVerifier(int callingUid) {
18180 final int callingUserId = UserHandle.getUserId(callingUid);
18181 return mRequiredVerifierPackage != null &&
18182 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId);
18185 private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
18186 if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
18187 || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
18190 final int callingUserId = UserHandle.getUserId(callingUid);
18191 // If the caller installed the pkgName, then allow it to silently uninstall.
18192 if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
18196 // Allow package verifier to silently uninstall.
18197 if (mRequiredVerifierPackage != null &&
18198 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
18202 // Allow package uninstaller to silently uninstall.
18203 if (mRequiredUninstallerPackage != null &&
18204 callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
18208 // Allow storage manager to silently uninstall.
18209 if (mStorageManagerPackage != null &&
18210 callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
18214 // Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently
18215 // uninstall for device owner provisioning.
18216 if (checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid)
18217 == PERMISSION_GRANTED) {
18224 private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
18225 int[] result = EMPTY_INT_ARRAY;
18226 for (int userId : userIds) {
18227 if (getBlockUninstallForUser(packageName, userId)) {
18228 result = ArrayUtils.appendInt(result, userId);
18235 public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
18236 final int callingUid = Binder.getCallingUid();
18237 if (checkUidPermission(android.Manifest.permission.MANAGE_USERS, callingUid)
18238 != PERMISSION_GRANTED) {
18239 EventLog.writeEvent(0x534e4554, "128599183", -1, "");
18240 throw new SecurityException(android.Manifest.permission.MANAGE_USERS
18241 + " permission is required to call this API");
18243 if (getInstantAppPackageName(callingUid) != null
18244 && !isCallerSameApp(packageName, callingUid)) {
18247 return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
18250 private boolean isPackageDeviceAdmin(String packageName, int userId) {
18251 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
18252 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
18255 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
18256 /* callingUserOnly =*/ false);
18257 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
18258 : deviceOwnerComponentName.getPackageName();
18259 // Does the package contains the device owner?
18260 // TODO Do we have to do it even if userId != UserHandle.USER_ALL? Otherwise,
18261 // this check is probably not needed, since DO should be registered as a device
18262 // admin on some user too. (Original bug for this: b/17657954)
18263 if (packageName.equals(deviceOwnerPackageName)) {
18266 // Does it contain a device admin for any user?
18268 if (userId == UserHandle.USER_ALL) {
18269 users = sUserManager.getUserIds();
18271 users = new int[]{userId};
18273 for (int i = 0; i < users.length; ++i) {
18274 if (dpm.packageHasActiveAdmins(packageName, users[i])) {
18279 } catch (RemoteException e) {
18284 private boolean shouldKeepUninstalledPackageLPr(String packageName) {
18285 return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
18289 * This method is an internal method that could be get invoked either
18290 * to delete an installed package or to clean up a failed installation.
18291 * After deleting an installed package, a broadcast is sent to notify any
18292 * listeners that the package has been removed. For cleaning up a failed
18293 * installation, the broadcast is not necessary since the package's
18294 * installation wouldn't have sent the initial broadcast either
18295 * The key steps in deleting a package are
18296 * deleting the package information in internal structures like mPackages,
18297 * deleting the packages base directories through installd
18298 * updating mSettings to reflect current status
18299 * persisting settings for later use
18300 * sending a broadcast if necessary
18302 int deletePackageX(String packageName, long versionCode, int userId, int deleteFlags) {
18303 final PackageRemovedInfo info = new PackageRemovedInfo(this);
18306 final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
18307 ? UserHandle.USER_ALL : userId;
18309 if (isPackageDeviceAdmin(packageName, removeUser)) {
18310 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
18311 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
18314 PackageSetting uninstalledPs = null;
18315 PackageParser.Package pkg = null;
18317 // for the uninstall-updates case and restricted profiles, remember the per-
18318 // user handle installed state
18320 synchronized (mPackages) {
18321 uninstalledPs = mSettings.mPackages.get(packageName);
18322 if (uninstalledPs == null) {
18323 Slog.w(TAG, "Not removing non-existent package " + packageName);
18324 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18327 if (versionCode != PackageManager.VERSION_CODE_HIGHEST
18328 && uninstalledPs.versionCode != versionCode) {
18329 Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
18330 + uninstalledPs.versionCode + " != " + versionCode);
18331 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18334 // Static shared libs can be declared by any package, so let us not
18335 // allow removing a package if it provides a lib others depend on.
18336 pkg = mPackages.get(packageName);
18338 allUsers = sUserManager.getUserIds();
18340 if (pkg != null && pkg.staticSharedLibName != null) {
18341 SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName,
18342 pkg.staticSharedLibVersion);
18343 if (libEntry != null) {
18344 for (int currUserId : allUsers) {
18345 if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
18348 List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
18349 libEntry.info, MATCH_KNOWN_PACKAGES, currUserId);
18350 if (!ArrayUtils.isEmpty(libClientPackages)) {
18351 Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
18352 + " hosting lib " + libEntry.info.getName() + " version "
18353 + libEntry.info.getLongVersion() + " used by " + libClientPackages
18354 + " for user " + currUserId);
18355 return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
18361 info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
18364 final int freezeUser;
18365 if (isUpdatedSystemApp(uninstalledPs)
18366 && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
18367 // We're downgrading a system app, which will apply to all users, so
18368 // freeze them all during the downgrade
18369 freezeUser = UserHandle.USER_ALL;
18371 freezeUser = removeUser;
18374 synchronized (mInstallLock) {
18375 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
18376 try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
18377 deleteFlags, "deletePackageX")) {
18378 res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
18379 deleteFlags | PackageManager.DELETE_CHATTY, info, true, null);
18381 synchronized (mPackages) {
18384 mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
18386 updateSequenceNumberLP(uninstalledPs, info.removedUsers);
18387 updateInstantAppInstallerLocked(packageName);
18393 final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
18394 info.sendPackageRemovedBroadcasts(killApp);
18395 info.sendSystemPackageUpdatedBroadcasts();
18396 info.sendSystemPackageAppearedBroadcasts();
18398 // Force a gc here.
18399 Runtime.getRuntime().gc();
18400 // Delete the resources here after sending the broadcast to let
18401 // other processes clean up before deleting resources.
18402 if (info.args != null) {
18403 synchronized (mInstallLock) {
18404 info.args.doPostDeleteLI(true);
18408 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18411 static class PackageRemovedInfo {
18412 final PackageSender packageSender;
18413 String removedPackage;
18414 String installerPackageName;
18416 int removedAppId = -1;
18418 int[] removedUsers = null;
18419 int[] broadcastUsers = null;
18420 int[] instantUserIds = null;
18421 SparseArray<Integer> installReasons;
18422 boolean isRemovedPackageSystemUpdate = false;
18424 boolean dataRemoved;
18425 boolean removedForAllUsers;
18426 boolean isStaticSharedLib;
18427 // Clean up resources deleted packages.
18428 InstallArgs args = null;
18429 ArrayMap<String, PackageRemovedInfo> removedChildPackages;
18430 ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
18432 PackageRemovedInfo(PackageSender packageSender) {
18433 this.packageSender = packageSender;
18436 void sendPackageRemovedBroadcasts(boolean killApp) {
18437 sendPackageRemovedBroadcastInternal(killApp);
18438 final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
18439 for (int i = 0; i < childCount; i++) {
18440 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
18441 childInfo.sendPackageRemovedBroadcastInternal(killApp);
18445 void sendSystemPackageUpdatedBroadcasts() {
18446 if (isRemovedPackageSystemUpdate) {
18447 sendSystemPackageUpdatedBroadcastsInternal();
18448 final int childCount = (removedChildPackages != null)
18449 ? removedChildPackages.size() : 0;
18450 for (int i = 0; i < childCount; i++) {
18451 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
18452 if (childInfo.isRemovedPackageSystemUpdate) {
18453 childInfo.sendSystemPackageUpdatedBroadcastsInternal();
18459 void sendSystemPackageAppearedBroadcasts() {
18460 final int packageCount = (appearedChildPackages != null)
18461 ? appearedChildPackages.size() : 0;
18462 for (int i = 0; i < packageCount; i++) {
18463 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
18464 packageSender.sendPackageAddedForNewUsers(installedInfo.name,
18465 true /*sendBootCompleted*/, false /*startReceiver*/,
18466 UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers, null);
18470 private void sendSystemPackageUpdatedBroadcastsInternal() {
18471 Bundle extras = new Bundle(2);
18472 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
18473 extras.putBoolean(Intent.EXTRA_REPLACING, true);
18474 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
18475 removedPackage, extras, 0, null /*targetPackage*/, null, null, null);
18476 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
18477 removedPackage, extras, 0, null /*targetPackage*/, null, null, null);
18478 packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
18479 null, null, 0, removedPackage, null, null, null);
18480 if (installerPackageName != null) {
18481 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
18482 removedPackage, extras, 0 /*flags*/,
18483 installerPackageName, null, null, null);
18484 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
18485 removedPackage, extras, 0 /*flags*/,
18486 installerPackageName, null, null, null);
18490 private void sendPackageRemovedBroadcastInternal(boolean killApp) {
18491 // Don't send static shared library removal broadcasts as these
18492 // libs are visible only the the apps that depend on them an one
18493 // cannot remove the library if it has a dependency.
18494 if (isStaticSharedLib) {
18497 Bundle extras = new Bundle(2);
18498 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
18499 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
18500 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
18501 if (isUpdate || isRemovedPackageSystemUpdate) {
18502 extras.putBoolean(Intent.EXTRA_REPLACING, true);
18504 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
18505 if (removedPackage != null) {
18506 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
18507 removedPackage, extras, 0, null /*targetPackage*/, null,
18508 broadcastUsers, instantUserIds);
18509 if (installerPackageName != null) {
18510 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
18511 removedPackage, extras, 0 /*flags*/,
18512 installerPackageName, null, broadcastUsers, instantUserIds);
18514 if (dataRemoved && !isRemovedPackageSystemUpdate) {
18515 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
18516 removedPackage, extras,
18517 Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
18518 null, null, broadcastUsers, instantUserIds);
18519 packageSender.notifyPackageRemoved(removedPackage);
18522 if (removedAppId >= 0) {
18523 packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
18524 null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
18525 null, null, broadcastUsers, instantUserIds);
18529 void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
18530 removedUsers = userIds;
18531 if (removedUsers == null) {
18532 broadcastUsers = null;
18536 broadcastUsers = EMPTY_INT_ARRAY;
18537 instantUserIds = EMPTY_INT_ARRAY;
18538 for (int i = userIds.length - 1; i >= 0; --i) {
18539 final int userId = userIds[i];
18540 if (deletedPackageSetting.getInstantApp(userId)) {
18541 instantUserIds = ArrayUtils.appendInt(instantUserIds, userId);
18543 broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
18550 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
18551 * flag is not set, the data directory is removed as well.
18552 * make sure this flag is set for partially installed apps. If not its meaningless to
18553 * delete a partially installed application.
18555 private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
18556 PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
18557 String packageName = ps.name;
18558 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
18559 // Retrieve object to delete permissions for shared user later on
18560 final PackageParser.Package deletedPkg;
18561 final PackageSetting deletedPs;
18563 synchronized (mPackages) {
18564 deletedPkg = mPackages.get(packageName);
18565 deletedPs = mSettings.mPackages.get(packageName);
18566 if (outInfo != null) {
18567 outInfo.removedPackage = packageName;
18568 outInfo.installerPackageName = ps.installerPackageName;
18569 outInfo.isStaticSharedLib = deletedPkg != null
18570 && deletedPkg.staticSharedLibName != null;
18571 outInfo.populateUsers(deletedPs == null ? null
18572 : deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true), deletedPs);
18576 removePackageLI(ps, (flags & PackageManager.DELETE_CHATTY) != 0);
18578 if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
18579 final PackageParser.Package resolvedPkg;
18580 if (deletedPkg != null) {
18581 resolvedPkg = deletedPkg;
18583 // We don't have a parsed package when it lives on an ejected
18584 // adopted storage device, so fake something together
18585 resolvedPkg = new PackageParser.Package(ps.name);
18586 resolvedPkg.setVolumeUuid(ps.volumeUuid);
18588 destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
18589 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18590 destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
18591 if (outInfo != null) {
18592 outInfo.dataRemoved = true;
18594 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
18597 int removedAppId = -1;
18600 synchronized (mPackages) {
18601 boolean installedStateChanged = false;
18602 if (deletedPs != null) {
18603 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
18604 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL, true);
18605 clearDefaultBrowserIfNeeded(packageName);
18606 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
18607 removedAppId = mSettings.removePackageLPw(packageName);
18608 if (outInfo != null) {
18609 outInfo.removedAppId = removedAppId;
18611 mPermissionManager.updatePermissions(
18612 deletedPs.name, null, false, mPackages.values(), mPermissionCallback);
18613 if (deletedPs.sharedUser != null) {
18614 // Remove permissions associated with package. Since runtime
18615 // permissions are per user we have to kill the removed package
18616 // or packages running under the shared user of the removed
18617 // package if revoking the permissions requested only by the removed
18618 // package is successful and this causes a change in gids.
18619 for (int userId : UserManagerService.getInstance().getUserIds()) {
18620 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
18622 if (userIdToKill == UserHandle.USER_ALL
18623 || userIdToKill >= UserHandle.USER_SYSTEM) {
18624 // If gids changed for this user, kill all affected packages.
18625 mHandler.post(new Runnable() {
18627 public void run() {
18628 // This has to happen with no lock held.
18629 killApplication(deletedPs.name, deletedPs.appId,
18630 KILL_APP_REASON_GIDS_CHANGED);
18637 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
18639 // make sure to preserve per-user disabled state if this removal was just
18640 // a downgrade of a system app to the factory package
18641 if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
18642 if (DEBUG_REMOVE) {
18643 Slog.d(TAG, "Propagating install state across downgrade");
18645 for (int userId : allUserHandles) {
18646 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
18647 if (DEBUG_REMOVE) {
18648 Slog.d(TAG, " user " + userId + " => " + installed);
18650 if (installed != ps.getInstalled(userId)) {
18651 installedStateChanged = true;
18653 ps.setInstalled(installed, userId);
18657 // can downgrade to reader
18658 if (writeSettings) {
18659 // Save settings now
18660 mSettings.writeLPr();
18662 if (installedStateChanged) {
18663 mSettings.writeKernelMappingLPr(ps);
18666 if (removedAppId != -1) {
18667 // A user ID was deleted here. Go through all users and remove it
18669 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId);
18673 static boolean locationIsPrivileged(String path) {
18675 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
18676 final File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
18677 final File privilegedOdmAppDir = new File(Environment.getOdmDirectory(), "priv-app");
18678 final File privilegedProductAppDir = new File(Environment.getProductDirectory(), "priv-app");
18679 return path.startsWith(privilegedAppDir.getCanonicalPath())
18680 || path.startsWith(privilegedVendorAppDir.getCanonicalPath())
18681 || path.startsWith(privilegedOdmAppDir.getCanonicalPath())
18682 || path.startsWith(privilegedProductAppDir.getCanonicalPath());
18683 } catch (IOException e) {
18684 Slog.e(TAG, "Unable to access code path " + path);
18689 static boolean locationIsOem(String path) {
18691 return path.startsWith(Environment.getOemDirectory().getCanonicalPath());
18692 } catch (IOException e) {
18693 Slog.e(TAG, "Unable to access code path " + path);
18698 static boolean locationIsVendor(String path) {
18700 return path.startsWith(Environment.getVendorDirectory().getCanonicalPath())
18701 || path.startsWith(Environment.getOdmDirectory().getCanonicalPath());
18702 } catch (IOException e) {
18703 Slog.e(TAG, "Unable to access code path " + path);
18708 static boolean locationIsProduct(String path) {
18710 return path.startsWith(Environment.getProductDirectory().getCanonicalPath());
18711 } catch (IOException e) {
18712 Slog.e(TAG, "Unable to access code path " + path);
18718 * Tries to delete system package.
18720 private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
18721 PackageSetting deletedPs, int[] allUserHandles, int flags,
18722 @Nullable PackageRemovedInfo outInfo,
18723 boolean writeSettings) {
18724 if (deletedPs.parentPackageName != null) {
18725 Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
18729 final boolean applyUserRestrictions
18730 = (allUserHandles != null) && outInfo != null && (outInfo.origUsers != null);
18731 final PackageSetting disabledPs;
18732 // Confirm if the system package has been updated
18733 // An updated system app can be deleted. This will also have to restore
18734 // the system pkg from system partition
18736 synchronized (mPackages) {
18737 disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
18740 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
18741 + " disabledPs=" + disabledPs);
18743 if (disabledPs == null) {
18744 Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
18746 } else if (DEBUG_REMOVE) {
18747 Slog.d(TAG, "Deleting system pkg from data partition");
18750 if (DEBUG_REMOVE) {
18751 if (applyUserRestrictions) {
18752 Slog.d(TAG, "Remembering install states:");
18753 for (int userId : allUserHandles) {
18754 final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
18755 Slog.d(TAG, " u=" + userId + " inst=" + finstalled);
18760 if (outInfo != null) {
18761 // Delete the updated package
18762 outInfo.isRemovedPackageSystemUpdate = true;
18763 if (outInfo.removedChildPackages != null) {
18764 final int childCount = (deletedPs.childPackageNames != null)
18765 ? deletedPs.childPackageNames.size() : 0;
18766 for (int i = 0; i < childCount; i++) {
18767 String childPackageName = deletedPs.childPackageNames.get(i);
18768 if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
18769 .contains(childPackageName)) {
18770 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
18772 if (childInfo != null) {
18773 childInfo.isRemovedPackageSystemUpdate = true;
18780 if (disabledPs.versionCode < deletedPs.versionCode) {
18781 // Delete data for downgrades
18782 flags &= ~PackageManager.DELETE_KEEP_DATA;
18784 // Preserve data by setting flag
18785 flags |= PackageManager.DELETE_KEEP_DATA;
18788 boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
18789 outInfo, writeSettings, disabledPs.pkg);
18795 synchronized (mPackages) {
18796 // NOTE: The system package always needs to be enabled; even if it's for
18797 // a compressed stub. If we don't, installing the system package fails
18798 // during scan [scanning checks the disabled packages]. We will reverse
18799 // this later, after we've "installed" the stub.
18800 // Reinstate the old system package
18801 enableSystemPackageLPw(disabledPs.pkg);
18802 // Remove any native libraries from the upgraded package.
18803 removeNativeBinariesLI(deletedPs);
18806 // Install the system package
18807 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
18809 installPackageFromSystemLIF(disabledPs.codePathString, false, allUserHandles,
18810 outInfo.origUsers, deletedPs.getPermissionsState(), writeSettings);
18811 } catch (PackageManagerException e) {
18812 Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
18816 if (disabledPs.pkg.isStub) {
18817 mSettings.disableSystemPackageLPw(disabledPs.name, true /*replaced*/);
18824 * Installs a package that's already on the system partition.
18826 private PackageParser.Package installPackageFromSystemLIF(@NonNull String codePathString,
18827 boolean isPrivileged, @Nullable int[] allUserHandles, @Nullable int[] origUserHandles,
18828 @Nullable PermissionsState origPermissionState, boolean writeSettings)
18829 throws PackageManagerException {
18830 @ParseFlags int parseFlags =
18832 | PackageParser.PARSE_MUST_BE_APK
18833 | PackageParser.PARSE_IS_SYSTEM_DIR;
18834 @ScanFlags int scanFlags = SCAN_AS_SYSTEM;
18835 if (isPrivileged || locationIsPrivileged(codePathString)) {
18836 scanFlags |= SCAN_AS_PRIVILEGED;
18838 if (locationIsOem(codePathString)) {
18839 scanFlags |= SCAN_AS_OEM;
18841 if (locationIsVendor(codePathString)) {
18842 scanFlags |= SCAN_AS_VENDOR;
18844 if (locationIsProduct(codePathString)) {
18845 scanFlags |= SCAN_AS_PRODUCT;
18848 final File codePath = new File(codePathString);
18849 final PackageParser.Package pkg =
18850 scanPackageTracedLI(codePath, parseFlags, scanFlags, 0 /*currentTime*/, null);
18853 // update shared libraries for the newly re-installed system package
18854 updateSharedLibrariesLPr(pkg, null);
18855 } catch (PackageManagerException e) {
18856 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
18859 prepareAppDataAfterInstallLIF(pkg);
18862 synchronized (mPackages) {
18863 PackageSetting ps = mSettings.mPackages.get(pkg.packageName);
18865 // Propagate the permissions state as we do not want to drop on the floor
18866 // runtime permissions. The update permissions method below will take
18867 // care of removing obsolete permissions and grant install permissions.
18868 if (origPermissionState != null) {
18869 ps.getPermissionsState().copyFrom(origPermissionState);
18871 mPermissionManager.updatePermissions(pkg.packageName, pkg, true, mPackages.values(),
18872 mPermissionCallback);
18874 final boolean applyUserRestrictions
18875 = (allUserHandles != null) && (origUserHandles != null);
18876 if (applyUserRestrictions) {
18877 boolean installedStateChanged = false;
18878 if (DEBUG_REMOVE) {
18879 Slog.d(TAG, "Propagating install state across reinstall");
18881 for (int userId : allUserHandles) {
18882 final boolean installed = ArrayUtils.contains(origUserHandles, userId);
18883 if (DEBUG_REMOVE) {
18884 Slog.d(TAG, " user " + userId + " => " + installed);
18886 if (installed != ps.getInstalled(userId)) {
18887 installedStateChanged = true;
18889 ps.setInstalled(installed, userId);
18891 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
18893 // Regardless of writeSettings we need to ensure that this restriction
18894 // state propagation is persisted
18895 mSettings.writeAllUsersPackageRestrictionsLPr();
18896 if (installedStateChanged) {
18897 mSettings.writeKernelMappingLPr(ps);
18900 // can downgrade to reader here
18901 if (writeSettings) {
18902 mSettings.writeLPr();
18908 private boolean deleteInstalledPackageLIF(PackageSetting ps,
18909 boolean deleteCodeAndResources, int flags, int[] allUserHandles,
18910 PackageRemovedInfo outInfo, boolean writeSettings,
18911 PackageParser.Package replacingPackage) {
18912 synchronized (mPackages) {
18913 if (outInfo != null) {
18914 outInfo.uid = ps.appId;
18917 if (outInfo != null && outInfo.removedChildPackages != null) {
18918 final int childCount = (ps.childPackageNames != null)
18919 ? ps.childPackageNames.size() : 0;
18920 for (int i = 0; i < childCount; i++) {
18921 String childPackageName = ps.childPackageNames.get(i);
18922 PackageSetting childPs = mSettings.mPackages.get(childPackageName);
18923 if (childPs == null) {
18926 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
18928 if (childInfo != null) {
18929 childInfo.uid = childPs.appId;
18935 // Delete package data from internal structures and also remove data if flag is set
18936 removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
18938 // Delete the child packages data
18939 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
18940 for (int i = 0; i < childCount; i++) {
18941 PackageSetting childPs;
18942 synchronized (mPackages) {
18943 childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
18945 if (childPs != null) {
18946 PackageRemovedInfo childOutInfo = (outInfo != null
18947 && outInfo.removedChildPackages != null)
18948 ? outInfo.removedChildPackages.get(childPs.name) : null;
18949 final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
18950 && (replacingPackage != null
18951 && !replacingPackage.hasChildPackage(childPs.name))
18952 ? flags & ~DELETE_KEEP_DATA : flags;
18953 removePackageDataLIF(childPs, allUserHandles, childOutInfo,
18954 deleteFlags, writeSettings);
18958 // Delete application code and resources only for parent packages
18959 if (ps.parentPackageName == null) {
18960 if (deleteCodeAndResources && (outInfo != null)) {
18961 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
18962 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
18963 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
18971 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
18973 mContext.enforceCallingOrSelfPermission(
18974 android.Manifest.permission.DELETE_PACKAGES, null);
18975 synchronized (mPackages) {
18976 // Cannot block uninstall of static shared libs as they are
18977 // considered a part of the using app (emulating static linking).
18978 // Also static libs are installed always on internal storage.
18979 PackageParser.Package pkg = mPackages.get(packageName);
18980 if (pkg != null && pkg.staticSharedLibName != null) {
18981 Slog.w(TAG, "Cannot block uninstall of package: " + packageName
18982 + " providing static shared library: " + pkg.staticSharedLibName);
18985 mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
18986 mSettings.writePackageRestrictionsLPr(userId);
18992 public boolean getBlockUninstallForUser(String packageName, int userId) {
18993 synchronized (mPackages) {
18994 final PackageSetting ps = mSettings.mPackages.get(packageName);
18995 if (ps == null || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
18998 return mSettings.getBlockUninstallLPr(userId, packageName);
19003 public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
19004 enforceSystemOrRoot("setRequiredForSystemUser can only be run by the system or root");
19005 synchronized (mPackages) {
19006 PackageSetting ps = mSettings.mPackages.get(packageName);
19008 Log.w(TAG, "Package doesn't exist: " + packageName);
19011 if (systemUserApp) {
19012 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
19014 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
19016 mSettings.writeLPr();
19022 * This method handles package deletion in general
19024 private boolean deletePackageLIF(String packageName, UserHandle user,
19025 boolean deleteCodeAndResources, int[] allUserHandles, int flags,
19026 PackageRemovedInfo outInfo, boolean writeSettings,
19027 PackageParser.Package replacingPackage) {
19028 if (packageName == null) {
19029 Slog.w(TAG, "Attempt to delete null packageName.");
19033 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
19036 synchronized (mPackages) {
19037 ps = mSettings.mPackages.get(packageName);
19039 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
19043 if (ps.parentPackageName != null && (!isSystemApp(ps)
19044 || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
19045 if (DEBUG_REMOVE) {
19046 Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
19047 + ((user == null) ? UserHandle.USER_ALL : user));
19049 final int removedUserId = (user != null) ? user.getIdentifier()
19050 : UserHandle.USER_ALL;
19052 if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
19055 markPackageUninstalledForUserLPw(ps, user);
19056 scheduleWritePackageRestrictionsLocked(user);
19061 final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
19062 if (ps.getPermissionsState().hasPermission(Manifest.permission.SUSPEND_APPS, userId)) {
19063 unsuspendForSuspendingPackage(packageName, userId);
19067 if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
19068 && user.getIdentifier() != UserHandle.USER_ALL)) {
19069 // The caller is asking that the package only be deleted for a single
19070 // user. To do this, we just mark its uninstalled state and delete
19071 // its data. If this is a system app, we only allow this to happen if
19072 // they have set the special DELETE_SYSTEM_APP which requests different
19073 // semantics than normal for uninstalling system apps.
19074 markPackageUninstalledForUserLPw(ps, user);
19076 if (!isSystemApp(ps)) {
19077 // Do not uninstall the APK if an app should be cached
19078 boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
19079 if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
19080 // Other user still have this package installed, so all
19081 // we need to do is clear this user's data and save that
19082 // it is uninstalled.
19083 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
19084 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
19087 scheduleWritePackageRestrictionsLocked(user);
19090 // We need to set it back to 'installed' so the uninstall
19091 // broadcasts will be sent correctly.
19092 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
19093 ps.setInstalled(true, user.getIdentifier());
19094 mSettings.writeKernelMappingLPr(ps);
19097 // This is a system app, so we assume that the
19098 // other users still have this package installed, so all
19099 // we need to do is clear this user's data and save that
19100 // it is uninstalled.
19101 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
19102 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
19105 scheduleWritePackageRestrictionsLocked(user);
19110 // If we are deleting a composite package for all users, keep track
19111 // of result for each child.
19112 if (ps.childPackageNames != null && outInfo != null) {
19113 synchronized (mPackages) {
19114 final int childCount = ps.childPackageNames.size();
19115 outInfo.removedChildPackages = new ArrayMap<>(childCount);
19116 for (int i = 0; i < childCount; i++) {
19117 String childPackageName = ps.childPackageNames.get(i);
19118 PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
19119 childInfo.removedPackage = childPackageName;
19120 childInfo.installerPackageName = ps.installerPackageName;
19121 outInfo.removedChildPackages.put(childPackageName, childInfo);
19122 PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
19123 if (childPs != null) {
19124 childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
19130 boolean ret = false;
19131 if (isSystemApp(ps)) {
19132 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
19133 // When an updated system application is deleted we delete the existing resources
19134 // as well and fall back to existing code in system partition
19135 ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
19137 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
19138 ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
19139 outInfo, writeSettings, replacingPackage);
19142 // Take a note whether we deleted the package for all users
19143 if (outInfo != null) {
19144 outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
19145 if (outInfo.removedChildPackages != null) {
19146 synchronized (mPackages) {
19147 final int childCount = outInfo.removedChildPackages.size();
19148 for (int i = 0; i < childCount; i++) {
19149 PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
19150 if (childInfo != null) {
19151 childInfo.removedForAllUsers = mPackages.get(
19152 childInfo.removedPackage) == null;
19157 // If we uninstalled an update to a system app there may be some
19158 // child packages that appeared as they are declared in the system
19159 // app but were not declared in the update.
19160 if (isSystemApp(ps)) {
19161 synchronized (mPackages) {
19162 PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
19163 final int childCount = (updatedPs.childPackageNames != null)
19164 ? updatedPs.childPackageNames.size() : 0;
19165 for (int i = 0; i < childCount; i++) {
19166 String childPackageName = updatedPs.childPackageNames.get(i);
19167 if (outInfo.removedChildPackages == null
19168 || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
19169 PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
19170 if (childPs == null) {
19173 PackageInstalledInfo installRes = new PackageInstalledInfo();
19174 installRes.name = childPackageName;
19175 installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
19176 installRes.pkg = mPackages.get(childPackageName);
19177 installRes.uid = childPs.pkg.applicationInfo.uid;
19178 if (outInfo.appearedChildPackages == null) {
19179 outInfo.appearedChildPackages = new ArrayMap<>();
19181 outInfo.appearedChildPackages.put(childPackageName, installRes);
19191 private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
19192 final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
19193 ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
19194 for (int nextUserId : userIds) {
19195 if (DEBUG_REMOVE) {
19196 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
19198 ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
19199 false /*installed*/,
19201 true /*notLaunched*/,
19203 false /*suspended*/,
19204 null /*suspendingPackage*/,
19205 null /*dialogMessage*/,
19206 null /*suspendedAppExtras*/,
19207 null /*suspendedLauncherExtras*/,
19208 false /*instantApp*/,
19209 false /*virtualPreload*/,
19210 null /*lastDisableAppCaller*/,
19211 null /*enabledComponents*/,
19212 null /*disabledComponents*/,
19213 ps.readUserState(nextUserId).domainVerificationStatus,
19214 0, PackageManager.INSTALL_REASON_UNKNOWN,
19215 null /*harmfulAppWarning*/);
19217 mSettings.writeKernelMappingLPr(ps);
19220 private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
19221 PackageRemovedInfo outInfo) {
19222 final PackageParser.Package pkg;
19223 synchronized (mPackages) {
19224 pkg = mPackages.get(ps.name);
19227 final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
19228 : new int[] {userId};
19229 for (int nextUserId : userIds) {
19230 if (DEBUG_REMOVE) {
19231 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
19235 destroyAppDataLIF(pkg, userId,
19236 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19237 destroyAppProfilesLIF(pkg, userId);
19238 clearDefaultBrowserIfNeededForUser(ps.name, userId);
19239 removeKeystoreDataIfNeeded(nextUserId, ps.appId);
19240 schedulePackageCleaning(ps.name, nextUserId, false);
19241 synchronized (mPackages) {
19242 if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
19243 scheduleWritePackageRestrictionsLocked(nextUserId);
19245 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
19249 if (outInfo != null) {
19250 outInfo.removedPackage = ps.name;
19251 outInfo.installerPackageName = ps.installerPackageName;
19252 outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
19253 outInfo.removedAppId = ps.appId;
19254 outInfo.removedUsers = userIds;
19255 outInfo.broadcastUsers = userIds;
19261 private final class ClearStorageConnection implements ServiceConnection {
19262 IMediaContainerService mContainerService;
19265 public void onServiceConnected(ComponentName name, IBinder service) {
19266 synchronized (this) {
19267 mContainerService = IMediaContainerService.Stub
19268 .asInterface(Binder.allowBlocking(service));
19274 public void onServiceDisconnected(ComponentName name) {
19278 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
19279 if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
19281 final boolean mounted;
19282 if (Environment.isExternalStorageEmulated()) {
19285 final String status = Environment.getExternalStorageState();
19287 mounted = status.equals(Environment.MEDIA_MOUNTED)
19288 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
19295 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
19297 if (userId == UserHandle.USER_ALL) {
19298 users = sUserManager.getUserIds();
19300 users = new int[] { userId };
19302 final ClearStorageConnection conn = new ClearStorageConnection();
19303 if (mContext.bindServiceAsUser(
19304 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
19306 for (int curUser : users) {
19307 long timeout = SystemClock.uptimeMillis() + 5000;
19308 synchronized (conn) {
19310 while (conn.mContainerService == null &&
19311 (now = SystemClock.uptimeMillis()) < timeout) {
19313 conn.wait(timeout - now);
19314 } catch (InterruptedException e) {
19318 if (conn.mContainerService == null) {
19322 final UserEnvironment userEnv = new UserEnvironment(curUser);
19323 clearDirectory(conn.mContainerService,
19324 userEnv.buildExternalStorageAppCacheDirs(packageName));
19326 clearDirectory(conn.mContainerService,
19327 userEnv.buildExternalStorageAppDataDirs(packageName));
19328 clearDirectory(conn.mContainerService,
19329 userEnv.buildExternalStorageAppMediaDirs(packageName));
19333 mContext.unbindService(conn);
19339 public void clearApplicationProfileData(String packageName) {
19340 enforceSystemOrRoot("Only the system can clear all profile data");
19342 final PackageParser.Package pkg;
19343 synchronized (mPackages) {
19344 pkg = mPackages.get(packageName);
19347 try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
19348 synchronized (mInstallLock) {
19349 clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
19355 public void clearApplicationUserData(final String packageName,
19356 final IPackageDataObserver observer, final int userId) {
19357 mContext.enforceCallingOrSelfPermission(
19358 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
19360 final int callingUid = Binder.getCallingUid();
19361 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
19362 true /* requireFullPermission */, false /* checkShell */, "clear application data");
19364 final PackageSetting ps = mSettings.getPackageLPr(packageName);
19365 final boolean filterApp = (ps != null && filterAppAccessLPr(ps, callingUid, userId));
19366 if (!filterApp && mProtectedPackages.isPackageDataProtected(userId, packageName)) {
19367 throw new SecurityException("Cannot clear data for a protected package: "
19370 // Queue up an async operation since the package deletion may take a little while.
19371 mHandler.post(new Runnable() {
19372 public void run() {
19373 mHandler.removeCallbacks(this);
19374 final boolean succeeded;
19376 try (PackageFreezer freezer = freezePackage(packageName,
19377 "clearApplicationUserData")) {
19378 synchronized (mInstallLock) {
19379 succeeded = clearApplicationUserDataLIF(packageName, userId);
19381 clearExternalStorageDataSync(packageName, userId, true);
19382 synchronized (mPackages) {
19383 mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
19384 packageName, userId);
19388 // invoke DeviceStorageMonitor's update method to clear any notifications
19389 DeviceStorageMonitorInternal dsm = LocalServices
19390 .getService(DeviceStorageMonitorInternal.class);
19394 if (checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId)
19395 == PERMISSION_GRANTED) {
19396 unsuspendForSuspendingPackage(packageName, userId);
19402 if (observer != null) {
19404 observer.onRemoveCompleted(packageName, succeeded);
19405 } catch (RemoteException e) {
19406 Log.i(TAG, "Observer no longer exists.");
19408 } //end if observer
19413 private boolean clearApplicationUserDataLIF(String packageName, int userId) {
19414 if (packageName == null) {
19415 Slog.w(TAG, "Attempt to delete null packageName.");
19419 // Try finding details about the requested package
19420 PackageParser.Package pkg;
19421 synchronized (mPackages) {
19422 pkg = mPackages.get(packageName);
19424 final PackageSetting ps = mSettings.mPackages.get(packageName);
19431 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
19435 PackageSetting ps = (PackageSetting) pkg.mExtras;
19436 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
19439 clearAppDataLIF(pkg, userId,
19440 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19442 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
19443 removeKeystoreDataIfNeeded(userId, appId);
19445 UserManagerInternal umInternal = getUserManagerInternal();
19447 if (umInternal.isUserUnlockingOrUnlocked(userId)) {
19448 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
19449 } else if (umInternal.isUserRunning(userId)) {
19450 flags = StorageManager.FLAG_STORAGE_DE;
19454 prepareAppDataContentsLIF(pkg, userId, flags);
19460 * Reverts user permission state changes (permissions and flags) in
19461 * all packages for a given user.
19463 * @param userId The device user for which to do a reset.
19465 private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
19466 final int packageCount = mPackages.size();
19467 for (int i = 0; i < packageCount; i++) {
19468 PackageParser.Package pkg = mPackages.valueAt(i);
19469 PackageSetting ps = (PackageSetting) pkg.mExtras;
19470 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
19474 private void resetNetworkPolicies(int userId) {
19475 LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
19479 * Reverts user permission state changes (permissions and flags).
19481 * @param ps The package for which to reset.
19482 * @param userId The device user for which to do a reset.
19484 private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
19485 final PackageSetting ps, final int userId) {
19486 if (ps.pkg == null) {
19490 // These are flags that can change base on user actions.
19491 final int userSettableMask = FLAG_PERMISSION_USER_SET
19492 | FLAG_PERMISSION_USER_FIXED
19493 | FLAG_PERMISSION_REVOKE_ON_UPGRADE
19494 | FLAG_PERMISSION_REVIEW_REQUIRED;
19496 final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
19497 | FLAG_PERMISSION_POLICY_FIXED;
19499 boolean writeInstallPermissions = false;
19500 boolean writeRuntimePermissions = false;
19502 final int permissionCount = ps.pkg.requestedPermissions.size();
19503 for (int i = 0; i < permissionCount; i++) {
19504 final String permName = ps.pkg.requestedPermissions.get(i);
19505 final BasePermission bp =
19506 (BasePermission) mPermissionManager.getPermissionTEMP(permName);
19511 // If shared user we just reset the state to which only this app contributed.
19512 if (ps.sharedUser != null) {
19513 boolean used = false;
19514 final int packageCount = ps.sharedUser.packages.size();
19515 for (int j = 0; j < packageCount; j++) {
19516 PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
19517 if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
19518 && pkg.pkg.requestedPermissions.contains(permName)) {
19528 final PermissionsState permissionsState = ps.getPermissionsState();
19530 final int oldFlags = permissionsState.getPermissionFlags(permName, userId);
19532 // Always clear the user settable flags.
19533 final boolean hasInstallState =
19534 permissionsState.getInstallPermissionState(permName) != null;
19535 // If permission review is enabled and this is a legacy app, mark the
19536 // permission as requiring a review as this is the initial state.
19538 if (mSettings.mPermissions.mPermissionReviewRequired
19539 && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
19540 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
19542 if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
19543 if (hasInstallState) {
19544 writeInstallPermissions = true;
19546 writeRuntimePermissions = true;
19550 // Below is only runtime permission handling.
19551 if (!bp.isRuntime()) {
19555 // Never clobber system or policy.
19556 if ((oldFlags & policyOrSystemFlags) != 0) {
19560 // If this permission was granted by default, make sure it is.
19561 if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
19562 if (permissionsState.grantRuntimePermission(bp, userId)
19563 != PERMISSION_OPERATION_FAILURE) {
19564 writeRuntimePermissions = true;
19566 // If permission review is enabled the permissions for a legacy apps
19567 // are represented as constantly granted runtime ones, so don't revoke.
19568 } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
19569 // Otherwise, reset the permission.
19570 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
19571 switch (revokeResult) {
19572 case PERMISSION_OPERATION_SUCCESS:
19573 case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
19574 writeRuntimePermissions = true;
19575 final int appId = ps.appId;
19576 mHandler.post(new Runnable() {
19578 public void run() {
19579 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
19587 // Synchronously write as we are taking permissions away.
19588 if (writeRuntimePermissions) {
19589 mSettings.writeRuntimePermissionsForUserLPr(userId, true);
19592 // Synchronously write as we are taking permissions away.
19593 if (writeInstallPermissions) {
19594 mSettings.writeLPr();
19599 * Remove entries from the keystore daemon. Will only remove it if the
19600 * {@code appId} is valid.
19602 private static void removeKeystoreDataIfNeeded(int userId, int appId) {
19607 final KeyStore keyStore = KeyStore.getInstance();
19608 if (keyStore != null) {
19609 if (userId == UserHandle.USER_ALL) {
19610 for (final int individual : sUserManager.getUserIds()) {
19611 keyStore.clearUid(UserHandle.getUid(individual, appId));
19614 keyStore.clearUid(UserHandle.getUid(userId, appId));
19617 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
19622 public void deleteApplicationCacheFiles(final String packageName,
19623 final IPackageDataObserver observer) {
19624 final int userId = UserHandle.getCallingUserId();
19625 deleteApplicationCacheFilesAsUser(packageName, userId, observer);
19629 public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
19630 final IPackageDataObserver observer) {
19631 final int callingUid = Binder.getCallingUid();
19632 if (mContext.checkCallingOrSelfPermission(
19633 android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES)
19634 != PackageManager.PERMISSION_GRANTED) {
19635 // If the caller has the old delete cache permission, silently ignore. Else throw.
19636 if (mContext.checkCallingOrSelfPermission(
19637 android.Manifest.permission.DELETE_CACHE_FILES)
19638 == PackageManager.PERMISSION_GRANTED) {
19639 Slog.w(TAG, "Calling uid " + callingUid + " does not have " +
19640 android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES +
19641 ", silently ignoring");
19644 mContext.enforceCallingOrSelfPermission(
19645 android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES, null);
19647 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
19648 /* requireFullPermission= */ true, /* checkShell= */ false,
19649 "delete application cache files");
19650 final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
19651 android.Manifest.permission.ACCESS_INSTANT_APPS);
19653 final PackageParser.Package pkg;
19654 synchronized (mPackages) {
19655 pkg = mPackages.get(packageName);
19658 // Queue up an async operation since the package deletion may take a little while.
19659 mHandler.post(new Runnable() {
19660 public void run() {
19661 final PackageSetting ps = pkg == null ? null : (PackageSetting) pkg.mExtras;
19662 boolean doClearData = true;
19664 final boolean targetIsInstantApp =
19665 ps.getInstantApp(UserHandle.getUserId(callingUid));
19666 doClearData = !targetIsInstantApp
19667 || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
19670 synchronized (mInstallLock) {
19671 final int flags = StorageManager.FLAG_STORAGE_DE
19672 | StorageManager.FLAG_STORAGE_CE;
19673 // We're only clearing cache files, so we don't care if the
19674 // app is unfrozen and still able to run
19675 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
19676 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
19678 clearExternalStorageDataSync(packageName, userId, false);
19680 if (observer != null) {
19682 observer.onRemoveCompleted(packageName, true);
19683 } catch (RemoteException e) {
19684 Log.i(TAG, "Observer no longer exists.");
19692 public void getPackageSizeInfo(final String packageName, int userHandle,
19693 final IPackageStatsObserver observer) {
19694 throw new UnsupportedOperationException(
19695 "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
19698 private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
19699 final PackageSetting ps;
19700 synchronized (mPackages) {
19701 ps = mSettings.mPackages.get(packageName);
19703 Slog.w(TAG, "Failed to find settings for " + packageName);
19708 final String[] packageNames = { packageName };
19709 final long[] ceDataInodes = { ps.getCeDataInode(userId) };
19710 final String[] codePaths = { ps.codePathString };
19713 mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
19714 ps.appId, ceDataInodes, codePaths, stats);
19716 // For now, ignore code size of packages on system partition
19717 if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
19718 stats.codeSize = 0;
19721 // External clients expect these to be tracked separately
19722 stats.dataSize -= stats.cacheSize;
19724 } catch (InstallerException e) {
19725 Slog.w(TAG, String.valueOf(e));
19732 private int getUidTargetSdkVersionLockedLPr(int uid) {
19733 Object obj = mSettings.getUserIdLPr(uid);
19734 if (obj instanceof SharedUserSetting) {
19735 final SharedUserSetting sus = (SharedUserSetting) obj;
19736 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
19737 final Iterator<PackageSetting> it = sus.packages.iterator();
19738 while (it.hasNext()) {
19739 final PackageSetting ps = it.next();
19740 if (ps.pkg != null) {
19741 int v = ps.pkg.applicationInfo.targetSdkVersion;
19742 if (v < vers) vers = v;
19746 } else if (obj instanceof PackageSetting) {
19747 final PackageSetting ps = (PackageSetting) obj;
19748 if (ps.pkg != null) {
19749 return ps.pkg.applicationInfo.targetSdkVersion;
19752 return Build.VERSION_CODES.CUR_DEVELOPMENT;
19755 private int getPackageTargetSdkVersionLockedLPr(String packageName) {
19756 final PackageParser.Package p = mPackages.get(packageName);
19758 return p.applicationInfo.targetSdkVersion;
19760 return Build.VERSION_CODES.CUR_DEVELOPMENT;
19764 public void addPreferredActivity(IntentFilter filter, int match,
19765 ComponentName[] set, ComponentName activity, int userId) {
19766 addPreferredActivityInternal(filter, match, set, activity, true, userId,
19767 "Adding preferred");
19770 private void addPreferredActivityInternal(IntentFilter filter, int match,
19771 ComponentName[] set, ComponentName activity, boolean always, int userId,
19774 int callingUid = Binder.getCallingUid();
19775 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
19776 true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
19777 if (filter.countActions() == 0) {
19778 Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19781 synchronized (mPackages) {
19782 if (mContext.checkCallingOrSelfPermission(
19783 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19784 != PackageManager.PERMISSION_GRANTED) {
19785 if (getUidTargetSdkVersionLockedLPr(callingUid)
19786 < Build.VERSION_CODES.FROYO) {
19787 Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
19791 mContext.enforceCallingOrSelfPermission(
19792 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19795 PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
19796 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
19798 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
19799 pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
19800 scheduleWritePackageRestrictionsLocked(userId);
19801 postPreferredActivityChangedBroadcast(userId);
19805 private void postPreferredActivityChangedBroadcast(int userId) {
19806 mHandler.post(() -> {
19807 final IActivityManager am = ActivityManager.getService();
19812 final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
19813 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19815 am.broadcastIntent(null, intent, null, null,
19816 0, null, null, null, android.app.AppOpsManager.OP_NONE,
19817 null, false, false, userId);
19818 } catch (RemoteException e) {
19824 public void replacePreferredActivity(IntentFilter filter, int match,
19825 ComponentName[] set, ComponentName activity, int userId) {
19826 if (filter.countActions() != 1) {
19827 throw new IllegalArgumentException(
19828 "replacePreferredActivity expects filter to have only 1 action.");
19830 if (filter.countDataAuthorities() != 0
19831 || filter.countDataPaths() != 0
19832 || filter.countDataSchemes() > 1
19833 || filter.countDataTypes() != 0) {
19834 throw new IllegalArgumentException(
19835 "replacePreferredActivity expects filter to have no data authorities, " +
19836 "paths, or types; and at most one scheme.");
19839 final int callingUid = Binder.getCallingUid();
19840 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
19841 true /* requireFullPermission */, false /* checkShell */,
19842 "replace preferred activity");
19843 synchronized (mPackages) {
19844 if (mContext.checkCallingOrSelfPermission(
19845 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19846 != PackageManager.PERMISSION_GRANTED) {
19847 if (getUidTargetSdkVersionLockedLPr(callingUid)
19848 < Build.VERSION_CODES.FROYO) {
19849 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
19850 + Binder.getCallingUid());
19853 mContext.enforceCallingOrSelfPermission(
19854 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19857 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19859 // Get all of the existing entries that exactly match this filter.
19860 ArrayList<PreferredActivity> existing = pir.findFilters(filter);
19861 if (existing != null && existing.size() == 1) {
19862 PreferredActivity cur = existing.get(0);
19863 if (DEBUG_PREFERRED) {
19864 Slog.i(TAG, "Checking replace of preferred:");
19865 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
19866 if (!cur.mPref.mAlways) {
19867 Slog.i(TAG, " -- CUR; not mAlways!");
19869 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch);
19870 Slog.i(TAG, " -- CUR: mSet="
19871 + Arrays.toString(cur.mPref.mSetComponents));
19872 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent);
19873 Slog.i(TAG, " -- NEW: mMatch="
19874 + (match&IntentFilter.MATCH_CATEGORY_MASK));
19875 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set));
19876 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString());
19879 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
19880 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
19881 && cur.mPref.sameSet(set)) {
19882 // Setting the preferred activity to what it happens to be already
19883 if (DEBUG_PREFERRED) {
19884 Slog.i(TAG, "Replacing with same preferred activity "
19885 + cur.mPref.mShortComponent + " for user "
19887 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
19893 if (existing != null) {
19894 if (DEBUG_PREFERRED) {
19895 Slog.i(TAG, existing.size() + " existing preferred matches for:");
19896 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
19898 for (int i = 0; i < existing.size(); i++) {
19899 PreferredActivity pa = existing.get(i);
19900 if (DEBUG_PREFERRED) {
19901 Slog.i(TAG, "Removing existing preferred activity "
19902 + pa.mPref.mComponent + ":");
19903 pa.dump(new LogPrinter(Log.INFO, TAG), " ");
19905 pir.removeFilter(pa);
19909 addPreferredActivityInternal(filter, match, set, activity, true, userId,
19910 "Replacing preferred");
19915 public void clearPackagePreferredActivities(String packageName) {
19916 final int callingUid = Binder.getCallingUid();
19917 if (getInstantAppPackageName(callingUid) != null) {
19921 synchronized (mPackages) {
19922 PackageParser.Package pkg = mPackages.get(packageName);
19923 if (pkg == null || pkg.applicationInfo.uid != callingUid) {
19924 if (mContext.checkCallingOrSelfPermission(
19925 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19926 != PackageManager.PERMISSION_GRANTED) {
19927 if (getUidTargetSdkVersionLockedLPr(callingUid)
19928 < Build.VERSION_CODES.FROYO) {
19929 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
19933 mContext.enforceCallingOrSelfPermission(
19934 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19937 final PackageSetting ps = mSettings.getPackageLPr(packageName);
19939 && filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
19942 int user = UserHandle.getCallingUserId();
19943 if (clearPackagePreferredActivitiesLPw(packageName, user)) {
19944 scheduleWritePackageRestrictionsLocked(user);
19949 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19950 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
19951 ArrayList<PreferredActivity> removed = null;
19952 boolean changed = false;
19953 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
19954 final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
19955 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
19956 if (userId != UserHandle.USER_ALL && userId != thisUserId) {
19959 Iterator<PreferredActivity> it = pir.filterIterator();
19960 while (it.hasNext()) {
19961 PreferredActivity pa = it.next();
19962 // Mark entry for removal only if it matches the package name
19963 // and the entry is of type "always".
19964 if (packageName == null ||
19965 (pa.mPref.mComponent.getPackageName().equals(packageName)
19966 && pa.mPref.mAlways)) {
19967 if (removed == null) {
19968 removed = new ArrayList<PreferredActivity>();
19973 if (removed != null) {
19974 for (int j=0; j<removed.size(); j++) {
19975 PreferredActivity pa = removed.get(j);
19976 pir.removeFilter(pa);
19982 postPreferredActivityChangedBroadcast(userId);
19987 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19988 private void clearIntentFilterVerificationsLPw(int userId) {
19989 final int packageCount = mPackages.size();
19990 for (int i = 0; i < packageCount; i++) {
19991 PackageParser.Package pkg = mPackages.valueAt(i);
19992 clearIntentFilterVerificationsLPw(pkg.packageName, userId, true);
19996 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19997 void clearIntentFilterVerificationsLPw(String packageName, int userId,
19998 boolean alsoResetStatus) {
19999 if (userId == UserHandle.USER_ALL) {
20000 if (mSettings.removeIntentFilterVerificationLPw(packageName,
20001 sUserManager.getUserIds())) {
20002 for (int oneUserId : sUserManager.getUserIds()) {
20003 scheduleWritePackageRestrictionsLocked(oneUserId);
20007 if (mSettings.removeIntentFilterVerificationLPw(packageName, userId,
20008 alsoResetStatus)) {
20009 scheduleWritePackageRestrictionsLocked(userId);
20014 /** Clears state for all users, and touches intent filter verification policy */
20015 void clearDefaultBrowserIfNeeded(String packageName) {
20016 for (int oneUserId : sUserManager.getUserIds()) {
20017 clearDefaultBrowserIfNeededForUser(packageName, oneUserId);
20021 private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
20022 final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
20023 if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
20024 if (packageName.equals(defaultBrowserPackageName)) {
20025 setDefaultBrowserPackageName(null, userId);
20031 public void resetApplicationPreferences(int userId) {
20032 mContext.enforceCallingOrSelfPermission(
20033 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20034 final long identity = Binder.clearCallingIdentity();
20037 synchronized (mPackages) {
20038 clearPackagePreferredActivitiesLPw(null, userId);
20039 mSettings.applyDefaultPreferredAppsLPw(this, userId);
20040 // TODO: We have to reset the default SMS and Phone. This requires
20041 // significant refactoring to keep all default apps in the package
20042 // manager (cleaner but more work) or have the services provide
20043 // callbacks to the package manager to request a default app reset.
20044 applyFactoryDefaultBrowserLPw(userId);
20045 clearIntentFilterVerificationsLPw(userId);
20046 primeDomainVerificationsLPw(userId);
20047 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
20048 scheduleWritePackageRestrictionsLocked(userId);
20050 resetNetworkPolicies(userId);
20052 Binder.restoreCallingIdentity(identity);
20057 public int getPreferredActivities(List<IntentFilter> outFilters,
20058 List<ComponentName> outActivities, String packageName) {
20059 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20063 final int userId = UserHandle.getCallingUserId();
20065 synchronized (mPackages) {
20066 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
20068 final Iterator<PreferredActivity> it = pir.filterIterator();
20069 while (it.hasNext()) {
20070 final PreferredActivity pa = it.next();
20071 if (packageName == null
20072 || (pa.mPref.mComponent.getPackageName().equals(packageName)
20073 && pa.mPref.mAlways)) {
20074 if (outFilters != null) {
20075 outFilters.add(new IntentFilter(pa));
20077 if (outActivities != null) {
20078 outActivities.add(pa.mPref.mComponent);
20089 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
20091 int callingUid = Binder.getCallingUid();
20092 if (callingUid != Process.SYSTEM_UID) {
20093 throw new SecurityException(
20094 "addPersistentPreferredActivity can only be run by the system");
20096 if (filter.countActions() == 0) {
20097 Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
20100 synchronized (mPackages) {
20101 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
20103 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
20104 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
20105 new PersistentPreferredActivity(filter, activity));
20106 scheduleWritePackageRestrictionsLocked(userId);
20107 postPreferredActivityChangedBroadcast(userId);
20112 public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
20113 int callingUid = Binder.getCallingUid();
20114 if (callingUid != Process.SYSTEM_UID) {
20115 throw new SecurityException(
20116 "clearPackagePersistentPreferredActivities can only be run by the system");
20118 ArrayList<PersistentPreferredActivity> removed = null;
20119 boolean changed = false;
20120 synchronized (mPackages) {
20121 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
20122 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
20123 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
20125 if (userId != thisUserId) {
20128 Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
20129 while (it.hasNext()) {
20130 PersistentPreferredActivity ppa = it.next();
20131 // Mark entry for removal only if it matches the package name.
20132 if (ppa.mComponent.getPackageName().equals(packageName)) {
20133 if (removed == null) {
20134 removed = new ArrayList<PersistentPreferredActivity>();
20139 if (removed != null) {
20140 for (int j=0; j<removed.size(); j++) {
20141 PersistentPreferredActivity ppa = removed.get(j);
20142 ppir.removeFilter(ppa);
20149 scheduleWritePackageRestrictionsLocked(userId);
20150 postPreferredActivityChangedBroadcast(userId);
20156 * Common machinery for picking apart a restored XML blob and passing
20157 * it to a caller-supplied functor to be applied to the running system.
20159 private void restoreFromXml(XmlPullParser parser, int userId,
20160 String expectedStartTag, BlobXmlRestorer functor)
20161 throws IOException, XmlPullParserException {
20163 while ((type = parser.next()) != XmlPullParser.START_TAG
20164 && type != XmlPullParser.END_DOCUMENT) {
20166 if (type != XmlPullParser.START_TAG) {
20167 // oops didn't find a start tag?!
20168 if (DEBUG_BACKUP) {
20169 Slog.e(TAG, "Didn't find start tag during restore");
20173 Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
20174 // this is supposed to be TAG_PREFERRED_BACKUP
20175 if (!expectedStartTag.equals(parser.getName())) {
20176 if (DEBUG_BACKUP) {
20177 Slog.e(TAG, "Found unexpected tag " + parser.getName());
20182 // skip interfering stuff, then we're aligned with the backing implementation
20183 while ((type = parser.next()) == XmlPullParser.TEXT) { }
20184 Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
20185 functor.apply(parser, userId);
20188 private interface BlobXmlRestorer {
20189 public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
20193 * Non-Binder method, support for the backup/restore mechanism: write the
20194 * full set of preferred activities in its canonical XML format. Returns the
20195 * XML output as a byte array, or null if there is none.
20198 public byte[] getPreferredActivityBackup(int userId) {
20199 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20200 throw new SecurityException("Only the system may call getPreferredActivityBackup()");
20203 ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20205 final XmlSerializer serializer = new FastXmlSerializer();
20206 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20207 serializer.startDocument(null, true);
20208 serializer.startTag(null, TAG_PREFERRED_BACKUP);
20210 synchronized (mPackages) {
20211 mSettings.writePreferredActivitiesLPr(serializer, userId, true);
20214 serializer.endTag(null, TAG_PREFERRED_BACKUP);
20215 serializer.endDocument();
20216 serializer.flush();
20217 } catch (Exception e) {
20218 if (DEBUG_BACKUP) {
20219 Slog.e(TAG, "Unable to write preferred activities for backup", e);
20224 return dataStream.toByteArray();
20228 public void restorePreferredActivities(byte[] backup, int userId) {
20229 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20230 throw new SecurityException("Only the system may call restorePreferredActivities()");
20234 final XmlPullParser parser = Xml.newPullParser();
20235 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20236 restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
20237 new BlobXmlRestorer() {
20239 public void apply(XmlPullParser parser, int userId)
20240 throws XmlPullParserException, IOException {
20241 synchronized (mPackages) {
20242 mSettings.readPreferredActivitiesLPw(parser, userId);
20246 } catch (Exception e) {
20247 if (DEBUG_BACKUP) {
20248 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
20254 * Non-Binder method, support for the backup/restore mechanism: write the
20255 * default browser (etc) settings in its canonical XML format. Returns the default
20256 * browser XML representation as a byte array, or null if there is none.
20259 public byte[] getDefaultAppsBackup(int userId) {
20260 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20261 throw new SecurityException("Only the system may call getDefaultAppsBackup()");
20264 ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20266 final XmlSerializer serializer = new FastXmlSerializer();
20267 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20268 serializer.startDocument(null, true);
20269 serializer.startTag(null, TAG_DEFAULT_APPS);
20271 synchronized (mPackages) {
20272 mSettings.writeDefaultAppsLPr(serializer, userId);
20275 serializer.endTag(null, TAG_DEFAULT_APPS);
20276 serializer.endDocument();
20277 serializer.flush();
20278 } catch (Exception e) {
20279 if (DEBUG_BACKUP) {
20280 Slog.e(TAG, "Unable to write default apps for backup", e);
20285 return dataStream.toByteArray();
20289 public void restoreDefaultApps(byte[] backup, int userId) {
20290 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20291 throw new SecurityException("Only the system may call restoreDefaultApps()");
20295 final XmlPullParser parser = Xml.newPullParser();
20296 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20297 restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
20298 new BlobXmlRestorer() {
20300 public void apply(XmlPullParser parser, int userId)
20301 throws XmlPullParserException, IOException {
20302 synchronized (mPackages) {
20303 mSettings.readDefaultAppsLPw(parser, userId);
20307 } catch (Exception e) {
20308 if (DEBUG_BACKUP) {
20309 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
20315 public byte[] getIntentFilterVerificationBackup(int userId) {
20316 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20317 throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
20320 ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20322 final XmlSerializer serializer = new FastXmlSerializer();
20323 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20324 serializer.startDocument(null, true);
20325 serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
20327 synchronized (mPackages) {
20328 mSettings.writeAllDomainVerificationsLPr(serializer, userId);
20331 serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
20332 serializer.endDocument();
20333 serializer.flush();
20334 } catch (Exception e) {
20335 if (DEBUG_BACKUP) {
20336 Slog.e(TAG, "Unable to write default apps for backup", e);
20341 return dataStream.toByteArray();
20345 public void restoreIntentFilterVerification(byte[] backup, int userId) {
20346 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20347 throw new SecurityException("Only the system may call restorePreferredActivities()");
20351 final XmlPullParser parser = Xml.newPullParser();
20352 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20353 restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
20354 new BlobXmlRestorer() {
20356 public void apply(XmlPullParser parser, int userId)
20357 throws XmlPullParserException, IOException {
20358 synchronized (mPackages) {
20359 mSettings.readAllDomainVerificationsLPr(parser, userId);
20360 mSettings.writeLPr();
20364 } catch (Exception e) {
20365 if (DEBUG_BACKUP) {
20366 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
20372 public byte[] getPermissionGrantBackup(int userId) {
20373 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20374 throw new SecurityException("Only the system may call getPermissionGrantBackup()");
20377 ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20379 final XmlSerializer serializer = new FastXmlSerializer();
20380 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20381 serializer.startDocument(null, true);
20382 serializer.startTag(null, TAG_PERMISSION_BACKUP);
20384 synchronized (mPackages) {
20385 serializeRuntimePermissionGrantsLPr(serializer, userId);
20388 serializer.endTag(null, TAG_PERMISSION_BACKUP);
20389 serializer.endDocument();
20390 serializer.flush();
20391 } catch (Exception e) {
20392 if (DEBUG_BACKUP) {
20393 Slog.e(TAG, "Unable to write default apps for backup", e);
20398 return dataStream.toByteArray();
20402 public void restorePermissionGrants(byte[] backup, int userId) {
20403 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20404 throw new SecurityException("Only the system may call restorePermissionGrants()");
20408 final XmlPullParser parser = Xml.newPullParser();
20409 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20410 restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
20411 new BlobXmlRestorer() {
20413 public void apply(XmlPullParser parser, int userId)
20414 throws XmlPullParserException, IOException {
20415 synchronized (mPackages) {
20416 processRestoredPermissionGrantsLPr(parser, userId);
20420 } catch (Exception e) {
20421 if (DEBUG_BACKUP) {
20422 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
20427 private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
20428 throws IOException {
20429 serializer.startTag(null, TAG_ALL_GRANTS);
20431 final int N = mSettings.mPackages.size();
20432 for (int i = 0; i < N; i++) {
20433 final PackageSetting ps = mSettings.mPackages.valueAt(i);
20434 boolean pkgGrantsKnown = false;
20436 PermissionsState packagePerms = ps.getPermissionsState();
20438 for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
20439 final int grantFlags = state.getFlags();
20440 // only look at grants that are not system/policy fixed
20441 if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
20442 final boolean isGranted = state.isGranted();
20443 // And only back up the user-twiddled state bits
20444 if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
20445 final String packageName = mSettings.mPackages.keyAt(i);
20446 if (!pkgGrantsKnown) {
20447 serializer.startTag(null, TAG_GRANT);
20448 serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
20449 pkgGrantsKnown = true;
20452 final boolean userSet =
20453 (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
20454 final boolean userFixed =
20455 (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
20456 final boolean revoke =
20457 (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
20459 serializer.startTag(null, TAG_PERMISSION);
20460 serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
20462 serializer.attribute(null, ATTR_IS_GRANTED, "true");
20465 serializer.attribute(null, ATTR_USER_SET, "true");
20468 serializer.attribute(null, ATTR_USER_FIXED, "true");
20471 serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
20473 serializer.endTag(null, TAG_PERMISSION);
20478 if (pkgGrantsKnown) {
20479 serializer.endTag(null, TAG_GRANT);
20483 serializer.endTag(null, TAG_ALL_GRANTS);
20486 private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
20487 throws XmlPullParserException, IOException {
20488 String pkgName = null;
20489 int outerDepth = parser.getDepth();
20491 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
20492 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
20493 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
20497 final String tagName = parser.getName();
20498 if (tagName.equals(TAG_GRANT)) {
20499 pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
20500 if (DEBUG_BACKUP) {
20501 Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
20503 } else if (tagName.equals(TAG_PERMISSION)) {
20505 final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
20506 final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
20508 int newFlagSet = 0;
20509 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
20510 newFlagSet |= FLAG_PERMISSION_USER_SET;
20512 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
20513 newFlagSet |= FLAG_PERMISSION_USER_FIXED;
20515 if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
20516 newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
20518 if (DEBUG_BACKUP) {
20519 Slog.v(TAG, " + Restoring grant:"
20520 + " pkg=" + pkgName
20521 + " perm=" + permName
20522 + " granted=" + isGranted
20523 + " bits=0x" + Integer.toHexString(newFlagSet));
20525 final PackageSetting ps = mSettings.mPackages.get(pkgName);
20527 // Already installed so we apply the grant immediately
20528 if (DEBUG_BACKUP) {
20529 Slog.v(TAG, " + already installed; applying");
20531 PermissionsState perms = ps.getPermissionsState();
20532 BasePermission bp =
20533 (BasePermission) mPermissionManager.getPermissionTEMP(permName);
20536 perms.grantRuntimePermission(bp, userId);
20538 if (newFlagSet != 0) {
20539 perms.updatePermissionFlags(
20540 bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
20544 // Need to wait for post-restore install to apply the grant
20545 if (DEBUG_BACKUP) {
20546 Slog.v(TAG, " - not yet installed; saving for later");
20548 mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
20549 isGranted, newFlagSet, userId);
20552 PackageManagerService.reportSettingsProblem(Log.WARN,
20553 "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
20554 XmlUtils.skipCurrentTag(parser);
20558 scheduleWriteSettingsLocked();
20559 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
20563 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
20564 int sourceUserId, int targetUserId, int flags) {
20565 mContext.enforceCallingOrSelfPermission(
20566 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
20567 int callingUid = Binder.getCallingUid();
20568 enforceOwnerRights(ownerPackage, callingUid);
20569 PackageManagerServiceUtils.enforceShellRestriction(
20570 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
20571 if (intentFilter.countActions() == 0) {
20572 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
20575 synchronized (mPackages) {
20576 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
20577 ownerPackage, targetUserId, flags);
20578 CrossProfileIntentResolver resolver =
20579 mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
20580 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
20581 // We have all those whose filter is equal. Now checking if the rest is equal as well.
20582 if (existing != null) {
20583 int size = existing.size();
20584 for (int i = 0; i < size; i++) {
20585 if (newFilter.equalsIgnoreFilter(existing.get(i))) {
20590 resolver.addFilter(newFilter);
20591 scheduleWritePackageRestrictionsLocked(sourceUserId);
20596 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
20597 mContext.enforceCallingOrSelfPermission(
20598 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
20599 final int callingUid = Binder.getCallingUid();
20600 enforceOwnerRights(ownerPackage, callingUid);
20601 PackageManagerServiceUtils.enforceShellRestriction(
20602 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
20603 synchronized (mPackages) {
20604 CrossProfileIntentResolver resolver =
20605 mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
20606 ArraySet<CrossProfileIntentFilter> set =
20607 new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
20608 for (CrossProfileIntentFilter filter : set) {
20609 if (filter.getOwnerPackage().equals(ownerPackage)) {
20610 resolver.removeFilter(filter);
20613 scheduleWritePackageRestrictionsLocked(sourceUserId);
20617 // Enforcing that callingUid is owning pkg on userId
20618 private void enforceOwnerRights(String pkg, int callingUid) {
20619 // The system owns everything.
20620 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
20623 final int callingUserId = UserHandle.getUserId(callingUid);
20624 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
20626 throw new IllegalArgumentException("Unknown package " + pkg + " on user "
20629 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
20630 throw new SecurityException("Calling uid " + callingUid
20631 + " does not own package " + pkg);
20636 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
20637 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20640 return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
20643 public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
20644 UserManagerService ums = UserManagerService.getInstance();
20646 final UserInfo parent = ums.getProfileParent(userId);
20647 final int launcherUid = (parent != null) ? parent.id : userId;
20648 final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
20649 if (launcherComponent != null) {
20650 Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
20651 .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
20652 .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
20653 .setPackage(launcherComponent.getPackageName());
20654 mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUid));
20660 * Report the 'Home' activity which is currently set as "always use this one". If non is set
20661 * then reports the most likely home activity or null if there are more than one.
20663 private ComponentName getDefaultHomeActivity(int userId) {
20664 List<ResolveInfo> allHomeCandidates = new ArrayList<>();
20665 ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
20670 // Find the launcher with the highest priority and return that component if there are no
20671 // other home activity with the same priority.
20672 int lastPriority = Integer.MIN_VALUE;
20673 ComponentName lastComponent = null;
20674 final int size = allHomeCandidates.size();
20675 for (int i = 0; i < size; i++) {
20676 final ResolveInfo ri = allHomeCandidates.get(i);
20677 if (ri.priority > lastPriority) {
20678 lastComponent = ri.activityInfo.getComponentName();
20679 lastPriority = ri.priority;
20680 } else if (ri.priority == lastPriority) {
20681 // Two components found with same priority.
20682 lastComponent = null;
20685 return lastComponent;
20688 private Intent getHomeIntent() {
20689 Intent intent = new Intent(Intent.ACTION_MAIN);
20690 intent.addCategory(Intent.CATEGORY_HOME);
20691 intent.addCategory(Intent.CATEGORY_DEFAULT);
20695 private IntentFilter getHomeFilter() {
20696 IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
20697 filter.addCategory(Intent.CATEGORY_HOME);
20698 filter.addCategory(Intent.CATEGORY_DEFAULT);
20702 ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
20704 Intent intent = getHomeIntent();
20705 List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
20706 PackageManager.GET_META_DATA, userId);
20707 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
20708 true, false, false, userId);
20710 allHomeCandidates.clear();
20711 if (list != null) {
20712 for (ResolveInfo ri : list) {
20713 allHomeCandidates.add(ri);
20716 return (preferred == null || preferred.activityInfo == null)
20718 : new ComponentName(preferred.activityInfo.packageName,
20719 preferred.activityInfo.name);
20723 public void setHomeActivity(ComponentName comp, int userId) {
20724 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20727 ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
20728 getHomeActivitiesAsUser(homeActivities, userId);
20730 boolean found = false;
20732 final int size = homeActivities.size();
20733 final ComponentName[] set = new ComponentName[size];
20734 for (int i = 0; i < size; i++) {
20735 final ResolveInfo candidate = homeActivities.get(i);
20736 final ActivityInfo info = candidate.activityInfo;
20737 final ComponentName activityName = new ComponentName(info.packageName, info.name);
20738 set[i] = activityName;
20739 if (!found && activityName.equals(comp)) {
20744 throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
20747 replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
20748 set, comp, userId);
20751 private @Nullable String getSetupWizardPackageName() {
20752 final Intent intent = new Intent(Intent.ACTION_MAIN);
20753 intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
20755 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
20756 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
20757 | MATCH_DISABLED_COMPONENTS,
20758 UserHandle.myUserId());
20759 if (matches.size() == 1) {
20760 return matches.get(0).getComponentInfo().packageName;
20762 Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
20763 + ": matches=" + matches);
20768 private @Nullable String getStorageManagerPackageName() {
20769 final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
20771 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
20772 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
20773 | MATCH_DISABLED_COMPONENTS,
20774 UserHandle.myUserId());
20775 if (matches.size() == 1) {
20776 return matches.get(0).getComponentInfo().packageName;
20778 Slog.e(TAG, "There should probably be exactly one storage manager; found "
20779 + matches.size() + ": matches=" + matches);
20785 public String getSystemTextClassifierPackageName() {
20786 return ensureSystemPackageName(mContext.getString(
20787 R.string.config_defaultTextClassifierPackage));
20791 private String ensureSystemPackageName(@Nullable String packageName) {
20792 if (packageName == null) {
20795 long token = Binder.clearCallingIdentity();
20797 if (getPackageInfo(packageName, MATCH_FACTORY_ONLY, UserHandle.USER_SYSTEM) == null) {
20798 PackageInfo packageInfo = getPackageInfo(packageName, 0, UserHandle.USER_SYSTEM);
20799 if (packageInfo != null) {
20800 EventLog.writeEvent(0x534e4554, "145981139", packageInfo.applicationInfo.uid,
20806 Binder.restoreCallingIdentity(token);
20808 return packageName;
20812 public void setApplicationEnabledSetting(String appPackageName,
20813 int newState, int flags, int userId, String callingPackage) {
20814 if (!sUserManager.exists(userId)) return;
20815 if (callingPackage == null) {
20816 callingPackage = Integer.toString(Binder.getCallingUid());
20818 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
20822 public void setUpdateAvailable(String packageName, boolean updateAvailable) {
20823 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
20824 synchronized (mPackages) {
20825 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
20826 if (pkgSetting != null) {
20827 pkgSetting.setUpdateAvailable(updateAvailable);
20833 public void setComponentEnabledSetting(ComponentName componentName,
20834 int newState, int flags, int userId) {
20835 if (!sUserManager.exists(userId)) return;
20836 setEnabledSetting(componentName.getPackageName(),
20837 componentName.getClassName(), newState, flags, userId, null);
20840 private void setEnabledSetting(final String packageName, String className, int newState,
20841 final int flags, int userId, String callingPackage) {
20842 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
20843 || newState == COMPONENT_ENABLED_STATE_ENABLED
20844 || newState == COMPONENT_ENABLED_STATE_DISABLED
20845 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20846 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
20847 throw new IllegalArgumentException("Invalid new component state: "
20850 PackageSetting pkgSetting;
20851 final int callingUid = Binder.getCallingUid();
20852 final int permission;
20853 if (callingUid == Process.SYSTEM_UID) {
20854 permission = PackageManager.PERMISSION_GRANTED;
20856 permission = mContext.checkCallingOrSelfPermission(
20857 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20859 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20860 false /* requireFullPermission */, true /* checkShell */, "set enabled");
20861 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20862 boolean sendNow = false;
20863 boolean isApp = (className == null);
20864 final boolean isCallerInstantApp = (getInstantAppPackageName(callingUid) != null);
20865 String componentName = isApp ? packageName : className;
20866 int packageUid = -1;
20867 ArrayList<String> components;
20870 synchronized (mPackages) {
20871 pkgSetting = mSettings.mPackages.get(packageName);
20872 if (pkgSetting == null) {
20873 if (!isCallerInstantApp) {
20874 if (className == null) {
20875 throw new IllegalArgumentException("Unknown package: " + packageName);
20877 throw new IllegalArgumentException(
20878 "Unknown component: " + packageName + "/" + className);
20880 // throw SecurityException to prevent leaking package information
20881 throw new SecurityException(
20882 "Attempt to change component state; "
20883 + "pid=" + Binder.getCallingPid()
20884 + ", uid=" + callingUid
20885 + (className == null
20886 ? ", package=" + packageName
20887 : ", component=" + packageName + "/" + className));
20892 // Limit who can change which apps
20893 if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
20894 // Don't allow apps that don't have permission to modify other apps
20895 if (!allowedByPermission
20896 || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
20897 throw new SecurityException(
20898 "Attempt to change component state; "
20899 + "pid=" + Binder.getCallingPid()
20900 + ", uid=" + callingUid
20901 + (className == null
20902 ? ", package=" + packageName
20903 : ", component=" + packageName + "/" + className));
20905 // Don't allow changing protected packages.
20906 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
20907 throw new SecurityException("Cannot disable a protected package: " + packageName);
20911 synchronized (mPackages) {
20912 if (callingUid == Process.SHELL_UID
20913 && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
20914 // Shell can only change whole packages between ENABLED and DISABLED_USER states
20915 // unless it is a test package.
20916 int oldState = pkgSetting.getEnabled(userId);
20917 if (className == null
20919 (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
20920 || oldState == COMPONENT_ENABLED_STATE_DEFAULT
20921 || oldState == COMPONENT_ENABLED_STATE_ENABLED)
20923 (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20924 || newState == COMPONENT_ENABLED_STATE_DEFAULT
20925 || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
20928 throw new SecurityException(
20929 "Shell cannot change component state for " + packageName + "/"
20930 + className + " to " + newState);
20934 if (className == null) {
20935 // We're dealing with an application/package level state change
20936 synchronized (mPackages) {
20937 if (pkgSetting.getEnabled(userId) == newState) {
20942 // If we're enabling a system stub, there's a little more work to do.
20943 // Prior to enabling the package, we need to decompress the APK(s) to the
20944 // data partition and then replace the version on the system partition.
20945 final PackageParser.Package deletedPkg = pkgSetting.pkg;
20946 final boolean isSystemStub = deletedPkg.isStub
20947 && deletedPkg.isSystem();
20949 && (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
20950 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED)) {
20951 final File codePath = decompressPackage(deletedPkg);
20952 if (codePath == null) {
20953 Slog.e(TAG, "couldn't decompress pkg: " + pkgSetting.name);
20956 // TODO remove direct parsing of the package object during internal cleanup
20958 // We need to call parse directly here for no other reason than we need
20959 // the new package in order to disable the old one [we use the information
20960 // for some internal optimization to optionally create a new package setting
20961 // object on replace]. However, we can't get the package from the scan
20962 // because the scan modifies live structures and we need to remove the
20963 // old [system] package from the system before a scan can be attempted.
20964 // Once scan is indempotent we can remove this parse and use the package
20965 // object we scanned, prior to adding it to package settings.
20966 final PackageParser pp = new PackageParser();
20967 pp.setSeparateProcesses(mSeparateProcesses);
20968 pp.setDisplayMetrics(mMetrics);
20969 pp.setCallback(mPackageParserCallback);
20970 final PackageParser.Package tmpPkg;
20972 final @ParseFlags int parseFlags = mDefParseFlags
20973 | PackageParser.PARSE_MUST_BE_APK
20974 | PackageParser.PARSE_IS_SYSTEM_DIR;
20975 tmpPkg = pp.parsePackage(codePath, parseFlags);
20976 } catch (PackageParserException e) {
20977 Slog.w(TAG, "Failed to parse compressed system package:" + pkgSetting.name, e);
20980 synchronized (mInstallLock) {
20981 // Disable the stub and remove any package entries
20982 removePackageLI(deletedPkg, true);
20983 synchronized (mPackages) {
20984 disableSystemPackageLPw(deletedPkg, tmpPkg);
20986 final PackageParser.Package pkg;
20987 try (PackageFreezer freezer =
20988 freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
20989 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
20990 | PackageParser.PARSE_ENFORCE_CODE;
20991 pkg = scanPackageTracedLI(codePath, parseFlags, 0 /*scanFlags*/,
20992 0 /*currentTime*/, null /*user*/);
20993 prepareAppDataAfterInstallLIF(pkg);
20994 synchronized (mPackages) {
20996 updateSharedLibrariesLPr(pkg, null);
20997 } catch (PackageManagerException e) {
20998 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: ", e);
21000 mPermissionManager.updatePermissions(
21001 pkg.packageName, pkg, true, mPackages.values(),
21002 mPermissionCallback);
21003 mSettings.writeLPr();
21005 } catch (PackageManagerException e) {
21006 // Whoops! Something went wrong; try to roll back to the stub
21007 Slog.w(TAG, "Failed to install compressed system package:"
21008 + pkgSetting.name, e);
21009 // Remove the failed install
21010 removeCodePathLI(codePath);
21012 // Install the system package
21013 try (PackageFreezer freezer =
21014 freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
21015 synchronized (mPackages) {
21016 // NOTE: The system package always needs to be enabled; even
21017 // if it's for a compressed stub. If we don't, installing the
21018 // system package fails during scan [scanning checks the disabled
21019 // packages]. We will reverse this later, after we've "installed"
21021 // This leaves us in a fragile state; the stub should never be
21022 // enabled, so, cross your fingers and hope nothing goes wrong
21023 // until we can disable the package later.
21024 enableSystemPackageLPw(deletedPkg);
21026 installPackageFromSystemLIF(deletedPkg.codePath,
21027 false /*isPrivileged*/, null /*allUserHandles*/,
21028 null /*origUserHandles*/, null /*origPermissionsState*/,
21029 true /*writeSettings*/);
21030 } catch (PackageManagerException pme) {
21031 Slog.w(TAG, "Failed to restore system package:"
21032 + deletedPkg.packageName, pme);
21034 synchronized (mPackages) {
21035 mSettings.disableSystemPackageLPw(
21036 deletedPkg.packageName, true /*replaced*/);
21037 mSettings.writeLPr();
21042 clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE
21043 | FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
21044 mDexManager.notifyPackageUpdated(pkg.packageName,
21045 pkg.baseCodePath, pkg.splitCodePaths);
21048 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
21049 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
21050 // Don't care about who enables an app.
21051 callingPackage = null;
21053 synchronized (mPackages) {
21054 pkgSetting.setEnabled(newState, userId, callingPackage);
21057 synchronized (mPackages) {
21058 // We're dealing with a component level state change
21059 // First, verify that this is a valid class name.
21060 PackageParser.Package pkg = pkgSetting.pkg;
21061 if (pkg == null || !pkg.hasComponentClassName(className)) {
21063 pkg.applicationInfo.targetSdkVersion >=
21064 Build.VERSION_CODES.JELLY_BEAN) {
21065 throw new IllegalArgumentException("Component class " + className
21066 + " does not exist in " + packageName);
21068 Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
21069 + className + " does not exist in " + packageName);
21072 switch (newState) {
21073 case COMPONENT_ENABLED_STATE_ENABLED:
21074 if (!pkgSetting.enableComponentLPw(className, userId)) {
21078 case COMPONENT_ENABLED_STATE_DISABLED:
21079 if (!pkgSetting.disableComponentLPw(className, userId)) {
21083 case COMPONENT_ENABLED_STATE_DEFAULT:
21084 if (!pkgSetting.restoreComponentLPw(className, userId)) {
21089 Slog.e(TAG, "Invalid new component state: " + newState);
21094 synchronized (mPackages) {
21095 scheduleWritePackageRestrictionsLocked(userId);
21096 updateSequenceNumberLP(pkgSetting, new int[] { userId });
21097 final long callingId = Binder.clearCallingIdentity();
21099 updateInstantAppInstallerLocked(packageName);
21101 Binder.restoreCallingIdentity(callingId);
21103 components = mPendingBroadcasts.get(userId, packageName);
21104 final boolean newPackage = components == null;
21106 components = new ArrayList<String>();
21108 if (!components.contains(componentName)) {
21109 components.add(componentName);
21111 if ((flags&PackageManager.DONT_KILL_APP) == 0) {
21113 // Purge entry from pending broadcast list if another one exists already
21114 // since we are sending one right away.
21115 mPendingBroadcasts.remove(userId, packageName);
21118 mPendingBroadcasts.put(userId, packageName, components);
21120 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
21121 // Schedule a message
21122 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
21127 long callingId = Binder.clearCallingIdentity();
21130 packageUid = UserHandle.getUid(userId, pkgSetting.appId);
21131 sendPackageChangedBroadcast(packageName,
21132 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
21135 Binder.restoreCallingIdentity(callingId);
21140 public void flushPackageRestrictionsAsUser(int userId) {
21141 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
21144 if (!sUserManager.exists(userId)) {
21147 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
21148 false /* checkShell */, "flushPackageRestrictions");
21149 synchronized (mPackages) {
21150 mSettings.writePackageRestrictionsLPr(userId);
21151 mDirtyUsers.remove(userId);
21152 if (mDirtyUsers.isEmpty()) {
21153 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
21158 private void sendPackageChangedBroadcast(String packageName,
21159 boolean killFlag, ArrayList<String> componentNames, int packageUid) {
21161 Log.v(TAG, "Sending package changed: package=" + packageName + " components="
21163 Bundle extras = new Bundle(4);
21164 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
21165 String nameList[] = new String[componentNames.size()];
21166 componentNames.toArray(nameList);
21167 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
21168 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
21169 extras.putInt(Intent.EXTRA_UID, packageUid);
21170 // If this is not reporting a change of the overall package, then only send it
21171 // to registered receivers. We don't want to launch a swath of apps for every
21172 // little component state change.
21173 final int flags = !componentNames.contains(packageName)
21174 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
21175 final int userId = UserHandle.getUserId(packageUid);
21176 final boolean isInstantApp = isInstantApp(packageName, userId);
21177 final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
21178 final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
21179 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, flags, null, null,
21180 userIds, instantUserIds);
21184 public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
21185 if (!sUserManager.exists(userId)) return;
21186 final int callingUid = Binder.getCallingUid();
21187 if (getInstantAppPackageName(callingUid) != null) {
21190 final int permission = mContext.checkCallingOrSelfPermission(
21191 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
21192 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
21193 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
21194 true /* requireFullPermission */, true /* checkShell */, "stop package");
21196 synchronized (mPackages) {
21197 final PackageSetting ps = mSettings.mPackages.get(packageName);
21198 if (!filterAppAccessLPr(ps, callingUid, userId)
21199 && mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
21200 allowedByPermission, callingUid, userId)) {
21201 scheduleWritePackageRestrictionsLocked(userId);
21207 public String getInstallerPackageName(String packageName) {
21208 final int callingUid = Binder.getCallingUid();
21209 synchronized (mPackages) {
21210 final PackageSetting ps = mSettings.mPackages.get(packageName);
21211 if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
21214 return mSettings.getInstallerPackageNameLPr(packageName);
21218 public boolean isOrphaned(String packageName) {
21220 synchronized (mPackages) {
21221 return mSettings.isOrphaned(packageName);
21226 public int getApplicationEnabledSetting(String packageName, int userId) {
21227 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
21228 int callingUid = Binder.getCallingUid();
21229 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
21230 false /* requireFullPermission */, false /* checkShell */, "get enabled");
21232 synchronized (mPackages) {
21233 if (filterAppAccessLPr(mSettings.getPackageLPr(packageName), callingUid, userId)) {
21234 return COMPONENT_ENABLED_STATE_DISABLED;
21236 return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
21241 public int getComponentEnabledSetting(ComponentName component, int userId) {
21242 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
21243 int callingUid = Binder.getCallingUid();
21244 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
21245 false /*requireFullPermission*/, false /*checkShell*/, "getComponentEnabled");
21246 synchronized (mPackages) {
21247 if (filterAppAccessLPr(mSettings.getPackageLPr(component.getPackageName()), callingUid,
21248 component, TYPE_UNKNOWN, userId)) {
21249 return COMPONENT_ENABLED_STATE_DISABLED;
21251 return mSettings.getComponentEnabledSettingLPr(component, userId);
21256 public void enterSafeMode() {
21257 enforceSystemOrRoot("Only the system can request entering safe mode");
21259 if (!mSystemReady) {
21265 public void systemReady() {
21266 enforceSystemOrRoot("Only the system can claim the system is ready");
21268 mSystemReady = true;
21269 final ContentResolver resolver = mContext.getContentResolver();
21270 ContentObserver co = new ContentObserver(mHandler) {
21272 public void onChange(boolean selfChange) {
21273 mWebInstantAppsDisabled =
21274 (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) ||
21275 (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0);
21278 mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
21279 .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
21280 false, co, UserHandle.USER_SYSTEM);
21281 mContext.getContentResolver().registerContentObserver(android.provider.Settings.Secure
21282 .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM);
21285 // Disable any carrier apps. We do this very early in boot to prevent the apps from being
21286 // disabled after already being started.
21287 CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
21288 mContext.getContentResolver(), UserHandle.USER_SYSTEM);
21290 disableSkuSpecificApps();
21292 // Read the compatibilty setting when the system is ready.
21293 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
21294 mContext.getContentResolver(),
21295 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
21296 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
21297 if (DEBUG_SETTINGS) {
21298 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
21301 int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
21303 synchronized (mPackages) {
21304 // Verify that all of the preferred activity components actually
21305 // exist. It is possible for applications to be updated and at
21306 // that point remove a previously declared activity component that
21307 // had been set as a preferred activity. We try to clean this up
21308 // the next time we encounter that preferred activity, but it is
21309 // possible for the user flow to never be able to return to that
21310 // situation so here we do a sanity check to make sure we haven't
21311 // left any junk around.
21312 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
21313 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
21314 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
21316 for (PreferredActivity pa : pir.filterSet()) {
21317 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
21321 if (removed.size() > 0) {
21322 for (int r=0; r<removed.size(); r++) {
21323 PreferredActivity pa = removed.get(r);
21324 Slog.w(TAG, "Removing dangling preferred activity: "
21325 + pa.mPref.mComponent);
21326 pir.removeFilter(pa);
21328 mSettings.writePackageRestrictionsLPr(
21329 mSettings.mPreferredActivities.keyAt(i));
21333 for (int userId : UserManagerService.getInstance().getUserIds()) {
21334 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
21335 grantPermissionsUserIds = ArrayUtils.appendInt(
21336 grantPermissionsUserIds, userId);
21340 sUserManager.systemReady();
21341 // If we upgraded grant all default permissions before kicking off.
21342 for (int userId : grantPermissionsUserIds) {
21343 mDefaultPermissionPolicy.grantDefaultPermissions(userId);
21346 if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
21347 // If we did not grant default permissions, we preload from this the
21348 // default permission exceptions lazily to ensure we don't hit the
21349 // disk on a new user creation.
21350 mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
21353 // Now that we've scanned all packages, and granted any default
21354 // permissions, ensure permissions are updated. Beware of dragons if you
21355 // try optimizing this.
21356 synchronized (mPackages) {
21357 mPermissionManager.updateAllPermissions(
21358 StorageManager.UUID_PRIVATE_INTERNAL, false, mPackages.values(),
21359 mPermissionCallback);
21362 // Kick off any messages waiting for system ready
21363 if (mPostSystemReadyMessages != null) {
21364 for (Message msg : mPostSystemReadyMessages) {
21365 msg.sendToTarget();
21367 mPostSystemReadyMessages = null;
21370 // Watch for external volumes that come and go over time
21371 final StorageManager storage = mContext.getSystemService(StorageManager.class);
21372 storage.registerListener(mStorageListener);
21374 mInstallerService.systemReady();
21375 mDexManager.systemReady();
21376 mPackageDexOptimizer.systemReady();
21378 StorageManagerInternal StorageManagerInternal = LocalServices.getService(
21379 StorageManagerInternal.class);
21380 StorageManagerInternal.addExternalStoragePolicy(
21381 new StorageManagerInternal.ExternalStorageMountPolicy() {
21383 public int getMountMode(int uid, String packageName) {
21384 if (Process.isIsolated(uid)) {
21385 return Zygote.MOUNT_EXTERNAL_NONE;
21387 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
21388 return Zygote.MOUNT_EXTERNAL_DEFAULT;
21390 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
21391 return Zygote.MOUNT_EXTERNAL_READ;
21393 return Zygote.MOUNT_EXTERNAL_WRITE;
21397 public boolean hasExternalStorage(int uid, String packageName) {
21402 // Now that we're mostly running, clean up stale users and apps
21403 sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
21404 reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
21406 mPermissionManager.systemReady();
21408 if (mInstantAppResolverConnection != null) {
21409 mContext.registerReceiver(new BroadcastReceiver() {
21411 public void onReceive(Context context, Intent intent) {
21412 mInstantAppResolverConnection.optimisticBind();
21413 mContext.unregisterReceiver(this);
21415 }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
21419 public void waitForAppDataPrepared() {
21420 if (mPrepareAppDataFuture == null) {
21423 ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
21424 mPrepareAppDataFuture = null;
21428 public boolean isSafeMode() {
21429 // allow instant applications
21434 public boolean hasSystemUidErrors() {
21435 // allow instant applications
21436 return mHasSystemUidErrors;
21439 static String arrayToString(int[] array) {
21440 StringBuffer buf = new StringBuffer(128);
21442 if (array != null) {
21443 for (int i=0; i<array.length; i++) {
21444 if (i > 0) buf.append(", ");
21445 buf.append(array[i]);
21449 return buf.toString();
21453 public void onShellCommand(FileDescriptor in, FileDescriptor out,
21454 FileDescriptor err, String[] args, ShellCallback callback,
21455 ResultReceiver resultReceiver) {
21456 (new PackageManagerShellCommand(this)).exec(
21457 this, in, out, err, args, callback, resultReceiver);
21461 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
21462 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
21464 DumpState dumpState = new DumpState();
21465 boolean fullPreferred = false;
21466 boolean checkin = false;
21468 String packageName = null;
21469 ArraySet<String> permissionNames = null;
21472 while (opti < args.length) {
21473 String opt = args[opti];
21474 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
21479 if ("-a".equals(opt)) {
21480 // Right now we only know how to print all.
21481 } else if ("-h".equals(opt)) {
21482 pw.println("Package manager dump options:");
21483 pw.println(" [-h] [-f] [--checkin] [cmd] ...");
21484 pw.println(" --checkin: dump for a checkin");
21485 pw.println(" -f: print details of intent filters");
21486 pw.println(" -h: print this help");
21487 pw.println(" cmd may be one of:");
21488 pw.println(" l[ibraries]: list known shared libraries");
21489 pw.println(" f[eatures]: list device features");
21490 pw.println(" k[eysets]: print known keysets");
21491 pw.println(" r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
21492 pw.println(" perm[issions]: dump permissions");
21493 pw.println(" permission [name ...]: dump declaration and use of given permission");
21494 pw.println(" pref[erred]: print preferred package settings");
21495 pw.println(" preferred-xml [--full]: print preferred package settings as xml");
21496 pw.println(" prov[iders]: dump content providers");
21497 pw.println(" p[ackages]: dump installed packages");
21498 pw.println(" s[hared-users]: dump shared user IDs");
21499 pw.println(" m[essages]: print collected runtime messages");
21500 pw.println(" v[erifiers]: print package verifier info");
21501 pw.println(" d[omain-preferred-apps]: print domains preferred apps");
21502 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
21503 pw.println(" version: print database version info");
21504 pw.println(" write: write current settings now");
21505 pw.println(" installs: details about install sessions");
21506 pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?");
21507 pw.println(" dexopt: dump dexopt state");
21508 pw.println(" compiler-stats: dump compiler statistics");
21509 pw.println(" service-permissions: dump permissions required by services");
21510 pw.println(" <package.name>: info about given package");
21512 } else if ("--checkin".equals(opt)) {
21514 } else if ("-f".equals(opt)) {
21515 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
21516 } else if ("--proto".equals(opt)) {
21520 pw.println("Unknown argument: " + opt + "; use -h for help");
21524 // Is the caller requesting to dump a particular piece of data?
21525 if (opti < args.length) {
21526 String cmd = args[opti];
21528 // Is this a package name?
21529 if ("android".equals(cmd) || cmd.contains(".")) {
21531 // When dumping a single package, we always dump all of its
21532 // filter information since the amount of data will be reasonable.
21533 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
21534 } else if ("check-permission".equals(cmd)) {
21535 if (opti >= args.length) {
21536 pw.println("Error: check-permission missing permission argument");
21539 String perm = args[opti];
21541 if (opti >= args.length) {
21542 pw.println("Error: check-permission missing package argument");
21546 String pkg = args[opti];
21548 int user = UserHandle.getUserId(Binder.getCallingUid());
21549 if (opti < args.length) {
21551 user = Integer.parseInt(args[opti]);
21552 } catch (NumberFormatException e) {
21553 pw.println("Error: check-permission user argument is not a number: "
21559 // Normalize package name to handle renamed packages and static libs
21560 pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
21562 pw.println(checkPermission(perm, pkg, user));
21564 } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
21565 dumpState.setDump(DumpState.DUMP_LIBS);
21566 } else if ("f".equals(cmd) || "features".equals(cmd)) {
21567 dumpState.setDump(DumpState.DUMP_FEATURES);
21568 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
21569 if (opti >= args.length) {
21570 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
21571 | DumpState.DUMP_SERVICE_RESOLVERS
21572 | DumpState.DUMP_RECEIVER_RESOLVERS
21573 | DumpState.DUMP_CONTENT_RESOLVERS);
21575 while (opti < args.length) {
21576 String name = args[opti];
21577 if ("a".equals(name) || "activity".equals(name)) {
21578 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
21579 } else if ("s".equals(name) || "service".equals(name)) {
21580 dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
21581 } else if ("r".equals(name) || "receiver".equals(name)) {
21582 dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
21583 } else if ("c".equals(name) || "content".equals(name)) {
21584 dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
21586 pw.println("Error: unknown resolver table type: " + name);
21592 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
21593 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
21594 } else if ("permission".equals(cmd)) {
21595 if (opti >= args.length) {
21596 pw.println("Error: permission requires permission name");
21599 permissionNames = new ArraySet<>();
21600 while (opti < args.length) {
21601 permissionNames.add(args[opti]);
21604 dumpState.setDump(DumpState.DUMP_PERMISSIONS
21605 | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
21606 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
21607 dumpState.setDump(DumpState.DUMP_PREFERRED);
21608 } else if ("preferred-xml".equals(cmd)) {
21609 dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
21610 if (opti < args.length && "--full".equals(args[opti])) {
21611 fullPreferred = true;
21614 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
21615 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
21616 } else if ("p".equals(cmd) || "packages".equals(cmd)) {
21617 dumpState.setDump(DumpState.DUMP_PACKAGES);
21618 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
21619 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
21620 } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
21621 dumpState.setDump(DumpState.DUMP_PROVIDERS);
21622 } else if ("m".equals(cmd) || "messages".equals(cmd)) {
21623 dumpState.setDump(DumpState.DUMP_MESSAGES);
21624 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
21625 dumpState.setDump(DumpState.DUMP_VERIFIERS);
21626 } else if ("i".equals(cmd) || "ifv".equals(cmd)
21627 || "intent-filter-verifiers".equals(cmd)) {
21628 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
21629 } else if ("version".equals(cmd)) {
21630 dumpState.setDump(DumpState.DUMP_VERSION);
21631 } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
21632 dumpState.setDump(DumpState.DUMP_KEYSETS);
21633 } else if ("installs".equals(cmd)) {
21634 dumpState.setDump(DumpState.DUMP_INSTALLS);
21635 } else if ("frozen".equals(cmd)) {
21636 dumpState.setDump(DumpState.DUMP_FROZEN);
21637 } else if ("volumes".equals(cmd)) {
21638 dumpState.setDump(DumpState.DUMP_VOLUMES);
21639 } else if ("dexopt".equals(cmd)) {
21640 dumpState.setDump(DumpState.DUMP_DEXOPT);
21641 } else if ("compiler-stats".equals(cmd)) {
21642 dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
21643 } else if ("changes".equals(cmd)) {
21644 dumpState.setDump(DumpState.DUMP_CHANGES);
21645 } else if ("service-permissions".equals(cmd)) {
21646 dumpState.setDump(DumpState.DUMP_SERVICE_PERMISSIONS);
21647 } else if ("write".equals(cmd)) {
21648 synchronized (mPackages) {
21649 mSettings.writeLPr();
21650 pw.println("Settings written.");
21657 pw.println("vers,1");
21661 synchronized (mPackages) {
21662 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
21664 if (dumpState.onTitlePrinted())
21666 pw.println("Database versions:");
21667 mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, " "));
21671 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
21673 if (dumpState.onTitlePrinted())
21675 pw.println("Verifiers:");
21676 pw.print(" Required: ");
21677 pw.print(mRequiredVerifierPackage);
21678 pw.print(" (uid=");
21679 pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
21680 UserHandle.USER_SYSTEM));
21682 } else if (mRequiredVerifierPackage != null) {
21683 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
21685 pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
21686 UserHandle.USER_SYSTEM));
21690 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
21691 packageName == null) {
21692 if (mIntentFilterVerifierComponent != null) {
21693 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
21695 if (dumpState.onTitlePrinted())
21697 pw.println("Intent Filter Verifier:");
21698 pw.print(" Using: ");
21699 pw.print(verifierPackageName);
21700 pw.print(" (uid=");
21701 pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
21702 UserHandle.USER_SYSTEM));
21704 } else if (verifierPackageName != null) {
21705 pw.print("ifv,"); pw.print(verifierPackageName);
21707 pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
21708 UserHandle.USER_SYSTEM));
21712 pw.println("No Intent Filter Verifier available!");
21716 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
21717 boolean printedHeader = false;
21718 final Iterator<String> it = mSharedLibraries.keySet().iterator();
21719 while (it.hasNext()) {
21720 String libName = it.next();
21721 LongSparseArray<SharedLibraryEntry> versionedLib
21722 = mSharedLibraries.get(libName);
21723 if (versionedLib == null) {
21726 final int versionCount = versionedLib.size();
21727 for (int i = 0; i < versionCount; i++) {
21728 SharedLibraryEntry libEntry = versionedLib.valueAt(i);
21730 if (!printedHeader) {
21731 if (dumpState.onTitlePrinted())
21733 pw.println("Libraries:");
21734 printedHeader = true;
21740 pw.print(libEntry.info.getName());
21741 if (libEntry.info.isStatic()) {
21742 pw.print(" version=" + libEntry.info.getLongVersion());
21747 if (libEntry.path != null) {
21748 pw.print(" (jar) ");
21749 pw.print(libEntry.path);
21751 pw.print(" (apk) ");
21752 pw.print(libEntry.apk);
21759 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
21760 if (dumpState.onTitlePrinted())
21763 pw.println("Features:");
21766 synchronized (mAvailableFeatures) {
21767 for (FeatureInfo feat : mAvailableFeatures.values()) {
21770 pw.print(feat.name);
21772 pw.println(feat.version);
21775 pw.print(feat.name);
21776 if (feat.version > 0) {
21777 pw.print(" version=");
21778 pw.print(feat.version);
21786 if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
21787 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
21788 : "Activity Resolver Table:", " ", packageName,
21789 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21790 dumpState.setTitlePrinted(true);
21793 if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
21794 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
21795 : "Receiver Resolver Table:", " ", packageName,
21796 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21797 dumpState.setTitlePrinted(true);
21800 if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
21801 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
21802 : "Service Resolver Table:", " ", packageName,
21803 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21804 dumpState.setTitlePrinted(true);
21807 if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
21808 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
21809 : "Provider Resolver Table:", " ", packageName,
21810 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21811 dumpState.setTitlePrinted(true);
21815 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
21816 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
21817 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
21818 int user = mSettings.mPreferredActivities.keyAt(i);
21820 dumpState.getTitlePrinted()
21821 ? "\nPreferred Activities User " + user + ":"
21822 : "Preferred Activities User " + user + ":", " ",
21823 packageName, true, false)) {
21824 dumpState.setTitlePrinted(true);
21829 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
21831 FileOutputStream fout = new FileOutputStream(fd);
21832 BufferedOutputStream str = new BufferedOutputStream(fout);
21833 XmlSerializer serializer = new FastXmlSerializer();
21835 serializer.setOutput(str, StandardCharsets.UTF_8.name());
21836 serializer.startDocument(null, true);
21837 serializer.setFeature(
21838 "http://xmlpull.org/v1/doc/features.html#indent-output", true);
21839 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
21840 serializer.endDocument();
21841 serializer.flush();
21842 } catch (IllegalArgumentException e) {
21843 pw.println("Failed writing: " + e);
21844 } catch (IllegalStateException e) {
21845 pw.println("Failed writing: " + e);
21846 } catch (IOException e) {
21847 pw.println("Failed writing: " + e);
21852 && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
21853 && packageName == null) {
21855 int count = mSettings.mPackages.size();
21857 pw.println("No applications!");
21860 final String prefix = " ";
21861 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
21862 if (allPackageSettings.size() == 0) {
21863 pw.println("No domain preferred apps!");
21866 pw.println("App verification status:");
21869 for (PackageSetting ps : allPackageSettings) {
21870 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
21871 if (ivi == null || ivi.getPackageName() == null) continue;
21872 pw.println(prefix + "Package: " + ivi.getPackageName());
21873 pw.println(prefix + "Domains: " + ivi.getDomainsString());
21874 pw.println(prefix + "Status: " + ivi.getStatusString());
21879 pw.println(prefix + "No app verification established.");
21882 for (int userId : sUserManager.getUserIds()) {
21883 pw.println("App linkages for user " + userId + ":");
21886 for (PackageSetting ps : allPackageSettings) {
21887 final long status = ps.getDomainVerificationStatusForUser(userId);
21888 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
21889 && !DEBUG_DOMAIN_VERIFICATION) {
21892 pw.println(prefix + "Package: " + ps.name);
21893 pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
21894 String statusStr = IntentFilterVerificationInfo.
21895 getStatusStringFromValue(status);
21896 pw.println(prefix + "Status: " + statusStr);
21901 pw.println(prefix + "No configured app linkages.");
21909 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
21910 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
21913 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
21914 boolean printedSomething = false;
21915 for (PackageParser.Provider p : mProviders.mProviders.values()) {
21916 if (packageName != null && !packageName.equals(p.info.packageName)) {
21919 if (!printedSomething) {
21920 if (dumpState.onTitlePrinted())
21922 pw.println("Registered ContentProviders:");
21923 printedSomething = true;
21925 pw.print(" "); p.printComponentShortName(pw); pw.println(":");
21926 pw.print(" "); pw.println(p.toString());
21928 printedSomething = false;
21929 for (Map.Entry<String, PackageParser.Provider> entry :
21930 mProvidersByAuthority.entrySet()) {
21931 PackageParser.Provider p = entry.getValue();
21932 if (packageName != null && !packageName.equals(p.info.packageName)) {
21935 if (!printedSomething) {
21936 if (dumpState.onTitlePrinted())
21938 pw.println("ContentProvider Authorities:");
21939 printedSomething = true;
21941 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:");
21942 pw.print(" "); pw.println(p.toString());
21943 if (p.info != null && p.info.applicationInfo != null) {
21944 final String appInfo = p.info.applicationInfo.toString();
21945 pw.print(" applicationInfo="); pw.println(appInfo);
21950 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
21951 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
21954 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
21955 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
21958 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
21959 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
21962 if (dumpState.isDumping(DumpState.DUMP_CHANGES)) {
21963 if (dumpState.onTitlePrinted()) pw.println();
21964 pw.println("Package Changes:");
21965 pw.print(" Sequence number="); pw.println(mChangedPackagesSequenceNumber);
21966 final int K = mChangedPackages.size();
21967 for (int i = 0; i < K; i++) {
21968 final SparseArray<String> changes = mChangedPackages.valueAt(i);
21969 pw.print(" User "); pw.print(mChangedPackages.keyAt(i)); pw.println(":");
21970 final int N = changes.size();
21972 pw.print(" "); pw.println("No packages changed");
21974 for (int j = 0; j < N; j++) {
21975 final String pkgName = changes.valueAt(j);
21976 final int sequenceNumber = changes.keyAt(j);
21979 pw.print(sequenceNumber);
21980 pw.print(", package=");
21981 pw.println(pkgName);
21987 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
21988 mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
21991 if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
21992 // XXX should handle packageName != null by dumping only install data that
21993 // the given package is involved with.
21994 if (dumpState.onTitlePrinted()) pw.println();
21996 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120);
21998 ipw.println("Frozen packages:");
21999 ipw.increaseIndent();
22000 if (mFrozenPackages.size() == 0) {
22001 ipw.println("(none)");
22003 for (int i = 0; i < mFrozenPackages.size(); i++) {
22004 ipw.println(mFrozenPackages.valueAt(i));
22007 ipw.decreaseIndent();
22010 if (!checkin && dumpState.isDumping(DumpState.DUMP_VOLUMES) && packageName == null) {
22011 if (dumpState.onTitlePrinted()) pw.println();
22013 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120);
22015 ipw.println("Loaded volumes:");
22016 ipw.increaseIndent();
22017 if (mLoadedVolumes.size() == 0) {
22018 ipw.println("(none)");
22020 for (int i = 0; i < mLoadedVolumes.size(); i++) {
22021 ipw.println(mLoadedVolumes.valueAt(i));
22024 ipw.decreaseIndent();
22027 if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_PERMISSIONS)
22028 && packageName == null) {
22029 if (dumpState.onTitlePrinted()) pw.println();
22030 pw.println("Service permissions:");
22032 final Iterator<ServiceIntentInfo> filterIterator = mServices.filterIterator();
22033 while (filterIterator.hasNext()) {
22034 final ServiceIntentInfo info = filterIterator.next();
22035 final ServiceInfo serviceInfo = info.service.info;
22036 final String permission = serviceInfo.permission;
22037 if (permission != null) {
22039 pw.print(serviceInfo.getComponentName().flattenToShortString());
22041 pw.println(permission);
22046 if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
22047 if (dumpState.onTitlePrinted()) pw.println();
22048 dumpDexoptStateLPr(pw, packageName);
22051 if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
22052 if (dumpState.onTitlePrinted()) pw.println();
22053 dumpCompilerStatsLPr(pw, packageName);
22056 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
22057 if (dumpState.onTitlePrinted()) pw.println();
22058 mSettings.dumpReadMessagesLPr(pw, dumpState);
22061 pw.println("Package warning messages:");
22062 dumpCriticalInfo(pw, null);
22065 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
22066 dumpCriticalInfo(pw, "msg,");
22070 // PackageInstaller should be called outside of mPackages lock
22071 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
22072 // XXX should handle packageName != null by dumping only install data that
22073 // the given package is involved with.
22074 if (dumpState.onTitlePrinted()) pw.println();
22075 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120));
22079 //TODO: b/111402650
22080 private void disableSkuSpecificApps() {
22081 String apkList[] = mContext.getResources().getStringArray(
22082 R.array.config_disableApksUnlessMatchedSku_apk_list);
22083 String skuArray[] = mContext.getResources().getStringArray(
22084 R.array.config_disableApkUnlessMatchedSku_skus_list);
22085 if (ArrayUtils.isEmpty(apkList)) {
22088 String sku = SystemProperties.get("ro.boot.hardware.sku");
22089 if (!TextUtils.isEmpty(sku) && ArrayUtils.contains(skuArray, sku)) {
22092 for (String packageName : apkList) {
22093 setSystemAppHiddenUntilInstalled(packageName, true);
22094 for (UserInfo user : sUserManager.getUsers(false)) {
22095 setSystemAppInstallState(packageName, false, user.id);
22100 private void dumpProto(FileDescriptor fd) {
22101 final ProtoOutputStream proto = new ProtoOutputStream(fd);
22103 synchronized (mPackages) {
22104 final long requiredVerifierPackageToken =
22105 proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
22106 proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
22108 PackageServiceDumpProto.PackageShortProto.UID,
22110 mRequiredVerifierPackage,
22111 MATCH_DEBUG_TRIAGED_MISSING,
22112 UserHandle.USER_SYSTEM));
22113 proto.end(requiredVerifierPackageToken);
22115 if (mIntentFilterVerifierComponent != null) {
22116 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
22117 final long verifierPackageToken =
22118 proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
22119 proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
22121 PackageServiceDumpProto.PackageShortProto.UID,
22123 verifierPackageName,
22124 MATCH_DEBUG_TRIAGED_MISSING,
22125 UserHandle.USER_SYSTEM));
22126 proto.end(verifierPackageToken);
22129 dumpSharedLibrariesProto(proto);
22130 dumpFeaturesProto(proto);
22131 mSettings.dumpPackagesProto(proto);
22132 mSettings.dumpSharedUsersProto(proto);
22133 dumpCriticalInfo(proto);
22138 private void dumpFeaturesProto(ProtoOutputStream proto) {
22139 synchronized (mAvailableFeatures) {
22140 final int count = mAvailableFeatures.size();
22141 for (int i = 0; i < count; i++) {
22142 mAvailableFeatures.valueAt(i).writeToProto(proto, PackageServiceDumpProto.FEATURES);
22147 private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
22148 final int count = mSharedLibraries.size();
22149 for (int i = 0; i < count; i++) {
22150 final String libName = mSharedLibraries.keyAt(i);
22151 LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
22152 if (versionedLib == null) {
22155 final int versionCount = versionedLib.size();
22156 for (int j = 0; j < versionCount; j++) {
22157 final SharedLibraryEntry libEntry = versionedLib.valueAt(j);
22158 final long sharedLibraryToken =
22159 proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
22160 proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libEntry.info.getName());
22161 final boolean isJar = (libEntry.path != null);
22162 proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
22164 proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH, libEntry.path);
22166 proto.write(PackageServiceDumpProto.SharedLibraryProto.APK, libEntry.apk);
22168 proto.end(sharedLibraryToken);
22173 private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
22174 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
22176 ipw.println("Dexopt state:");
22177 ipw.increaseIndent();
22178 Collection<PackageParser.Package> packages = null;
22179 if (packageName != null) {
22180 PackageParser.Package targetPackage = mPackages.get(packageName);
22181 if (targetPackage != null) {
22182 packages = Collections.singletonList(targetPackage);
22184 ipw.println("Unable to find package: " + packageName);
22188 packages = mPackages.values();
22191 for (PackageParser.Package pkg : packages) {
22192 ipw.println("[" + pkg.packageName + "]");
22193 ipw.increaseIndent();
22194 mPackageDexOptimizer.dumpDexoptState(ipw, pkg,
22195 mDexManager.getPackageUseInfoOrDefault(pkg.packageName));
22196 ipw.decreaseIndent();
22200 private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
22201 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
22203 ipw.println("Compiler stats:");
22204 ipw.increaseIndent();
22205 Collection<PackageParser.Package> packages = null;
22206 if (packageName != null) {
22207 PackageParser.Package targetPackage = mPackages.get(packageName);
22208 if (targetPackage != null) {
22209 packages = Collections.singletonList(targetPackage);
22211 ipw.println("Unable to find package: " + packageName);
22215 packages = mPackages.values();
22218 for (PackageParser.Package pkg : packages) {
22219 ipw.println("[" + pkg.packageName + "]");
22220 ipw.increaseIndent();
22222 CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
22223 if (stats == null) {
22224 ipw.println("(No recorded stats)");
22228 ipw.decreaseIndent();
22232 private String dumpDomainString(String packageName) {
22233 List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
22235 List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
22237 ArraySet<String> result = new ArraySet<>();
22238 if (iviList.size() > 0) {
22239 for (IntentFilterVerificationInfo ivi : iviList) {
22240 for (String host : ivi.getDomains()) {
22245 if (filters != null && filters.size() > 0) {
22246 for (IntentFilter filter : filters) {
22247 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
22248 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
22249 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
22250 result.addAll(filter.getHostsList());
22255 StringBuilder sb = new StringBuilder(result.size() * 16);
22256 for (String domain : result) {
22257 if (sb.length() > 0) sb.append(" ");
22260 return sb.toString();
22263 // ------- apps on sdcard specific code -------
22264 static final boolean DEBUG_SD_INSTALL = false;
22266 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
22268 private static final String SD_ENCRYPTION_ALGORITHM = "AES";
22270 private boolean mMediaMounted = false;
22272 static String getEncryptKey() {
22274 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
22275 SD_ENCRYPTION_KEYSTORE_NAME);
22276 if (sdEncKey == null) {
22277 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
22278 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
22279 if (sdEncKey == null) {
22280 Slog.e(TAG, "Failed to create encryption keys");
22285 } catch (NoSuchAlgorithmException nsae) {
22286 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
22288 } catch (IOException ioe) {
22289 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
22294 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
22295 ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
22296 final int size = infos.size();
22297 final String[] packageNames = new String[size];
22298 final int[] packageUids = new int[size];
22299 for (int i = 0; i < size; i++) {
22300 final ApplicationInfo info = infos.get(i);
22301 packageNames[i] = info.packageName;
22302 packageUids[i] = info.uid;
22304 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
22308 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
22309 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
22310 sendResourcesChangedBroadcast(mediaStatus, replacing,
22311 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
22314 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
22315 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
22316 int size = pkgList.length;
22318 // Send broadcasts here
22319 Bundle extras = new Bundle();
22320 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
22321 if (uidArr != null) {
22322 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
22325 extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
22327 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
22328 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
22329 sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null, null);
22333 private void loadPrivatePackages(final VolumeInfo vol) {
22334 mHandler.post(new Runnable() {
22336 public void run() {
22337 loadPrivatePackagesInner(vol);
22342 private void loadPrivatePackagesInner(VolumeInfo vol) {
22343 final String volumeUuid = vol.fsUuid;
22344 if (TextUtils.isEmpty(volumeUuid)) {
22345 Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
22349 final ArrayList<PackageFreezer> freezers = new ArrayList<>();
22350 final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
22351 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
22353 final VersionInfo ver;
22354 final List<PackageSetting> packages;
22355 synchronized (mPackages) {
22356 ver = mSettings.findOrCreateVersion(volumeUuid);
22357 packages = mSettings.getVolumePackagesLPr(volumeUuid);
22360 for (PackageSetting ps : packages) {
22361 freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
22362 synchronized (mInstallLock) {
22363 final PackageParser.Package pkg;
22365 pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
22366 loaded.add(pkg.applicationInfo);
22368 } catch (PackageManagerException e) {
22369 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
22372 if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
22373 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
22374 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
22375 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
22380 // Reconcile app data for all started/unlocked users
22381 final StorageManager sm = mContext.getSystemService(StorageManager.class);
22382 final UserManager um = mContext.getSystemService(UserManager.class);
22383 UserManagerInternal umInternal = getUserManagerInternal();
22384 for (UserInfo user : um.getUsers()) {
22386 if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
22387 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
22388 } else if (umInternal.isUserRunning(user.id)) {
22389 flags = StorageManager.FLAG_STORAGE_DE;
22395 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
22396 synchronized (mInstallLock) {
22397 reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
22399 } catch (IllegalStateException e) {
22400 // Device was probably ejected, and we'll process that event momentarily
22401 Slog.w(TAG, "Failed to prepare storage: " + e);
22405 synchronized (mPackages) {
22406 final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
22408 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
22409 + mSdkVersion + "; regranting permissions for " + volumeUuid);
22411 mPermissionManager.updateAllPermissions(volumeUuid, sdkUpdated, mPackages.values(),
22412 mPermissionCallback);
22414 // Yay, everything is now upgraded
22415 ver.forceCurrent();
22417 mSettings.writeLPr();
22420 for (PackageFreezer freezer : freezers) {
22424 if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
22425 sendResourcesChangedBroadcast(true, false, loaded, null);
22426 mLoadedVolumes.add(vol.getId());
22429 private void unloadPrivatePackages(final VolumeInfo vol) {
22430 mHandler.post(new Runnable() {
22432 public void run() {
22433 unloadPrivatePackagesInner(vol);
22438 private void unloadPrivatePackagesInner(VolumeInfo vol) {
22439 final String volumeUuid = vol.fsUuid;
22440 if (TextUtils.isEmpty(volumeUuid)) {
22441 Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
22445 final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
22446 synchronized (mInstallLock) {
22447 synchronized (mPackages) {
22448 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
22449 for (PackageSetting ps : packages) {
22450 if (ps.pkg == null) continue;
22452 final ApplicationInfo info = ps.pkg.applicationInfo;
22453 final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
22454 final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
22456 try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
22457 "unloadPrivatePackagesInner")) {
22458 if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
22460 unloaded.add(info);
22462 Slog.w(TAG, "Failed to unload " + ps.codePath);
22466 // Try very hard to release any references to this package
22467 // so we don't risk the system server being killed due to
22469 AttributeCache.instance().removePackage(ps.name);
22472 mSettings.writeLPr();
22476 if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
22477 sendResourcesChangedBroadcast(false, false, unloaded, null);
22478 mLoadedVolumes.remove(vol.getId());
22480 // Try very hard to release any references to this path so we don't risk
22481 // the system server being killed due to open FDs
22482 ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
22484 for (int i = 0; i < 3; i++) {
22486 System.runFinalization();
22490 private void assertPackageKnown(String volumeUuid, String packageName)
22491 throws PackageManagerException {
22492 synchronized (mPackages) {
22493 // Normalize package name to handle renamed packages
22494 packageName = normalizePackageNameLPr(packageName);
22496 final PackageSetting ps = mSettings.mPackages.get(packageName);
22498 throw new PackageManagerException("Package " + packageName + " is unknown");
22499 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
22500 throw new PackageManagerException(
22501 "Package " + packageName + " found on unknown volume " + volumeUuid
22502 + "; expected volume " + ps.volumeUuid);
22507 private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
22508 throws PackageManagerException {
22509 synchronized (mPackages) {
22510 // Normalize package name to handle renamed packages
22511 packageName = normalizePackageNameLPr(packageName);
22513 final PackageSetting ps = mSettings.mPackages.get(packageName);
22515 throw new PackageManagerException("Package " + packageName + " is unknown");
22516 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
22517 throw new PackageManagerException(
22518 "Package " + packageName + " found on unknown volume " + volumeUuid
22519 + "; expected volume " + ps.volumeUuid);
22520 } else if (!ps.getInstalled(userId)) {
22521 throw new PackageManagerException(
22522 "Package " + packageName + " not installed for user " + userId);
22527 private List<String> collectAbsoluteCodePaths() {
22528 synchronized (mPackages) {
22529 List<String> codePaths = new ArrayList<>();
22530 final int packageCount = mSettings.mPackages.size();
22531 for (int i = 0; i < packageCount; i++) {
22532 final PackageSetting ps = mSettings.mPackages.valueAt(i);
22533 codePaths.add(ps.codePath.getAbsolutePath());
22540 * Examine all apps present on given mounted volume, and destroy apps that
22541 * aren't expected, either due to uninstallation or reinstallation on
22544 private void reconcileApps(String volumeUuid) {
22545 List<String> absoluteCodePaths = collectAbsoluteCodePaths();
22546 List<File> filesToDelete = null;
22548 final File[] files = FileUtils.listFilesOrEmpty(
22549 Environment.getDataAppDirectory(volumeUuid));
22550 for (File file : files) {
22551 final boolean isPackage = (isApkFile(file) || file.isDirectory())
22552 && !PackageInstallerService.isStageName(file.getName());
22554 // Ignore entries which are not packages
22558 String absolutePath = file.getAbsolutePath();
22560 boolean pathValid = false;
22561 final int absoluteCodePathCount = absoluteCodePaths.size();
22562 for (int i = 0; i < absoluteCodePathCount; i++) {
22563 String absoluteCodePath = absoluteCodePaths.get(i);
22564 if (absolutePath.startsWith(absoluteCodePath)) {
22571 if (filesToDelete == null) {
22572 filesToDelete = new ArrayList<>();
22574 filesToDelete.add(file);
22578 if (filesToDelete != null) {
22579 final int fileToDeleteCount = filesToDelete.size();
22580 for (int i = 0; i < fileToDeleteCount; i++) {
22581 File fileToDelete = filesToDelete.get(i);
22582 logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
22583 synchronized (mInstallLock) {
22584 removeCodePathLI(fileToDelete);
22591 * Reconcile all app data for the given user.
22593 * Verifies that directories exist and that ownership and labeling is
22594 * correct for all installed apps on all mounted volumes.
22596 void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
22597 final StorageManager storage = mContext.getSystemService(StorageManager.class);
22598 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
22599 final String volumeUuid = vol.getFsUuid();
22600 synchronized (mInstallLock) {
22601 reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
22606 private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
22607 boolean migrateAppData) {
22608 reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
22612 * Reconcile all app data on given mounted volume.
22614 * Destroys app data that isn't expected, either due to uninstallation or
22615 * reinstallation on another volume.
22617 * Verifies that directories exist and that ownership and labeling is
22618 * correct for all installed apps.
22619 * @returns list of skipped non-core packages (if {@code onlyCoreApps} is true)
22621 private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
22622 boolean migrateAppData, boolean onlyCoreApps) {
22623 Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
22624 + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
22625 List<String> result = onlyCoreApps ? new ArrayList<>() : null;
22627 final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
22628 final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
22630 // First look for stale data that doesn't belong, and check if things
22631 // have changed since we did our last restorecon
22632 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
22633 if (StorageManager.isFileEncryptedNativeOrEmulated()
22634 && !StorageManager.isUserKeyUnlocked(userId)) {
22635 throw new RuntimeException(
22636 "Yikes, someone asked us to reconcile CE storage while " + userId
22637 + " was still locked; this would have caused massive data loss!");
22640 final File[] files = FileUtils.listFilesOrEmpty(ceDir);
22641 for (File file : files) {
22642 final String packageName = file.getName();
22644 assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
22645 } catch (PackageManagerException e) {
22646 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
22648 mInstaller.destroyAppData(volumeUuid, packageName, userId,
22649 StorageManager.FLAG_STORAGE_CE, 0);
22650 } catch (InstallerException e2) {
22651 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
22656 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
22657 final File[] files = FileUtils.listFilesOrEmpty(deDir);
22658 for (File file : files) {
22659 final String packageName = file.getName();
22661 assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
22662 } catch (PackageManagerException e) {
22663 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
22665 mInstaller.destroyAppData(volumeUuid, packageName, userId,
22666 StorageManager.FLAG_STORAGE_DE, 0);
22667 } catch (InstallerException e2) {
22668 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
22674 // Ensure that data directories are ready to roll for all packages
22675 // installed for this volume and user
22676 final List<PackageSetting> packages;
22677 synchronized (mPackages) {
22678 packages = mSettings.getVolumePackagesLPr(volumeUuid);
22680 int preparedCount = 0;
22681 for (PackageSetting ps : packages) {
22682 final String packageName = ps.name;
22683 if (ps.pkg == null) {
22684 Slog.w(TAG, "Odd, missing scanned package " + packageName);
22685 // TODO: might be due to legacy ASEC apps; we should circle back
22686 // and reconcile again once they're scanned
22689 // Skip non-core apps if requested
22690 if (onlyCoreApps && !ps.pkg.coreApp) {
22691 result.add(packageName);
22695 if (ps.getInstalled(userId)) {
22696 prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
22701 Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
22706 * Prepare app data for the given app just after it was installed or
22707 * upgraded. This method carefully only touches users that it's installed
22708 * for, and it forces a restorecon to handle any seinfo changes.
22710 * Verifies that directories exist and that ownership and labeling is
22711 * correct for all installed apps. If there is an ownership mismatch, it
22712 * will try recovering system apps by wiping data; third-party app data is
22715 * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
22717 private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
22718 final PackageSetting ps;
22719 synchronized (mPackages) {
22720 ps = mSettings.mPackages.get(pkg.packageName);
22721 mSettings.writeKernelMappingLPr(ps);
22724 final UserManagerService um = sUserManager;
22725 UserManagerInternal umInternal = getUserManagerInternal();
22726 for (UserInfo user : um.getUsers(false /* excludeDying */)) {
22728 if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
22729 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
22730 } else if (umInternal.isUserRunning(user.id)) {
22731 flags = StorageManager.FLAG_STORAGE_DE;
22736 if (ps.getInstalled(user.id)) {
22737 // TODO: when user data is locked, mark that we're still dirty
22738 prepareAppDataLIF(pkg, user.id, flags);
22744 * Prepare app data for the given app.
22746 * Verifies that directories exist and that ownership and labeling is
22747 * correct for all installed apps. If there is an ownership mismatch, this
22748 * will try recovering system apps by wiping data; third-party app data is
22751 private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
22753 Slog.wtf(TAG, "Package was null!", new Throwable());
22756 prepareAppDataLeafLIF(pkg, userId, flags);
22757 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
22758 for (int i = 0; i < childCount; i++) {
22759 prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
22763 private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags,
22764 boolean maybeMigrateAppData) {
22765 prepareAppDataLIF(pkg, userId, flags);
22767 if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
22768 // We may have just shuffled around app data directories, so
22769 // prepare them one more time
22770 prepareAppDataLIF(pkg, userId, flags);
22774 private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
22775 if (DEBUG_APP_DATA) {
22776 Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
22777 + Integer.toHexString(flags));
22780 final PackageSetting ps;
22781 synchronized (mPackages) {
22782 ps = mSettings.mPackages.get(pkg.packageName);
22784 final String volumeUuid = pkg.volumeUuid;
22785 final String packageName = pkg.packageName;
22787 ApplicationInfo app = (ps == null)
22788 ? pkg.applicationInfo
22789 : PackageParser.generateApplicationInfo(pkg, 0, ps.readUserState(userId), userId);
22791 app = pkg.applicationInfo;
22794 final int appId = UserHandle.getAppId(app.uid);
22796 Preconditions.checkNotNull(app.seInfo);
22798 final String seInfo = app.seInfo + (app.seInfoUser != null ? app.seInfoUser : "");
22799 long ceDataInode = -1;
22801 ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
22802 appId, seInfo, app.targetSdkVersion);
22803 } catch (InstallerException e) {
22804 if (app.isSystemApp()) {
22805 logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
22806 + ", but trying to recover: " + e);
22807 destroyAppDataLeafLIF(pkg, userId, flags);
22809 ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
22810 appId, seInfo, app.targetSdkVersion);
22811 logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
22812 } catch (InstallerException e2) {
22813 logCriticalInfo(Log.DEBUG, "Recovery failed!");
22816 Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
22819 // Prepare the application profiles only for upgrades and first boot (so that we don't
22820 // repeat the same operation at each boot).
22821 // We only have to cover the upgrade and first boot here because for app installs we
22822 // prepare the profiles before invoking dexopt (in installPackageLI).
22824 // We also have to cover non system users because we do not call the usual install package
22825 // methods for them.
22826 if (mIsUpgrade || mFirstBoot || (userId != UserHandle.USER_SYSTEM)) {
22827 mArtManagerService.prepareAppProfiles(pkg, userId);
22830 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
22831 // TODO: mark this structure as dirty so we persist it!
22832 synchronized (mPackages) {
22834 ps.setCeDataInode(ceDataInode, userId);
22839 prepareAppDataContentsLeafLIF(pkg, userId, flags);
22842 private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
22844 Slog.wtf(TAG, "Package was null!", new Throwable());
22847 prepareAppDataContentsLeafLIF(pkg, userId, flags);
22848 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
22849 for (int i = 0; i < childCount; i++) {
22850 prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
22854 private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
22855 final String volumeUuid = pkg.volumeUuid;
22856 final String packageName = pkg.packageName;
22857 final ApplicationInfo app = pkg.applicationInfo;
22859 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
22860 // Create a native library symlink only if we have native libraries
22861 // and if the native libraries are 32 bit libraries. We do not provide
22862 // this symlink for 64 bit libraries.
22863 if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
22864 final String nativeLibPath = app.nativeLibraryDir;
22866 mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
22867 nativeLibPath, userId);
22868 } catch (InstallerException e) {
22869 Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
22876 * For system apps on non-FBE devices, this method migrates any existing
22877 * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
22878 * requested by the app.
22880 private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
22881 if (pkg.isSystem() && !StorageManager.isFileEncryptedNativeOrEmulated()
22882 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
22883 final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
22884 ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
22886 mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
22888 } catch (InstallerException e) {
22889 logCriticalInfo(Log.WARN,
22890 "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
22898 public PackageFreezer freezePackage(String packageName, String killReason) {
22899 return freezePackage(packageName, UserHandle.USER_ALL, killReason);
22902 public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
22903 return new PackageFreezer(packageName, userId, killReason);
22906 public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
22907 String killReason) {
22908 return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
22911 public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
22912 String killReason) {
22913 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
22914 return new PackageFreezer();
22916 return freezePackage(packageName, userId, killReason);
22920 public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
22921 String killReason) {
22922 return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
22925 public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
22926 String killReason) {
22927 if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
22928 return new PackageFreezer();
22930 return freezePackage(packageName, userId, killReason);
22935 * Class that freezes and kills the given package upon creation, and
22936 * unfreezes it upon closing. This is typically used when doing surgery on
22937 * app code/data to prevent the app from running while you're working.
22939 private class PackageFreezer implements AutoCloseable {
22940 private final String mPackageName;
22941 private final PackageFreezer[] mChildren;
22943 private final boolean mWeFroze;
22945 private final AtomicBoolean mClosed = new AtomicBoolean();
22946 private final CloseGuard mCloseGuard = CloseGuard.get();
22949 * Create and return a stub freezer that doesn't actually do anything,
22950 * typically used when someone requested
22951 * {@link PackageManager#INSTALL_DONT_KILL_APP} or
22952 * {@link PackageManager#DELETE_DONT_KILL_APP}.
22954 public PackageFreezer() {
22955 mPackageName = null;
22958 mCloseGuard.open("close");
22961 public PackageFreezer(String packageName, int userId, String killReason) {
22962 synchronized (mPackages) {
22963 mPackageName = packageName;
22964 mWeFroze = mFrozenPackages.add(mPackageName);
22966 final PackageSetting ps = mSettings.mPackages.get(mPackageName);
22968 killApplication(ps.name, ps.appId, userId, killReason);
22971 final PackageParser.Package p = mPackages.get(packageName);
22972 if (p != null && p.childPackages != null) {
22973 final int N = p.childPackages.size();
22974 mChildren = new PackageFreezer[N];
22975 for (int i = 0; i < N; i++) {
22976 mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
22977 userId, killReason);
22983 mCloseGuard.open("close");
22987 protected void finalize() throws Throwable {
22989 if (mCloseGuard != null) {
22990 mCloseGuard.warnIfOpen();
23000 public void close() {
23001 mCloseGuard.close();
23002 if (mClosed.compareAndSet(false, true)) {
23003 synchronized (mPackages) {
23005 mFrozenPackages.remove(mPackageName);
23008 if (mChildren != null) {
23009 for (PackageFreezer freezer : mChildren) {
23019 * Verify that given package is currently frozen.
23021 private void checkPackageFrozen(String packageName) {
23022 synchronized (mPackages) {
23023 if (!mFrozenPackages.contains(packageName)) {
23024 Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
23030 public int movePackage(final String packageName, final String volumeUuid) {
23031 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
23033 final int callingUid = Binder.getCallingUid();
23034 final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
23035 final int moveId = mNextMoveId.getAndIncrement();
23036 mHandler.post(new Runnable() {
23038 public void run() {
23040 movePackageInternal(packageName, volumeUuid, moveId, callingUid, user);
23041 } catch (PackageManagerException e) {
23042 Slog.w(TAG, "Failed to move " + packageName, e);
23043 mMoveCallbacks.notifyStatusChanged(moveId, e.error);
23050 private void movePackageInternal(final String packageName, final String volumeUuid,
23051 final int moveId, final int callingUid, UserHandle user)
23052 throws PackageManagerException {
23053 final StorageManager storage = mContext.getSystemService(StorageManager.class);
23054 final PackageManager pm = mContext.getPackageManager();
23056 final boolean currentAsec;
23057 final String currentVolumeUuid;
23058 final File codeFile;
23059 final String installerPackageName;
23060 final String packageAbiOverride;
23062 final String seinfo;
23063 final String label;
23064 final int targetSdkVersion;
23065 final PackageFreezer freezer;
23066 final int[] installedUserIds;
23069 synchronized (mPackages) {
23070 final PackageParser.Package pkg = mPackages.get(packageName);
23071 final PackageSetting ps = mSettings.mPackages.get(packageName);
23074 || filterAppAccessLPr(ps, callingUid, user.getIdentifier())) {
23075 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
23077 if (pkg.applicationInfo.isSystemApp()) {
23078 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
23079 "Cannot move system application");
23082 final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
23083 final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
23084 com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
23085 if (isInternalStorage && !allow3rdPartyOnInternal) {
23086 throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
23087 "3rd party apps are not allowed on internal storage");
23090 if (pkg.applicationInfo.isExternalAsec()) {
23091 currentAsec = true;
23092 currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
23093 } else if (pkg.applicationInfo.isForwardLocked()) {
23094 currentAsec = true;
23095 currentVolumeUuid = "forward_locked";
23097 currentAsec = false;
23098 currentVolumeUuid = ps.volumeUuid;
23100 final File probe = new File(pkg.codePath);
23101 final File probeOat = new File(probe, "oat");
23102 if (!probe.isDirectory() || !probeOat.isDirectory()) {
23103 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23104 "Move only supported for modern cluster style installs");
23108 if (Objects.equals(currentVolumeUuid, volumeUuid)) {
23109 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23110 "Package already moved to " + volumeUuid);
23112 if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
23113 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
23114 "Device admin cannot be moved");
23117 if (mFrozenPackages.contains(packageName)) {
23118 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
23119 "Failed to move already frozen package");
23122 codeFile = new File(pkg.codePath);
23123 installerPackageName = ps.installerPackageName;
23124 packageAbiOverride = ps.cpuAbiOverrideString;
23125 appId = UserHandle.getAppId(pkg.applicationInfo.uid);
23126 seinfo = pkg.applicationInfo.seInfo;
23127 label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
23128 targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
23129 freezer = freezePackage(packageName, "movePackageInternal");
23130 installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
23133 final Bundle extras = new Bundle();
23134 extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
23135 extras.putString(Intent.EXTRA_TITLE, label);
23136 mMoveCallbacks.notifyCreated(moveId, extras);
23139 final boolean moveCompleteApp;
23140 final File measurePath;
23142 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
23143 installFlags = INSTALL_INTERNAL;
23144 moveCompleteApp = !currentAsec;
23145 measurePath = Environment.getDataAppDirectory(volumeUuid);
23146 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
23147 installFlags = INSTALL_EXTERNAL;
23148 moveCompleteApp = false;
23149 measurePath = storage.getPrimaryPhysicalVolume().getPath();
23151 final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
23152 if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
23153 || !volume.isMountedWritable()) {
23155 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23156 "Move location not mounted private volume");
23159 Preconditions.checkState(!currentAsec);
23161 installFlags = INSTALL_INTERNAL;
23162 moveCompleteApp = true;
23163 measurePath = Environment.getDataAppDirectory(volumeUuid);
23166 // If we're moving app data around, we need all the users unlocked
23167 if (moveCompleteApp) {
23168 for (int userId : installedUserIds) {
23169 if (StorageManager.isFileEncryptedNativeOrEmulated()
23170 && !StorageManager.isUserKeyUnlocked(userId)) {
23171 throw new PackageManagerException(MOVE_FAILED_LOCKED_USER,
23172 "User " + userId + " must be unlocked");
23177 final PackageStats stats = new PackageStats(null, -1);
23178 synchronized (mInstaller) {
23179 for (int userId : installedUserIds) {
23180 if (!getPackageSizeInfoLI(packageName, userId, stats)) {
23182 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23183 "Failed to measure package size");
23188 if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
23191 final long startFreeBytes = measurePath.getUsableSpace();
23192 final long sizeBytes;
23193 if (moveCompleteApp) {
23194 sizeBytes = stats.codeSize + stats.dataSize;
23196 sizeBytes = stats.codeSize;
23199 if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
23201 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23202 "Not enough free space to move");
23205 mMoveCallbacks.notifyStatusChanged(moveId, 10);
23207 final CountDownLatch installedLatch = new CountDownLatch(1);
23208 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
23210 public void onUserActionRequired(Intent intent) throws RemoteException {
23211 throw new IllegalStateException();
23215 public void onPackageInstalled(String basePackageName, int returnCode, String msg,
23216 Bundle extras) throws RemoteException {
23217 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
23218 + PackageManager.installStatusToString(returnCode, msg));
23220 installedLatch.countDown();
23223 final int status = PackageManager.installStatusToPublicStatus(returnCode);
23225 case PackageInstaller.STATUS_SUCCESS:
23226 mMoveCallbacks.notifyStatusChanged(moveId,
23227 PackageManager.MOVE_SUCCEEDED);
23229 case PackageInstaller.STATUS_FAILURE_STORAGE:
23230 mMoveCallbacks.notifyStatusChanged(moveId,
23231 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
23234 mMoveCallbacks.notifyStatusChanged(moveId,
23235 PackageManager.MOVE_FAILED_INTERNAL_ERROR);
23241 final MoveInfo move;
23242 if (moveCompleteApp) {
23243 // Kick off a thread to report progress estimates
23246 public void run() {
23249 if (installedLatch.await(1, TimeUnit.SECONDS)) {
23252 } catch (InterruptedException ignored) {
23255 final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
23256 final int progress = 10 + (int) MathUtils.constrain(
23257 ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
23258 mMoveCallbacks.notifyStatusChanged(moveId, progress);
23263 final String dataAppName = codeFile.getName();
23264 move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
23265 dataAppName, appId, seinfo, targetSdkVersion);
23270 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
23272 final Message msg = mHandler.obtainMessage(INIT_COPY);
23273 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
23274 final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
23275 installerPackageName, volumeUuid, null /*verificationInfo*/, user,
23276 packageAbiOverride, null /*grantedPermissions*/,
23277 PackageParser.SigningDetails.UNKNOWN, PackageManager.INSTALL_REASON_UNKNOWN);
23278 params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
23281 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
23282 System.identityHashCode(msg.obj));
23283 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
23284 System.identityHashCode(msg.obj));
23286 mHandler.sendMessage(msg);
23290 public int movePrimaryStorage(String volumeUuid) throws RemoteException {
23291 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
23293 final int realMoveId = mNextMoveId.getAndIncrement();
23294 final Bundle extras = new Bundle();
23295 extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
23296 mMoveCallbacks.notifyCreated(realMoveId, extras);
23298 final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
23300 public void onCreated(int moveId, Bundle extras) {
23305 public void onStatusChanged(int moveId, int status, long estMillis) {
23306 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
23310 final StorageManager storage = mContext.getSystemService(StorageManager.class);
23311 storage.setPrimaryStorageUuid(volumeUuid, callback);
23316 public int getMoveStatus(int moveId) {
23317 mContext.enforceCallingOrSelfPermission(
23318 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
23319 return mMoveCallbacks.mLastStatus.get(moveId);
23323 public void registerMoveCallback(IPackageMoveObserver callback) {
23324 mContext.enforceCallingOrSelfPermission(
23325 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
23326 mMoveCallbacks.register(callback);
23330 public void unregisterMoveCallback(IPackageMoveObserver callback) {
23331 mContext.enforceCallingOrSelfPermission(
23332 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
23333 mMoveCallbacks.unregister(callback);
23337 public boolean setInstallLocation(int loc) {
23338 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
23340 if (getInstallLocation() == loc) {
23343 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
23344 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
23345 android.provider.Settings.Global.putInt(mContext.getContentResolver(),
23346 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
23353 public int getInstallLocation() {
23354 // allow instant app access
23355 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
23356 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
23357 PackageHelper.APP_INSTALL_AUTO);
23360 /** Called by UserManagerService */
23361 void cleanUpUser(UserManagerService userManager, int userHandle) {
23362 synchronized (mPackages) {
23363 mDirtyUsers.remove(userHandle);
23364 mUserNeedsBadging.delete(userHandle);
23365 mSettings.removeUserLPw(userHandle);
23366 mPendingBroadcasts.remove(userHandle);
23367 mInstantAppRegistry.onUserRemovedLPw(userHandle);
23368 removeUnusedPackagesLPw(userManager, userHandle);
23373 * We're removing userHandle and would like to remove any downloaded packages
23374 * that are no longer in use by any other user.
23375 * @param userHandle the user being removed
23377 private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
23378 final boolean DEBUG_CLEAN_APKS = false;
23379 int [] users = userManager.getUserIds();
23380 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
23381 while (psit.hasNext()) {
23382 PackageSetting ps = psit.next();
23383 if (ps.pkg == null) {
23386 final String packageName = ps.pkg.packageName;
23387 // Skip over if system app or static shared library
23388 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0
23389 || !TextUtils.isEmpty(ps.pkg.staticSharedLibName)) {
23392 if (DEBUG_CLEAN_APKS) {
23393 Slog.i(TAG, "Checking package " + packageName);
23395 boolean keep = shouldKeepUninstalledPackageLPr(packageName);
23397 if (DEBUG_CLEAN_APKS) {
23398 Slog.i(TAG, " Keeping package " + packageName + " - requested by DO");
23401 for (int i = 0; i < users.length; i++) {
23402 if (users[i] != userHandle && ps.getInstalled(users[i])) {
23404 if (DEBUG_CLEAN_APKS) {
23405 Slog.i(TAG, " Keeping package " + packageName + " for user "
23413 if (DEBUG_CLEAN_APKS) {
23414 Slog.i(TAG, " Removing package " + packageName);
23416 mHandler.post(new Runnable() {
23417 public void run() {
23418 deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
23426 /** Called by UserManagerService */
23427 void createNewUser(int userId, String[] disallowedPackages) {
23428 synchronized (mInstallLock) {
23429 mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages);
23431 synchronized (mPackages) {
23432 scheduleWritePackageRestrictionsLocked(userId);
23433 scheduleWritePackageListLocked(userId);
23434 applyFactoryDefaultBrowserLPw(userId);
23435 primeDomainVerificationsLPw(userId);
23439 void onNewUserCreated(final int userId) {
23440 mDefaultPermissionPolicy.grantDefaultPermissions(userId);
23441 synchronized(mPackages) {
23442 // If permission review for legacy apps is required, we represent
23443 // dagerous permissions for such apps as always granted runtime
23444 // permissions to keep per user flag state whether review is needed.
23445 // Hence, if a new user is added we have to propagate dangerous
23446 // permission grants for these legacy apps.
23447 if (mSettings.mPermissions.mPermissionReviewRequired) {
23448 // NOTE: This adds UPDATE_PERMISSIONS_REPLACE_PKG
23449 mPermissionManager.updateAllPermissions(
23450 StorageManager.UUID_PRIVATE_INTERNAL, true, mPackages.values(),
23451 mPermissionCallback);
23457 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
23458 mContext.enforceCallingOrSelfPermission(
23459 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
23460 "Only package verification agents can read the verifier device identity");
23462 synchronized (mPackages) {
23463 return mSettings.getVerifierDeviceIdentityLPw();
23468 public void setPermissionEnforced(String permission, boolean enforced) {
23469 // TODO: Now that we no longer change GID for storage, this should to away.
23470 mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
23471 "setPermissionEnforced");
23472 if (READ_EXTERNAL_STORAGE.equals(permission)) {
23473 synchronized (mPackages) {
23474 if (mSettings.mReadExternalStorageEnforced == null
23475 || mSettings.mReadExternalStorageEnforced != enforced) {
23476 mSettings.mReadExternalStorageEnforced =
23477 enforced ? Boolean.TRUE : Boolean.FALSE;
23478 mSettings.writeLPr();
23481 // kill any non-foreground processes so we restart them and
23482 // grant/revoke the GID.
23483 final IActivityManager am = ActivityManager.getService();
23485 final long token = Binder.clearCallingIdentity();
23487 am.killProcessesBelowForeground("setPermissionEnforcement");
23488 } catch (RemoteException e) {
23490 Binder.restoreCallingIdentity(token);
23494 throw new IllegalArgumentException("No selective enforcement for " + permission);
23500 public boolean isPermissionEnforced(String permission) {
23501 // allow instant applications
23506 public boolean isStorageLow() {
23507 // allow instant applications
23508 final long token = Binder.clearCallingIdentity();
23510 final DeviceStorageMonitorInternal
23511 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
23513 return dsm.isMemoryLow();
23518 Binder.restoreCallingIdentity(token);
23523 public IPackageInstaller getPackageInstaller() {
23524 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
23527 return mInstallerService;
23531 public IArtManager getArtManager() {
23532 return mArtManagerService;
23535 private boolean userNeedsBadging(int userId) {
23536 int index = mUserNeedsBadging.indexOfKey(userId);
23538 final UserInfo userInfo;
23539 final long token = Binder.clearCallingIdentity();
23541 userInfo = sUserManager.getUserInfo(userId);
23543 Binder.restoreCallingIdentity(token);
23546 if (userInfo != null && userInfo.isManagedProfile()) {
23551 mUserNeedsBadging.put(userId, b);
23554 return mUserNeedsBadging.valueAt(index);
23558 public KeySet getKeySetByAlias(String packageName, String alias) {
23559 if (packageName == null || alias == null) {
23562 synchronized(mPackages) {
23563 final PackageParser.Package pkg = mPackages.get(packageName);
23565 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23566 throw new IllegalArgumentException("Unknown package: " + packageName);
23568 final PackageSetting ps = (PackageSetting) pkg.mExtras;
23569 if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
23570 Slog.w(TAG, "KeySet requested for filtered package: " + packageName);
23571 throw new IllegalArgumentException("Unknown package: " + packageName);
23573 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
23574 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
23579 public KeySet getSigningKeySet(String packageName) {
23580 if (packageName == null) {
23583 synchronized(mPackages) {
23584 final int callingUid = Binder.getCallingUid();
23585 final int callingUserId = UserHandle.getUserId(callingUid);
23586 final PackageParser.Package pkg = mPackages.get(packageName);
23588 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23589 throw new IllegalArgumentException("Unknown package: " + packageName);
23591 final PackageSetting ps = (PackageSetting) pkg.mExtras;
23592 if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
23593 // filter and pretend the package doesn't exist
23594 Slog.w(TAG, "KeySet requested for filtered package: " + packageName
23595 + ", uid:" + callingUid);
23596 throw new IllegalArgumentException("Unknown package: " + packageName);
23598 if (pkg.applicationInfo.uid != callingUid
23599 && Process.SYSTEM_UID != callingUid) {
23600 throw new SecurityException("May not access signing KeySet of other apps.");
23602 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
23603 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
23608 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
23609 final int callingUid = Binder.getCallingUid();
23610 if (getInstantAppPackageName(callingUid) != null) {
23613 if (packageName == null || ks == null) {
23616 synchronized(mPackages) {
23617 final PackageParser.Package pkg = mPackages.get(packageName);
23619 || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
23620 UserHandle.getUserId(callingUid))) {
23621 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23622 throw new IllegalArgumentException("Unknown package: " + packageName);
23624 IBinder ksh = ks.getToken();
23625 if (ksh instanceof KeySetHandle) {
23626 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
23627 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
23634 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
23635 final int callingUid = Binder.getCallingUid();
23636 if (getInstantAppPackageName(callingUid) != null) {
23639 if (packageName == null || ks == null) {
23642 synchronized(mPackages) {
23643 final PackageParser.Package pkg = mPackages.get(packageName);
23645 || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
23646 UserHandle.getUserId(callingUid))) {
23647 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23648 throw new IllegalArgumentException("Unknown package: " + packageName);
23650 IBinder ksh = ks.getToken();
23651 if (ksh instanceof KeySetHandle) {
23652 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
23653 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
23659 private void deletePackageIfUnusedLPr(final String packageName) {
23660 PackageSetting ps = mSettings.mPackages.get(packageName);
23664 if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
23665 // TODO Implement atomic delete if package is unused
23666 // It is currently possible that the package will be deleted even if it is installed
23667 // after this method returns.
23668 mHandler.post(new Runnable() {
23669 public void run() {
23670 deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
23671 0, PackageManager.DELETE_ALL_USERS);
23678 * Check and throw if the given before/after packages would be considered a
23681 private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
23682 throws PackageManagerException {
23683 if (after.getLongVersionCode() < before.getLongVersionCode()) {
23684 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23685 "Update version code " + after.versionCode + " is older than current "
23686 + before.getLongVersionCode());
23687 } else if (after.getLongVersionCode() == before.getLongVersionCode()) {
23688 if (after.baseRevisionCode < before.baseRevisionCode) {
23689 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23690 "Update base revision code " + after.baseRevisionCode
23691 + " is older than current " + before.baseRevisionCode);
23694 if (!ArrayUtils.isEmpty(after.splitNames)) {
23695 for (int i = 0; i < after.splitNames.length; i++) {
23696 final String splitName = after.splitNames[i];
23697 final int j = ArrayUtils.indexOf(before.splitNames, splitName);
23699 if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
23700 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23701 "Update split " + splitName + " revision code "
23702 + after.splitRevisionCodes[i] + " is older than current "
23703 + before.splitRevisionCodes[j]);
23711 private static class MoveCallbacks extends Handler {
23712 private static final int MSG_CREATED = 1;
23713 private static final int MSG_STATUS_CHANGED = 2;
23715 private final RemoteCallbackList<IPackageMoveObserver>
23716 mCallbacks = new RemoteCallbackList<>();
23718 private final SparseIntArray mLastStatus = new SparseIntArray();
23720 public MoveCallbacks(Looper looper) {
23724 public void register(IPackageMoveObserver callback) {
23725 mCallbacks.register(callback);
23728 public void unregister(IPackageMoveObserver callback) {
23729 mCallbacks.unregister(callback);
23733 public void handleMessage(Message msg) {
23734 final SomeArgs args = (SomeArgs) msg.obj;
23735 final int n = mCallbacks.beginBroadcast();
23736 for (int i = 0; i < n; i++) {
23737 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
23739 invokeCallback(callback, msg.what, args);
23740 } catch (RemoteException ignored) {
23743 mCallbacks.finishBroadcast();
23747 private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
23748 throws RemoteException {
23750 case MSG_CREATED: {
23751 callback.onCreated(args.argi1, (Bundle) args.arg2);
23754 case MSG_STATUS_CHANGED: {
23755 callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
23761 private void notifyCreated(int moveId, Bundle extras) {
23762 Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
23764 final SomeArgs args = SomeArgs.obtain();
23765 args.argi1 = moveId;
23766 args.arg2 = extras;
23767 obtainMessage(MSG_CREATED, args).sendToTarget();
23770 private void notifyStatusChanged(int moveId, int status) {
23771 notifyStatusChanged(moveId, status, -1);
23774 private void notifyStatusChanged(int moveId, int status, long estMillis) {
23775 Slog.v(TAG, "Move " + moveId + " status " + status);
23777 final SomeArgs args = SomeArgs.obtain();
23778 args.argi1 = moveId;
23779 args.argi2 = status;
23780 args.arg3 = estMillis;
23781 obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
23783 synchronized (mLastStatus) {
23784 mLastStatus.put(moveId, status);
23789 private final static class OnPermissionChangeListeners extends Handler {
23790 private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
23792 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
23793 new RemoteCallbackList<>();
23795 public OnPermissionChangeListeners(Looper looper) {
23800 public void handleMessage(Message msg) {
23801 switch (msg.what) {
23802 case MSG_ON_PERMISSIONS_CHANGED: {
23803 final int uid = msg.arg1;
23804 handleOnPermissionsChanged(uid);
23809 public void addListenerLocked(IOnPermissionsChangeListener listener) {
23810 mPermissionListeners.register(listener);
23814 public void removeListenerLocked(IOnPermissionsChangeListener listener) {
23815 mPermissionListeners.unregister(listener);
23818 public void onPermissionsChanged(int uid) {
23819 if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
23820 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
23824 private void handleOnPermissionsChanged(int uid) {
23825 final int count = mPermissionListeners.beginBroadcast();
23827 for (int i = 0; i < count; i++) {
23828 IOnPermissionsChangeListener callback = mPermissionListeners
23829 .getBroadcastItem(i);
23831 callback.onPermissionsChanged(uid);
23832 } catch (RemoteException e) {
23833 Log.e(TAG, "Permission listener is dead", e);
23837 mPermissionListeners.finishBroadcast();
23842 private class PackageManagerNative extends IPackageManagerNative.Stub {
23844 public String[] getNamesForUids(int[] uids) throws RemoteException {
23845 final String[] results = PackageManagerService.this.getNamesForUids(uids);
23846 // massage results so they can be parsed by the native binder
23847 for (int i = results.length - 1; i >= 0; --i) {
23848 if (results[i] == null) {
23855 // NB: this differentiates between preloads and sideloads
23857 public String getInstallerForPackage(String packageName) throws RemoteException {
23858 final String installerName = getInstallerPackageName(packageName);
23859 if (!TextUtils.isEmpty(installerName)) {
23860 return installerName;
23862 // differentiate between preload and sideload
23863 int callingUser = UserHandle.getUserId(Binder.getCallingUid());
23864 ApplicationInfo appInfo = getApplicationInfo(packageName,
23866 /*userId*/ callingUser);
23867 if (appInfo != null && (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
23874 public long getVersionCodeForPackage(String packageName) throws RemoteException {
23876 int callingUser = UserHandle.getUserId(Binder.getCallingUid());
23877 PackageInfo pInfo = getPackageInfo(packageName, 0, callingUser);
23878 if (pInfo != null) {
23879 return pInfo.getLongVersionCode();
23881 } catch (Exception e) {
23887 private class PackageManagerInternalImpl extends PackageManagerInternal {
23889 public void updatePermissionFlagsTEMP(String permName, String packageName, int flagMask,
23890 int flagValues, int userId) {
23891 PackageManagerService.this.updatePermissionFlags(
23892 permName, packageName, flagMask, flagValues, userId);
23896 public boolean isDataRestoreSafe(byte[] restoringFromSigHash, String packageName) {
23897 SigningDetails sd = getSigningDetails(packageName);
23901 return sd.hasSha256Certificate(restoringFromSigHash,
23902 SigningDetails.CertCapabilities.INSTALLED_DATA);
23906 public boolean isDataRestoreSafe(Signature restoringFromSig, String packageName) {
23907 SigningDetails sd = getSigningDetails(packageName);
23911 return sd.hasCertificate(restoringFromSig,
23912 SigningDetails.CertCapabilities.INSTALLED_DATA);
23916 public boolean hasSignatureCapability(int serverUid, int clientUid,
23917 @SigningDetails.CertCapabilities int capability) {
23918 SigningDetails serverSigningDetails = getSigningDetails(serverUid);
23919 SigningDetails clientSigningDetails = getSigningDetails(clientUid);
23920 return serverSigningDetails.checkCapability(clientSigningDetails, capability)
23921 || clientSigningDetails.hasAncestorOrSelf(serverSigningDetails);
23925 private SigningDetails getSigningDetails(@NonNull String packageName) {
23926 synchronized (mPackages) {
23927 PackageParser.Package p = mPackages.get(packageName);
23931 return p.mSigningDetails;
23935 private SigningDetails getSigningDetails(int uid) {
23936 synchronized (mPackages) {
23937 final int appId = UserHandle.getAppId(uid);
23938 final Object obj = mSettings.getUserIdLPr(appId);
23940 if (obj instanceof SharedUserSetting) {
23941 return ((SharedUserSetting) obj).signatures.mSigningDetails;
23942 } else if (obj instanceof PackageSetting) {
23943 final PackageSetting ps = (PackageSetting) obj;
23944 return ps.signatures.mSigningDetails;
23947 return SigningDetails.UNKNOWN;
23952 public int getPermissionFlagsTEMP(String permName, String packageName, int userId) {
23953 return PackageManagerService.this.getPermissionFlags(permName, packageName, userId);
23957 public boolean isInstantApp(String packageName, int userId) {
23958 return PackageManagerService.this.isInstantApp(packageName, userId);
23962 public String getInstantAppPackageName(int uid) {
23963 return PackageManagerService.this.getInstantAppPackageName(uid);
23967 public boolean filterAppAccess(PackageParser.Package pkg, int callingUid, int userId) {
23968 synchronized (mPackages) {
23969 return PackageManagerService.this.filterAppAccessLPr(
23970 (PackageSetting) pkg.mExtras, callingUid, userId);
23975 public PackageParser.Package getPackage(String packageName) {
23976 synchronized (mPackages) {
23977 packageName = resolveInternalPackageNameLPr(
23978 packageName, PackageManager.VERSION_CODE_HIGHEST);
23979 return mPackages.get(packageName);
23984 public PackageList getPackageList(PackageListObserver observer) {
23985 synchronized (mPackages) {
23986 final int N = mPackages.size();
23987 final ArrayList<String> list = new ArrayList<>(N);
23988 for (int i = 0; i < N; i++) {
23989 list.add(mPackages.keyAt(i));
23991 final PackageList packageList = new PackageList(list, observer);
23992 if (observer != null) {
23993 mPackageListObservers.add(packageList);
23995 return packageList;
24000 public void removePackageListObserver(PackageListObserver observer) {
24001 synchronized (mPackages) {
24002 mPackageListObservers.remove(observer);
24007 public PackageParser.Package getDisabledPackage(String packageName) {
24008 synchronized (mPackages) {
24009 final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
24010 return (ps != null) ? ps.pkg : null;
24015 public String getKnownPackageName(int knownPackage, int userId) {
24016 switch(knownPackage) {
24017 case PackageManagerInternal.PACKAGE_BROWSER:
24018 return getDefaultBrowserPackageName(userId);
24019 case PackageManagerInternal.PACKAGE_INSTALLER:
24020 return mRequiredInstallerPackage;
24021 case PackageManagerInternal.PACKAGE_SETUP_WIZARD:
24022 return mSetupWizardPackage;
24023 case PackageManagerInternal.PACKAGE_SYSTEM:
24025 case PackageManagerInternal.PACKAGE_VERIFIER:
24026 return mRequiredVerifierPackage;
24027 case PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER:
24028 return mSystemTextClassifierPackage;
24034 public boolean isResolveActivityComponent(ComponentInfo component) {
24035 return mResolveActivity.packageName.equals(component.packageName)
24036 && mResolveActivity.name.equals(component.name);
24040 public void setLocationPackagesProvider(PackagesProvider provider) {
24041 mDefaultPermissionPolicy.setLocationPackagesProvider(provider);
24045 public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
24046 mDefaultPermissionPolicy.setVoiceInteractionPackagesProvider(provider);
24050 public void setSmsAppPackagesProvider(PackagesProvider provider) {
24051 mDefaultPermissionPolicy.setSmsAppPackagesProvider(provider);
24055 public void setDialerAppPackagesProvider(PackagesProvider provider) {
24056 mDefaultPermissionPolicy.setDialerAppPackagesProvider(provider);
24060 public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
24061 mDefaultPermissionPolicy.setSimCallManagerPackagesProvider(provider);
24065 public void setUseOpenWifiAppPackagesProvider(PackagesProvider provider) {
24066 mDefaultPermissionPolicy.setUseOpenWifiAppPackagesProvider(provider);
24070 public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
24071 mDefaultPermissionPolicy.setSyncAdapterPackagesProvider(provider);
24075 public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
24076 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsApp(packageName, userId);
24080 public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
24081 synchronized (mPackages) {
24082 mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
24084 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerApp(packageName, userId);
24088 public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
24089 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManager(
24090 packageName, userId);
24094 public void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName, int userId) {
24095 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultUseOpenWifiApp(
24096 packageName, userId);
24100 public void setKeepUninstalledPackages(final List<String> packageList) {
24101 Preconditions.checkNotNull(packageList);
24102 List<String> removedFromList = null;
24103 synchronized (mPackages) {
24104 if (mKeepUninstalledPackages != null) {
24105 final int packagesCount = mKeepUninstalledPackages.size();
24106 for (int i = 0; i < packagesCount; i++) {
24107 String oldPackage = mKeepUninstalledPackages.get(i);
24108 if (packageList != null && packageList.contains(oldPackage)) {
24111 if (removedFromList == null) {
24112 removedFromList = new ArrayList<>();
24114 removedFromList.add(oldPackage);
24117 mKeepUninstalledPackages = new ArrayList<>(packageList);
24118 if (removedFromList != null) {
24119 final int removedCount = removedFromList.size();
24120 for (int i = 0; i < removedCount; i++) {
24121 deletePackageIfUnusedLPr(removedFromList.get(i));
24128 public boolean isPermissionsReviewRequired(String packageName, int userId) {
24129 synchronized (mPackages) {
24130 return mPermissionManager.isPermissionsReviewRequired(
24131 mPackages.get(packageName), userId);
24136 public PackageInfo getPackageInfo(
24137 String packageName, int flags, int filterCallingUid, int userId) {
24138 return PackageManagerService.this
24139 .getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
24140 flags, filterCallingUid, userId);
24144 public Bundle getSuspendedPackageLauncherExtras(String packageName, int userId) {
24145 synchronized (mPackages) {
24146 final PackageSetting ps = mSettings.mPackages.get(packageName);
24147 PersistableBundle launcherExtras = null;
24149 launcherExtras = ps.readUserState(userId).suspendedLauncherExtras;
24151 return (launcherExtras != null) ? new Bundle(launcherExtras.deepCopy()) : null;
24156 public boolean isPackageSuspended(String packageName, int userId) {
24157 synchronized (mPackages) {
24158 final PackageSetting ps = mSettings.mPackages.get(packageName);
24159 return (ps != null) ? ps.getSuspended(userId) : false;
24164 public String getSuspendingPackage(String suspendedPackage, int userId) {
24165 synchronized (mPackages) {
24166 final PackageSetting ps = mSettings.mPackages.get(suspendedPackage);
24167 return (ps != null) ? ps.readUserState(userId).suspendingPackage : null;
24172 public String getSuspendedDialogMessage(String suspendedPackage, int userId) {
24173 synchronized (mPackages) {
24174 final PackageSetting ps = mSettings.mPackages.get(suspendedPackage);
24175 return (ps != null) ? ps.readUserState(userId).dialogMessage : null;
24180 public int getPackageUid(String packageName, int flags, int userId) {
24181 return PackageManagerService.this
24182 .getPackageUid(packageName, flags, userId);
24186 public ApplicationInfo getApplicationInfo(
24187 String packageName, int flags, int filterCallingUid, int userId) {
24188 return PackageManagerService.this
24189 .getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
24193 public ActivityInfo getActivityInfo(
24194 ComponentName component, int flags, int filterCallingUid, int userId) {
24195 return PackageManagerService.this
24196 .getActivityInfoInternal(component, flags, filterCallingUid, userId);
24200 public List<ResolveInfo> queryIntentActivities(
24201 Intent intent, int flags, int filterCallingUid, int userId) {
24202 final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
24203 return PackageManagerService.this
24204 .queryIntentActivitiesInternal(intent, resolvedType, flags, filterCallingUid,
24205 userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
24209 public List<ResolveInfo> queryIntentServices(
24210 Intent intent, int flags, int callingUid, int userId) {
24211 final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
24212 return PackageManagerService.this
24213 .queryIntentServicesInternal(intent, resolvedType, flags, userId, callingUid,
24218 public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
24220 return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
24224 public ComponentName getDefaultHomeActivity(int userId) {
24225 return PackageManagerService.this.getDefaultHomeActivity(userId);
24229 public void setDeviceAndProfileOwnerPackages(
24230 int deviceOwnerUserId, String deviceOwnerPackage,
24231 SparseArray<String> profileOwnerPackages) {
24232 mProtectedPackages.setDeviceAndProfileOwnerPackages(
24233 deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
24235 final ArraySet<Integer> usersWithPoOrDo = new ArraySet<>();
24236 if (deviceOwnerPackage != null) {
24237 usersWithPoOrDo.add(deviceOwnerUserId);
24239 final int sz = profileOwnerPackages.size();
24240 for (int i = 0; i < sz; i++) {
24241 if (profileOwnerPackages.valueAt(i) != null) {
24242 usersWithPoOrDo.add(profileOwnerPackages.keyAt(i));
24245 unsuspendForNonSystemSuspendingPackages(usersWithPoOrDo);
24249 public boolean isPackageDataProtected(int userId, String packageName) {
24250 return mProtectedPackages.isPackageDataProtected(userId, packageName);
24254 public boolean isPackageStateProtected(String packageName, int userId) {
24255 return mProtectedPackages.isPackageStateProtected(userId, packageName);
24259 public boolean isPackageEphemeral(int userId, String packageName) {
24260 synchronized (mPackages) {
24261 final PackageSetting ps = mSettings.mPackages.get(packageName);
24262 return ps != null ? ps.getInstantApp(userId) : false;
24267 public boolean wasPackageEverLaunched(String packageName, int userId) {
24268 synchronized (mPackages) {
24269 return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
24274 public void grantRuntimePermission(String packageName, String permName, int userId,
24275 boolean overridePolicy) {
24276 PackageManagerService.this.mPermissionManager.grantRuntimePermission(
24277 permName, packageName, overridePolicy, getCallingUid(), userId,
24278 mPermissionCallback);
24282 public void revokeRuntimePermission(String packageName, String permName, int userId,
24283 boolean overridePolicy) {
24284 mPermissionManager.revokeRuntimePermission(
24285 permName, packageName, overridePolicy, getCallingUid(), userId,
24286 mPermissionCallback);
24290 public String getNameForUid(int uid) {
24291 return PackageManagerService.this.getNameForUid(uid);
24295 public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
24296 Intent origIntent, String resolvedType, String callingPackage,
24297 Bundle verificationBundle, int userId) {
24298 PackageManagerService.this.requestInstantAppResolutionPhaseTwo(
24299 responseObj, origIntent, resolvedType, callingPackage, verificationBundle,
24304 public void grantEphemeralAccess(int userId, Intent intent,
24305 int targetAppId, int ephemeralAppId) {
24306 synchronized (mPackages) {
24307 mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
24308 targetAppId, ephemeralAppId);
24313 public boolean isInstantAppInstallerComponent(ComponentName component) {
24314 synchronized (mPackages) {
24315 return mInstantAppInstallerActivity != null
24316 && mInstantAppInstallerActivity.getComponentName().equals(component);
24321 public void pruneInstantApps() {
24322 mInstantAppRegistry.pruneInstantApps();
24326 public String getSetupWizardPackageName() {
24327 return mSetupWizardPackage;
24330 public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
24331 if (policy != null) {
24332 mExternalSourcesPolicy = policy;
24337 public boolean isPackagePersistent(String packageName) {
24338 synchronized (mPackages) {
24339 PackageParser.Package pkg = mPackages.get(packageName);
24341 ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM
24342 | ApplicationInfo.FLAG_PERSISTENT)) ==
24343 (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT))
24349 public boolean isLegacySystemApp(Package pkg) {
24350 synchronized (mPackages) {
24351 final PackageSetting ps = (PackageSetting) pkg.mExtras;
24352 return mPromoteSystemApps
24354 && mExistingSystemPackages.contains(ps.name);
24359 public List<PackageInfo> getOverlayPackages(int userId) {
24360 final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
24361 synchronized (mPackages) {
24362 for (PackageParser.Package p : mPackages.values()) {
24363 if (p.mOverlayTarget != null) {
24364 PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
24366 overlayPackages.add(pkg);
24371 return overlayPackages;
24375 public List<String> getTargetPackageNames(int userId) {
24376 List<String> targetPackages = new ArrayList<>();
24377 synchronized (mPackages) {
24378 for (PackageParser.Package p : mPackages.values()) {
24379 if (p.mOverlayTarget == null) {
24380 targetPackages.add(p.packageName);
24384 return targetPackages;
24388 public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
24389 @Nullable List<String> overlayPackageNames) {
24390 synchronized (mPackages) {
24391 if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
24392 Slog.e(TAG, "failed to find package " + targetPackageName);
24395 ArrayList<String> overlayPaths = null;
24396 if (overlayPackageNames != null && overlayPackageNames.size() > 0) {
24397 final int N = overlayPackageNames.size();
24398 overlayPaths = new ArrayList<>(N);
24399 for (int i = 0; i < N; i++) {
24400 final String packageName = overlayPackageNames.get(i);
24401 final PackageParser.Package pkg = mPackages.get(packageName);
24403 Slog.e(TAG, "failed to find package " + packageName);
24406 overlayPaths.add(pkg.baseCodePath);
24410 final PackageSetting ps = mSettings.mPackages.get(targetPackageName);
24411 ps.setOverlayPaths(overlayPaths, userId);
24417 public ResolveInfo resolveIntent(Intent intent, String resolvedType,
24418 int flags, int userId, boolean resolveForStart, int filterCallingUid) {
24419 return resolveIntentInternal(
24420 intent, resolvedType, flags, userId, resolveForStart, filterCallingUid);
24424 public ResolveInfo resolveService(Intent intent, String resolvedType,
24425 int flags, int userId, int callingUid) {
24426 return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
24430 public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
24431 return PackageManagerService.this.resolveContentProviderInternal(
24432 name, flags, userId);
24436 public void addIsolatedUid(int isolatedUid, int ownerUid) {
24437 synchronized (mPackages) {
24438 mIsolatedOwners.put(isolatedUid, ownerUid);
24443 public void removeIsolatedUid(int isolatedUid) {
24444 synchronized (mPackages) {
24445 mIsolatedOwners.delete(isolatedUid);
24450 public int getUidTargetSdkVersion(int uid) {
24451 synchronized (mPackages) {
24452 return getUidTargetSdkVersionLockedLPr(uid);
24457 public int getPackageTargetSdkVersion(String packageName) {
24458 synchronized (mPackages) {
24459 return getPackageTargetSdkVersionLockedLPr(packageName);
24464 public boolean canAccessInstantApps(int callingUid, int userId) {
24465 return PackageManagerService.this.canViewInstantApps(callingUid, userId);
24469 public boolean canAccessComponent(int callingUid, ComponentName component, int userId) {
24470 synchronized (mPackages) {
24471 final PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
24472 return !PackageManagerService.this.filterAppAccessLPr(
24473 ps, callingUid, component, TYPE_UNKNOWN, userId);
24478 public boolean hasInstantApplicationMetadata(String packageName, int userId) {
24479 synchronized (mPackages) {
24480 return mInstantAppRegistry.hasInstantApplicationMetadataLPr(packageName, userId);
24485 public void notifyPackageUse(String packageName, int reason) {
24486 synchronized (mPackages) {
24487 PackageManagerService.this.notifyPackageUseLocked(packageName, reason);
24493 public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
24494 enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
24495 synchronized (mPackages) {
24496 final long identity = Binder.clearCallingIdentity();
24498 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierApps(
24499 packageNames, userId);
24501 Binder.restoreCallingIdentity(identity);
24507 public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
24508 enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
24509 synchronized (mPackages) {
24510 final long identity = Binder.clearCallingIdentity();
24512 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServices(
24513 packageNames, userId);
24515 Binder.restoreCallingIdentity(identity);
24521 public void grantDefaultPermissionsToEnabledTelephonyDataServices(
24522 String[] packageNames, int userId) {
24523 enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledTelephonyDataServices");
24524 synchronized (mPackages) {
24525 Binder.withCleanCallingIdentity( () -> {
24526 mDefaultPermissionPolicy.
24527 grantDefaultPermissionsToEnabledTelephonyDataServices(
24528 packageNames, userId);
24534 public void revokeDefaultPermissionsFromDisabledTelephonyDataServices(
24535 String[] packageNames, int userId) {
24536 enforceSystemOrPhoneCaller("revokeDefaultPermissionsFromDisabledTelephonyDataServices");
24537 synchronized (mPackages) {
24538 Binder.withCleanCallingIdentity( () -> {
24539 mDefaultPermissionPolicy.
24540 revokeDefaultPermissionsFromDisabledTelephonyDataServices(
24541 packageNames, userId);
24547 public void grantDefaultPermissionsToActiveLuiApp(String packageName, int userId) {
24548 enforceSystemOrPhoneCaller("grantDefaultPermissionsToActiveLuiApp");
24549 synchronized (mPackages) {
24550 final long identity = Binder.clearCallingIdentity();
24552 mDefaultPermissionPolicy.grantDefaultPermissionsToActiveLuiApp(
24553 packageName, userId);
24555 Binder.restoreCallingIdentity(identity);
24561 public void revokeDefaultPermissionsFromLuiApps(String[] packageNames, int userId) {
24562 enforceSystemOrPhoneCaller("revokeDefaultPermissionsFromLuiApps");
24563 synchronized (mPackages) {
24564 final long identity = Binder.clearCallingIdentity();
24566 mDefaultPermissionPolicy.revokeDefaultPermissionsFromLuiApps(packageNames, userId);
24568 Binder.restoreCallingIdentity(identity);
24573 private static void enforceSystemOrPhoneCaller(String tag) {
24574 int callingUid = Binder.getCallingUid();
24575 if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
24576 throw new SecurityException(
24577 "Cannot call " + tag + " from UID " + callingUid);
24581 boolean isHistoricalPackageUsageAvailable() {
24582 return mPackageUsage.isHistoricalPackageUsageAvailable();
24586 * Return a <b>copy</b> of the collection of packages known to the package manager.
24587 * @return A copy of the values of mPackages.
24589 Collection<PackageParser.Package> getPackages() {
24590 synchronized (mPackages) {
24591 return new ArrayList<>(mPackages.values());
24596 * Logs process start information (including base APK hash) to the security log.
24600 public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
24601 String apkFile, int pid) {
24602 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24605 if (!SecurityLog.isLoggingEnabled()) {
24608 Bundle data = new Bundle();
24609 data.putLong("startTimestamp", System.currentTimeMillis());
24610 data.putString("processName", processName);
24611 data.putInt("uid", uid);
24612 data.putString("seinfo", seinfo);
24613 data.putString("apkFile", apkFile);
24614 data.putInt("pid", pid);
24615 Message msg = mProcessLoggingHandler.obtainMessage(
24616 ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
24618 mProcessLoggingHandler.sendMessage(msg);
24621 public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
24622 return mCompilerStats.getPackageStats(pkgName);
24625 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
24626 return getOrCreateCompilerPackageStats(pkg.packageName);
24629 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
24630 return mCompilerStats.getOrCreatePackageStats(pkgName);
24633 public void deleteCompilerPackageStats(String pkgName) {
24634 mCompilerStats.deletePackageStats(pkgName);
24638 public int getInstallReason(String packageName, int userId) {
24639 final int callingUid = Binder.getCallingUid();
24640 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
24641 true /* requireFullPermission */, false /* checkShell */,
24642 "get install reason");
24643 synchronized (mPackages) {
24644 final PackageSetting ps = mSettings.mPackages.get(packageName);
24645 if (filterAppAccessLPr(ps, callingUid, userId)) {
24646 return PackageManager.INSTALL_REASON_UNKNOWN;
24649 return ps.getInstallReason(userId);
24652 return PackageManager.INSTALL_REASON_UNKNOWN;
24656 public boolean canRequestPackageInstalls(String packageName, int userId) {
24657 return canRequestPackageInstallsInternal(packageName, 0, userId,
24658 true /* throwIfPermNotDeclared*/);
24661 private boolean canRequestPackageInstallsInternal(String packageName, int flags, int userId,
24662 boolean throwIfPermNotDeclared) {
24663 int callingUid = Binder.getCallingUid();
24664 int uid = getPackageUid(packageName, 0, userId);
24665 if (callingUid != uid && callingUid != Process.ROOT_UID
24666 && callingUid != Process.SYSTEM_UID) {
24667 throw new SecurityException(
24668 "Caller uid " + callingUid + " does not own package " + packageName);
24670 ApplicationInfo info = getApplicationInfo(packageName, flags, userId);
24671 if (info == null) {
24674 if (info.targetSdkVersion < Build.VERSION_CODES.O) {
24677 if (isInstantApp(packageName, userId)) {
24680 String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
24681 String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission);
24682 if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
24683 if (throwIfPermNotDeclared) {
24684 throw new SecurityException("Need to declare " + appOpPermission
24685 + " to call this api");
24687 Slog.e(TAG, "Need to declare " + appOpPermission + " to call this api");
24691 if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) {
24694 if (mExternalSourcesPolicy != null) {
24695 int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
24696 return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
24702 public ComponentName getInstantAppResolverSettingsComponent() {
24703 return mInstantAppResolverSettingsComponent;
24707 public ComponentName getInstantAppInstallerComponent() {
24708 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24711 return mInstantAppInstallerActivity == null
24712 ? null : mInstantAppInstallerActivity.getComponentName();
24716 public String getInstantAppAndroidId(String packageName, int userId) {
24717 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
24718 "getInstantAppAndroidId");
24719 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
24720 true /* requireFullPermission */, false /* checkShell */,
24721 "getInstantAppAndroidId");
24722 // Make sure the target is an Instant App.
24723 if (!isInstantApp(packageName, userId)) {
24726 synchronized (mPackages) {
24727 return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
24731 boolean canHaveOatDir(String packageName) {
24732 synchronized (mPackages) {
24733 PackageParser.Package p = mPackages.get(packageName);
24737 return p.canHaveOatDir();
24741 private String getOatDir(PackageParser.Package pkg) {
24742 if (!pkg.canHaveOatDir()) {
24745 File codePath = new File(pkg.codePath);
24746 if (codePath.isDirectory()) {
24747 return PackageDexOptimizer.getOatDir(codePath).getAbsolutePath();
24752 void deleteOatArtifactsOfPackage(String packageName) {
24753 final String[] instructionSets;
24754 final List<String> codePaths;
24755 final String oatDir;
24756 final PackageParser.Package pkg;
24757 synchronized (mPackages) {
24758 pkg = mPackages.get(packageName);
24760 instructionSets = getAppDexInstructionSets(pkg.applicationInfo);
24761 codePaths = pkg.getAllCodePaths();
24762 oatDir = getOatDir(pkg);
24764 for (String codePath : codePaths) {
24765 for (String isa : instructionSets) {
24767 mInstaller.deleteOdex(codePath, isa, oatDir);
24768 } catch (InstallerException e) {
24769 Log.e(TAG, "Failed deleting oat files for " + codePath, e);
24775 Set<String> getUnusedPackages(long downgradeTimeThresholdMillis) {
24776 Set<String> unusedPackages = new HashSet<>();
24777 long currentTimeInMillis = System.currentTimeMillis();
24778 synchronized (mPackages) {
24779 for (PackageParser.Package pkg : mPackages.values()) {
24780 PackageSetting ps = mSettings.mPackages.get(pkg.packageName);
24784 PackageDexUsage.PackageUseInfo packageUseInfo =
24785 getDexManager().getPackageUseInfoOrDefault(pkg.packageName);
24786 if (PackageManagerServiceUtils
24787 .isUnusedSinceTimeInMillis(ps.firstInstallTime, currentTimeInMillis,
24788 downgradeTimeThresholdMillis, packageUseInfo,
24789 pkg.getLatestPackageUseTimeInMills(),
24790 pkg.getLatestForegroundPackageUseTimeInMills())) {
24791 unusedPackages.add(pkg.packageName);
24795 return unusedPackages;
24799 public void setHarmfulAppWarning(@NonNull String packageName, @Nullable CharSequence warning,
24801 final int callingUid = Binder.getCallingUid();
24802 final int callingAppId = UserHandle.getAppId(callingUid);
24804 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
24805 true /*requireFullPermission*/, true /*checkShell*/, "setHarmfulAppInfo");
24807 if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
24808 checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
24809 throw new SecurityException("Caller must have the "
24810 + SET_HARMFUL_APP_WARNINGS + " permission.");
24813 synchronized(mPackages) {
24814 mSettings.setHarmfulAppWarningLPw(packageName, warning, userId);
24815 scheduleWritePackageRestrictionsLocked(userId);
24821 public CharSequence getHarmfulAppWarning(@NonNull String packageName, int userId) {
24822 final int callingUid = Binder.getCallingUid();
24823 final int callingAppId = UserHandle.getAppId(callingUid);
24825 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
24826 true /*requireFullPermission*/, true /*checkShell*/, "getHarmfulAppInfo");
24828 if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
24829 checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
24830 throw new SecurityException("Caller must have the "
24831 + SET_HARMFUL_APP_WARNINGS + " permission.");
24834 synchronized(mPackages) {
24835 return mSettings.getHarmfulAppWarningLPr(packageName, userId);
24840 public boolean isPackageStateProtected(@NonNull String packageName, @UserIdInt int userId) {
24841 final int callingUid = Binder.getCallingUid();
24842 final int callingAppId = UserHandle.getAppId(callingUid);
24844 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
24845 false /*requireFullPermission*/, true /*checkShell*/, "isPackageStateProtected");
24847 if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID
24848 && checkUidPermission(MANAGE_DEVICE_ADMINS, callingUid) != PERMISSION_GRANTED) {
24849 throw new SecurityException("Caller must have the "
24850 + MANAGE_DEVICE_ADMINS + " permission.");
24853 return mProtectedPackages.isPackageStateProtected(userId, packageName);
24857 interface PackageSender {
24859 * @param userIds User IDs where the action occurred on a full application
24860 * @param instantUserIds User IDs where the action occurred on an instant application
24862 void sendPackageBroadcast(final String action, final String pkg,
24863 final Bundle extras, final int flags, final String targetPkg,
24864 final IIntentReceiver finishedReceiver, final int[] userIds, int[] instantUserIds);
24865 void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
24866 boolean includeStopped, int appId, int[] userIds, int[] instantUserIds);
24867 void notifyPackageAdded(String packageName);
24868 void notifyPackageRemoved(String packageName);