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_PROFILE_AND_DEVICE_OWNERS;
22 import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
23 import static android.Manifest.permission.REQUEST_DELETE_PACKAGES;
24 import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
25 import static android.Manifest.permission.WRITE_MEDIA_STORAGE;
26 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
27 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
28 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
29 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
30 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
31 import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
32 import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
33 import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
34 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
35 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
36 import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
37 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
38 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
39 import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
40 import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
41 import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
42 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
43 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
44 import static android.content.pm.PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID;
45 import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
46 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
47 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
48 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
49 import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
50 import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
51 import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
52 import static android.content.pm.PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE;
53 import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
54 import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
55 import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
56 import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
57 import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
58 import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK;
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.PARSE_IS_PRIVILEGED;
86 import static android.content.pm.PackageParser.isApkFile;
87 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
88 import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
89 import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
90 import static android.system.OsConstants.O_CREAT;
91 import static android.system.OsConstants.O_RDWR;
93 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
94 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
95 import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
96 import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
97 import static com.android.internal.util.ArrayUtils.appendInt;
98 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
99 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
100 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
101 import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
102 import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
103 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
104 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
105 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
106 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
107 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
109 import static dalvik.system.DexFile.getNonProfileGuidedCompilerFilter;
111 import android.Manifest;
112 import android.annotation.IntDef;
113 import android.annotation.NonNull;
114 import android.annotation.Nullable;
115 import android.app.ActivityManager;
116 import android.app.AppOpsManager;
117 import android.app.IActivityManager;
118 import android.app.ResourcesManager;
119 import android.app.admin.IDevicePolicyManager;
120 import android.app.admin.SecurityLog;
121 import android.app.backup.IBackupManager;
122 import android.content.BroadcastReceiver;
123 import android.content.ComponentName;
124 import android.content.ContentResolver;
125 import android.content.Context;
126 import android.content.IIntentReceiver;
127 import android.content.Intent;
128 import android.content.IntentFilter;
129 import android.content.IntentSender;
130 import android.content.IntentSender.SendIntentException;
131 import android.content.ServiceConnection;
132 import android.content.pm.ActivityInfo;
133 import android.content.pm.ApplicationInfo;
134 import android.content.pm.AppsQueryHelper;
135 import android.content.pm.AuxiliaryResolveInfo;
136 import android.content.pm.ChangedPackages;
137 import android.content.pm.ComponentInfo;
138 import android.content.pm.FallbackCategoryProvider;
139 import android.content.pm.FeatureInfo;
140 import android.content.pm.IDexModuleRegisterCallback;
141 import android.content.pm.IOnPermissionsChangeListener;
142 import android.content.pm.IPackageDataObserver;
143 import android.content.pm.IPackageDeleteObserver;
144 import android.content.pm.IPackageDeleteObserver2;
145 import android.content.pm.IPackageInstallObserver2;
146 import android.content.pm.IPackageInstaller;
147 import android.content.pm.IPackageManager;
148 import android.content.pm.IPackageManagerNative;
149 import android.content.pm.IPackageMoveObserver;
150 import android.content.pm.IPackageStatsObserver;
151 import android.content.pm.InstantAppInfo;
152 import android.content.pm.InstantAppRequest;
153 import android.content.pm.InstantAppResolveInfo;
154 import android.content.pm.InstrumentationInfo;
155 import android.content.pm.IntentFilterVerificationInfo;
156 import android.content.pm.KeySet;
157 import android.content.pm.PackageCleanItem;
158 import android.content.pm.PackageInfo;
159 import android.content.pm.PackageInfoLite;
160 import android.content.pm.PackageInstaller;
161 import android.content.pm.PackageManager;
162 import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
163 import android.content.pm.PackageManagerInternal;
164 import android.content.pm.PackageParser;
165 import android.content.pm.PackageParser.ActivityIntentInfo;
166 import android.content.pm.PackageParser.PackageLite;
167 import android.content.pm.PackageParser.PackageParserException;
168 import android.content.pm.PackageStats;
169 import android.content.pm.PackageUserState;
170 import android.content.pm.ParceledListSlice;
171 import android.content.pm.PermissionGroupInfo;
172 import android.content.pm.PermissionInfo;
173 import android.content.pm.ProviderInfo;
174 import android.content.pm.ResolveInfo;
175 import android.content.pm.ServiceInfo;
176 import android.content.pm.SharedLibraryInfo;
177 import android.content.pm.Signature;
178 import android.content.pm.UserInfo;
179 import android.content.pm.VerifierDeviceIdentity;
180 import android.content.pm.VerifierInfo;
181 import android.content.pm.VersionedPackage;
182 import android.content.res.Resources;
183 import android.database.ContentObserver;
184 import android.graphics.Bitmap;
185 import android.hardware.display.DisplayManager;
186 import android.net.Uri;
187 import android.os.AsyncTask;
188 import android.os.Binder;
189 import android.os.Build;
190 import android.os.Bundle;
191 import android.os.Debug;
192 import android.os.Environment;
193 import android.os.Environment.UserEnvironment;
194 import android.os.FileUtils;
195 import android.os.Handler;
196 import android.os.IBinder;
197 import android.os.Looper;
198 import android.os.Message;
199 import android.os.Parcel;
200 import android.os.ParcelFileDescriptor;
201 import android.os.PatternMatcher;
202 import android.os.Process;
203 import android.os.RemoteCallbackList;
204 import android.os.RemoteException;
205 import android.os.ResultReceiver;
206 import android.os.SELinux;
207 import android.os.ServiceManager;
208 import android.os.ShellCallback;
209 import android.os.SystemClock;
210 import android.os.SystemProperties;
211 import android.os.Trace;
212 import android.os.UserHandle;
213 import android.os.UserManager;
214 import android.os.UserManagerInternal;
215 import android.os.storage.IStorageManager;
216 import android.os.storage.StorageEventListener;
217 import android.os.storage.StorageManager;
218 import android.os.storage.StorageManagerInternal;
219 import android.os.storage.VolumeInfo;
220 import android.os.storage.VolumeRecord;
221 import android.provider.Settings.Global;
222 import android.provider.Settings.Secure;
223 import android.security.KeyStore;
224 import android.security.SystemKeyStore;
225 import android.service.pm.PackageServiceDumpProto;
226 import android.system.ErrnoException;
227 import android.system.Os;
228 import android.text.TextUtils;
229 import android.text.format.DateUtils;
230 import android.util.ArrayMap;
231 import android.util.ArraySet;
232 import android.util.Base64;
233 import android.util.TimingsTraceLog;
234 import android.util.DisplayMetrics;
235 import android.util.EventLog;
236 import android.util.ExceptionUtils;
237 import android.util.Log;
238 import android.util.LogPrinter;
239 import android.util.MathUtils;
240 import android.util.PackageUtils;
241 import android.util.Pair;
242 import android.util.PrintStreamPrinter;
243 import android.util.Slog;
244 import android.util.SparseArray;
245 import android.util.SparseBooleanArray;
246 import android.util.SparseIntArray;
247 import android.util.Xml;
248 import android.util.jar.StrictJarFile;
249 import android.util.proto.ProtoOutputStream;
250 import android.view.Display;
252 import com.android.internal.R;
253 import com.android.internal.annotations.GuardedBy;
254 import com.android.internal.app.IMediaContainerService;
255 import com.android.internal.app.ResolverActivity;
256 import com.android.internal.content.NativeLibraryHelper;
257 import com.android.internal.content.PackageHelper;
258 import com.android.internal.logging.MetricsLogger;
259 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
260 import com.android.internal.os.IParcelFileDescriptorFactory;
261 import com.android.internal.os.RoSystemProperties;
262 import com.android.internal.os.SomeArgs;
263 import com.android.internal.os.Zygote;
264 import com.android.internal.telephony.CarrierAppUtils;
265 import com.android.internal.util.ArrayUtils;
266 import com.android.internal.util.ConcurrentUtils;
267 import com.android.internal.util.DumpUtils;
268 import com.android.internal.util.FastPrintWriter;
269 import com.android.internal.util.FastXmlSerializer;
270 import com.android.internal.util.IndentingPrintWriter;
271 import com.android.internal.util.Preconditions;
272 import com.android.internal.util.XmlUtils;
273 import com.android.server.AttributeCache;
274 import com.android.server.DeviceIdleController;
275 import com.android.server.EventLogTags;
276 import com.android.server.FgThread;
277 import com.android.server.IntentResolver;
278 import com.android.server.LocalServices;
279 import com.android.server.LockGuard;
280 import com.android.server.ServiceThread;
281 import com.android.server.SystemConfig;
282 import com.android.server.SystemServerInitThreadPool;
283 import com.android.server.Watchdog;
284 import com.android.server.net.NetworkPolicyManagerInternal;
285 import com.android.server.pm.Installer.InstallerException;
286 import com.android.server.pm.PermissionsState.PermissionState;
287 import com.android.server.pm.Settings.DatabaseVersion;
288 import com.android.server.pm.Settings.VersionInfo;
289 import com.android.server.pm.dex.DexManager;
290 import com.android.server.pm.dex.DexoptOptions;
291 import com.android.server.pm.dex.PackageDexUsage;
292 import com.android.server.storage.DeviceStorageMonitorInternal;
294 import dalvik.system.CloseGuard;
295 import dalvik.system.DexFile;
296 import dalvik.system.VMRuntime;
298 import libcore.io.IoUtils;
299 import libcore.io.Streams;
300 import libcore.util.EmptyArray;
302 import org.xmlpull.v1.XmlPullParser;
303 import org.xmlpull.v1.XmlPullParserException;
304 import org.xmlpull.v1.XmlSerializer;
306 import java.io.BufferedOutputStream;
307 import java.io.BufferedReader;
308 import java.io.ByteArrayInputStream;
309 import java.io.ByteArrayOutputStream;
311 import java.io.FileDescriptor;
312 import java.io.FileInputStream;
313 import java.io.FileOutputStream;
314 import java.io.FileReader;
315 import java.io.FilenameFilter;
316 import java.io.IOException;
317 import java.io.InputStream;
318 import java.io.OutputStream;
319 import java.io.PrintWriter;
320 import java.lang.annotation.Retention;
321 import java.lang.annotation.RetentionPolicy;
322 import java.nio.charset.StandardCharsets;
323 import java.security.DigestInputStream;
324 import java.security.MessageDigest;
325 import java.security.NoSuchAlgorithmException;
326 import java.security.PublicKey;
327 import java.security.SecureRandom;
328 import java.security.cert.Certificate;
329 import java.security.cert.CertificateEncodingException;
330 import java.security.cert.CertificateException;
331 import java.text.SimpleDateFormat;
332 import java.util.ArrayList;
333 import java.util.Arrays;
334 import java.util.Collection;
335 import java.util.Collections;
336 import java.util.Comparator;
337 import java.util.Date;
338 import java.util.HashMap;
339 import java.util.HashSet;
340 import java.util.Iterator;
341 import java.util.List;
342 import java.util.Map;
343 import java.util.Objects;
344 import java.util.Set;
345 import java.util.concurrent.CountDownLatch;
346 import java.util.concurrent.Future;
347 import java.util.concurrent.TimeUnit;
348 import java.util.concurrent.atomic.AtomicBoolean;
349 import java.util.concurrent.atomic.AtomicInteger;
350 import java.util.zip.GZIPInputStream;
353 * Keep track of all those APKs everywhere.
355 * Internally there are two important locks:
357 * <li>{@link #mPackages} is used to guard all in-memory parsed package details
358 * and other related state. It is a fine-grained lock that should only be held
359 * momentarily, as it's one of the most contended locks in the system.
360 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
361 * operations typically involve heavy lifting of application data on disk. Since
362 * {@code installd} is single-threaded, and it's operations can often be slow,
363 * this lock should never be acquired while already holding {@link #mPackages}.
364 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
365 * holding {@link #mInstallLock}.
367 * Many internal methods rely on the caller to hold the appropriate locks, and
368 * this contract is expressed through method name suffixes:
370 * <li>fooLI(): the caller must hold {@link #mInstallLock}
371 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
372 * being modified must be frozen
373 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
374 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
377 * Because this class is very central to the platform's security; please run all
378 * CTS and unit tests whenever making modifications:
381 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
382 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
385 public class PackageManagerService extends IPackageManager.Stub
386 implements PackageSender {
387 static final String TAG = "PackageManager";
388 static final boolean DEBUG_SETTINGS = false;
389 static final boolean DEBUG_PREFERRED = false;
390 static final boolean DEBUG_UPGRADE = false;
391 static final boolean DEBUG_DOMAIN_VERIFICATION = false;
392 private static final boolean DEBUG_BACKUP = false;
393 private static final boolean DEBUG_INSTALL = false;
394 private static final boolean DEBUG_REMOVE = false;
395 private static final boolean DEBUG_BROADCASTS = false;
396 private static final boolean DEBUG_SHOW_INFO = false;
397 private static final boolean DEBUG_PACKAGE_INFO = false;
398 private static final boolean DEBUG_INTENT_MATCHING = false;
399 private static final boolean DEBUG_PACKAGE_SCANNING = false;
400 private static final boolean DEBUG_VERIFY = false;
401 private static final boolean DEBUG_FILTERS = false;
402 private static final boolean DEBUG_PERMISSIONS = false;
403 private static final boolean DEBUG_SHARED_LIBRARIES = false;
404 private static final boolean DEBUG_COMPRESSION = Build.IS_DEBUGGABLE;
406 // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
407 // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
408 // user, but by default initialize to this.
409 public static final boolean DEBUG_DEXOPT = false;
411 private static final boolean DEBUG_ABI_SELECTION = false;
412 private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE;
413 private static final boolean DEBUG_TRIAGED_MISSING = false;
414 private static final boolean DEBUG_APP_DATA = false;
416 /** REMOVE. According to Svet, this was only used to reset permissions during development. */
417 static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
419 private static final boolean HIDE_EPHEMERAL_APIS = false;
421 private static final boolean ENABLE_FREE_CACHE_V2 =
422 SystemProperties.getBoolean("fw.free_cache_v2", true);
424 private static final int RADIO_UID = Process.PHONE_UID;
425 private static final int LOG_UID = Process.LOG_UID;
426 private static final int NFC_UID = Process.NFC_UID;
427 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
428 private static final int SHELL_UID = Process.SHELL_UID;
430 // Cap the size of permission trees that 3rd party apps can define
431 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768; // characters of text
433 // Suffix used during package installation when copying/moving
434 // package apks to install directory.
435 private static final String INSTALL_PACKAGE_SUFFIX = "-";
437 static final int SCAN_NO_DEX = 1<<1;
438 static final int SCAN_FORCE_DEX = 1<<2;
439 static final int SCAN_UPDATE_SIGNATURE = 1<<3;
440 static final int SCAN_NEW_INSTALL = 1<<4;
441 static final int SCAN_UPDATE_TIME = 1<<5;
442 static final int SCAN_BOOTING = 1<<6;
443 static final int SCAN_TRUSTED_OVERLAY = 1<<7;
444 static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<8;
445 static final int SCAN_REPLACING = 1<<9;
446 static final int SCAN_REQUIRE_KNOWN = 1<<10;
447 static final int SCAN_MOVE = 1<<11;
448 static final int SCAN_INITIAL = 1<<12;
449 static final int SCAN_CHECK_ONLY = 1<<13;
450 static final int SCAN_DONT_KILL_APP = 1<<14;
451 static final int SCAN_IGNORE_FROZEN = 1<<15;
452 static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<16;
453 static final int SCAN_AS_INSTANT_APP = 1<<17;
454 static final int SCAN_AS_FULL_APP = 1<<18;
455 static final int SCAN_AS_VIRTUAL_PRELOAD = 1<<19;
456 /** Should not be with the scan flags */
457 static final int FLAGS_REMOVE_CHATTY = 1<<31;
459 private static final String STATIC_SHARED_LIB_DELIMITER = "_";
460 /** Extension of the compressed packages */
461 private final static String COMPRESSED_EXTENSION = ".gz";
462 /** Suffix of stub packages on the system partition */
463 private final static String STUB_SUFFIX = "-Stub";
465 private static final int[] EMPTY_INT_ARRAY = new int[0];
467 private static final int TYPE_UNKNOWN = 0;
468 private static final int TYPE_ACTIVITY = 1;
469 private static final int TYPE_RECEIVER = 2;
470 private static final int TYPE_SERVICE = 3;
471 private static final int TYPE_PROVIDER = 4;
472 @IntDef(prefix = { "TYPE_" }, value = {
479 @Retention(RetentionPolicy.SOURCE)
480 public @interface ComponentType {}
483 * Timeout (in milliseconds) after which the watchdog should declare that
484 * our handler thread is wedged. The usual default for such things is one
485 * minute but we sometimes do very lengthy I/O operations on this thread,
486 * such as installing multi-gigabyte applications, so ours needs to be longer.
488 static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes
491 * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
492 * be run on this device. We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
493 * settings entry if available, otherwise we use the hardcoded default. If it's been
494 * more than this long since the last fstrim, we force one during the boot sequence.
496 * This backstops other fstrim scheduling: if the device is alive at midnight+idle,
497 * one gets run at the next available charging+idle time. This final mandatory
498 * no-fstrim check kicks in only of the other scheduling criteria is never met.
500 private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
503 * Whether verification is enabled by default.
505 private static final boolean DEFAULT_VERIFY_ENABLE = true;
508 * The default maximum time to wait for the verification agent to return in
511 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
514 * The default response for package verification timeout.
516 * This can be either PackageManager.VERIFICATION_ALLOW or
517 * PackageManager.VERIFICATION_REJECT.
519 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
521 static final String PLATFORM_PACKAGE_NAME = "android";
523 static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
525 static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
526 DEFAULT_CONTAINER_PACKAGE,
527 "com.android.defcontainer.DefaultContainerService");
529 private static final String KILL_APP_REASON_GIDS_CHANGED =
530 "permission grant or revoke changed gids";
532 private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
533 "permissions revoked";
535 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
537 private static final String PACKAGE_SCHEME = "package";
539 private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
541 /** Permission grant: not grant the permission. */
542 private static final int GRANT_DENIED = 1;
544 /** Permission grant: grant the permission as an install permission. */
545 private static final int GRANT_INSTALL = 2;
547 /** Permission grant: grant the permission as a runtime one. */
548 private static final int GRANT_RUNTIME = 3;
550 /** Permission grant: grant as runtime a permission that was granted as an install time one. */
551 private static final int GRANT_UPGRADE = 4;
553 /** Canonical intent used to identify what counts as a "web browser" app */
554 private static final Intent sBrowserIntent;
556 sBrowserIntent = new Intent();
557 sBrowserIntent.setAction(Intent.ACTION_VIEW);
558 sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
559 sBrowserIntent.setData(Uri.parse("http:"));
563 * The set of all protected actions [i.e. those actions for which a high priority
564 * intent filter is disallowed].
566 private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
568 PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
569 PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
570 PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
571 PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
574 // Compilation reasons.
575 public static final int REASON_FIRST_BOOT = 0;
576 public static final int REASON_BOOT = 1;
577 public static final int REASON_INSTALL = 2;
578 public static final int REASON_BACKGROUND_DEXOPT = 3;
579 public static final int REASON_AB_OTA = 4;
580 public static final int REASON_INACTIVE_PACKAGE_DOWNGRADE = 5;
581 public static final int REASON_SHARED = 6;
583 public static final int REASON_LAST = REASON_SHARED;
585 /** All dangerous permission names in the same order as the events in MetricsEvent */
586 private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList(
587 Manifest.permission.READ_CALENDAR,
588 Manifest.permission.WRITE_CALENDAR,
589 Manifest.permission.CAMERA,
590 Manifest.permission.READ_CONTACTS,
591 Manifest.permission.WRITE_CONTACTS,
592 Manifest.permission.GET_ACCOUNTS,
593 Manifest.permission.ACCESS_FINE_LOCATION,
594 Manifest.permission.ACCESS_COARSE_LOCATION,
595 Manifest.permission.RECORD_AUDIO,
596 Manifest.permission.READ_PHONE_STATE,
597 Manifest.permission.CALL_PHONE,
598 Manifest.permission.READ_CALL_LOG,
599 Manifest.permission.WRITE_CALL_LOG,
600 Manifest.permission.ADD_VOICEMAIL,
601 Manifest.permission.USE_SIP,
602 Manifest.permission.PROCESS_OUTGOING_CALLS,
603 Manifest.permission.READ_CELL_BROADCASTS,
604 Manifest.permission.BODY_SENSORS,
605 Manifest.permission.SEND_SMS,
606 Manifest.permission.RECEIVE_SMS,
607 Manifest.permission.READ_SMS,
608 Manifest.permission.RECEIVE_WAP_PUSH,
609 Manifest.permission.RECEIVE_MMS,
610 Manifest.permission.READ_EXTERNAL_STORAGE,
611 Manifest.permission.WRITE_EXTERNAL_STORAGE,
612 Manifest.permission.READ_PHONE_NUMBERS,
613 Manifest.permission.ANSWER_PHONE_CALLS);
617 * Version number for the package parser cache. Increment this whenever the format or
618 * extent of cached data changes. See {@code PackageParser#setCacheDir}.
620 private static final String PACKAGE_PARSER_CACHE_VERSION = "1";
623 * Whether the package parser cache is enabled.
625 private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
627 final ServiceThread mHandlerThread;
629 final PackageHandler mHandler;
631 private final ProcessLoggingHandler mProcessLoggingHandler;
634 * Messages for {@link #mHandler} that need to wait for system ready before
637 private ArrayList<Message> mPostSystemReadyMessages;
639 final int mSdkVersion = Build.VERSION.SDK_INT;
641 final Context mContext;
642 final boolean mFactoryTest;
643 final boolean mOnlyCore;
644 final DisplayMetrics mMetrics;
645 final int mDefParseFlags;
646 final String[] mSeparateProcesses;
647 final boolean mIsUpgrade;
648 final boolean mIsPreNUpgrade;
649 final boolean mIsPreNMR1Upgrade;
651 // Have we told the Activity Manager to whitelist the default container service by uid yet?
652 @GuardedBy("mPackages")
653 boolean mDefaultContainerWhitelisted = false;
655 @GuardedBy("mPackages")
656 private boolean mDexOptDialogShown;
658 /** The location for ASEC container files on internal storage. */
659 final String mAsecInternalPath;
661 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
662 // LOCK HELD. Can be called with mInstallLock held.
663 @GuardedBy("mInstallLock")
664 final Installer mInstaller;
666 /** Directory where installed third-party apps stored */
667 final File mAppInstallDir;
670 * Directory to which applications installed internally have their
671 * 32 bit native libraries copied.
673 private File mAppLib32InstallDir;
675 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
677 final File mDrmAppPrivateInstallDir;
679 // ----------------------------------------------------------------
681 // Lock for state used when installing and doing other long running
682 // operations. Methods that must be called with this lock held have
684 final Object mInstallLock = new Object();
686 // ----------------------------------------------------------------
688 // Keys are String (package name), values are Package. This also serves
689 // as the lock for the global state. Methods that must be called with
690 // this lock held have the prefix "LP".
691 @GuardedBy("mPackages")
692 final ArrayMap<String, PackageParser.Package> mPackages =
693 new ArrayMap<String, PackageParser.Package>();
695 final ArrayMap<String, Set<String>> mKnownCodebase =
696 new ArrayMap<String, Set<String>>();
698 // Keys are isolated uids and values are the uid of the application
699 // that created the isolated proccess.
700 @GuardedBy("mPackages")
701 final SparseIntArray mIsolatedOwners = new SparseIntArray();
704 * Tracks new system packages [received in an OTA] that we expect to
705 * find updated user-installed versions. Keys are package name, values
706 * are package location.
708 final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
710 * Tracks high priority intent filters for protected actions. During boot, certain
711 * filter actions are protected and should never be allowed to have a high priority
712 * intent filter for them. However, there is one, and only one exception -- the
713 * setup wizard. It must be able to define a high priority intent filter for these
714 * actions to ensure there are no escapes from the wizard. We need to delay processing
715 * of these during boot as we need to look at all of the system packages in order
716 * to know which component is the setup wizard.
718 private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
720 * Whether or not processing protected filters should be deferred.
722 private boolean mDeferProtectedFilters = true;
725 * Tracks existing system packages prior to receiving an OTA. Keys are package name.
727 final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
729 * Whether or not system app permissions should be promoted from install to runtime.
731 boolean mPromoteSystemApps;
733 @GuardedBy("mPackages")
734 final Settings mSettings;
737 * Set of package names that are currently "frozen", which means active
738 * surgery is being done on the code/data for that package. The platform
739 * will refuse to launch frozen packages to avoid race conditions.
741 * @see PackageFreezer
743 @GuardedBy("mPackages")
744 final ArraySet<String> mFrozenPackages = new ArraySet<>();
746 final ProtectedPackages mProtectedPackages;
748 @GuardedBy("mLoadedVolumes")
749 final ArraySet<String> mLoadedVolumes = new ArraySet<>();
753 PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
755 // System configuration read by SystemConfig.
756 final int[] mGlobalGids;
757 final SparseArray<ArraySet<String>> mSystemPermissions;
758 @GuardedBy("mAvailableFeatures")
759 final ArrayMap<String, FeatureInfo> mAvailableFeatures;
761 // If mac_permissions.xml was found for seinfo labeling.
762 boolean mFoundPolicyFile;
764 private final InstantAppRegistry mInstantAppRegistry;
766 @GuardedBy("mPackages")
767 int mChangedPackagesSequenceNumber;
769 * List of changed [installed, removed or updated] packages.
770 * mapping from user id -> sequence number -> package name
772 @GuardedBy("mPackages")
773 final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>();
775 * The sequence number of the last change to a package.
776 * mapping from user id -> package name -> sequence number
778 @GuardedBy("mPackages")
779 final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
781 class PackageParserCallback implements PackageParser.Callback {
782 @Override public final boolean hasFeature(String feature) {
783 return PackageManagerService.this.hasSystemFeature(feature, 0);
786 final List<PackageParser.Package> getStaticOverlayPackagesLocked(
787 Collection<PackageParser.Package> allPackages, String targetPackageName) {
788 List<PackageParser.Package> overlayPackages = null;
789 for (PackageParser.Package p : allPackages) {
790 if (targetPackageName.equals(p.mOverlayTarget) && p.mIsStaticOverlay) {
791 if (overlayPackages == null) {
792 overlayPackages = new ArrayList<PackageParser.Package>();
794 overlayPackages.add(p);
797 if (overlayPackages != null) {
798 Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
799 public int compare(PackageParser.Package p1, PackageParser.Package p2) {
800 return p1.mOverlayPriority - p2.mOverlayPriority;
803 Collections.sort(overlayPackages, cmp);
805 return overlayPackages;
808 final String[] getStaticOverlayPathsLocked(Collection<PackageParser.Package> allPackages,
809 String targetPackageName, String targetPath) {
810 if ("android".equals(targetPackageName)) {
811 // Static RROs targeting to "android", ie framework-res.apk, are already applied by
812 // native AssetManager.
815 List<PackageParser.Package> overlayPackages =
816 getStaticOverlayPackagesLocked(allPackages, targetPackageName);
817 if (overlayPackages == null || overlayPackages.isEmpty()) {
820 List<String> overlayPathList = null;
821 for (PackageParser.Package overlayPackage : overlayPackages) {
822 if (targetPath == null) {
823 if (overlayPathList == null) {
824 overlayPathList = new ArrayList<String>();
826 overlayPathList.add(overlayPackage.baseCodePath);
831 // Creates idmaps for system to parse correctly the Android manifest of the
834 // OverlayManagerService will update each of them with a correct gid from its
835 // target package app id.
836 mInstaller.idmap(targetPath, overlayPackage.baseCodePath,
837 UserHandle.getSharedAppGid(
838 UserHandle.getUserGid(UserHandle.USER_SYSTEM)));
839 if (overlayPathList == null) {
840 overlayPathList = new ArrayList<String>();
842 overlayPathList.add(overlayPackage.baseCodePath);
843 } catch (InstallerException e) {
844 Slog.e(TAG, "Failed to generate idmap for " + targetPath + " and " +
845 overlayPackage.baseCodePath);
848 return overlayPathList == null ? null : overlayPathList.toArray(new String[0]);
851 String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
852 synchronized (mPackages) {
853 return getStaticOverlayPathsLocked(
854 mPackages.values(), targetPackageName, targetPath);
858 @Override public final String[] getOverlayApks(String targetPackageName) {
859 return getStaticOverlayPaths(targetPackageName, null);
862 @Override public final String[] getOverlayPaths(String targetPackageName,
864 return getStaticOverlayPaths(targetPackageName, targetPath);
868 class ParallelPackageParserCallback extends PackageParserCallback {
869 List<PackageParser.Package> mOverlayPackages = null;
871 void findStaticOverlayPackages() {
872 synchronized (mPackages) {
873 for (PackageParser.Package p : mPackages.values()) {
874 if (p.mIsStaticOverlay) {
875 if (mOverlayPackages == null) {
876 mOverlayPackages = new ArrayList<PackageParser.Package>();
878 mOverlayPackages.add(p);
885 synchronized String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
886 // We can trust mOverlayPackages without holding mPackages because package uninstall
887 // can't happen while running parallel parsing.
888 // Moreover holding mPackages on each parsing thread causes dead-lock.
889 return mOverlayPackages == null ? null :
890 getStaticOverlayPathsLocked(mOverlayPackages, targetPackageName, targetPath);
894 final PackageParser.Callback mPackageParserCallback = new PackageParserCallback();
895 final ParallelPackageParserCallback mParallelPackageParserCallback =
896 new ParallelPackageParserCallback();
898 public static final class SharedLibraryEntry {
899 public final @Nullable String path;
900 public final @Nullable String apk;
901 public final @NonNull SharedLibraryInfo info;
903 SharedLibraryEntry(String _path, String _apk, String name, int version, int type,
904 String declaringPackageName, int declaringPackageVersionCode) {
907 info = new SharedLibraryInfo(name, version, type, new VersionedPackage(
908 declaringPackageName, declaringPackageVersionCode), null);
912 // Currently known shared libraries.
913 final ArrayMap<String, SparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>();
914 final ArrayMap<String, SparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage =
917 // All available activities, for your resolving pleasure.
918 final ActivityIntentResolver mActivities =
919 new ActivityIntentResolver();
921 // All available receivers, for your resolving pleasure.
922 final ActivityIntentResolver mReceivers =
923 new ActivityIntentResolver();
925 // All available services, for your resolving pleasure.
926 final ServiceIntentResolver mServices = new ServiceIntentResolver();
928 // All available providers, for your resolving pleasure.
929 final ProviderIntentResolver mProviders = new ProviderIntentResolver();
931 // Mapping from provider base names (first directory in content URI codePath)
932 // to the provider information.
933 final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
934 new ArrayMap<String, PackageParser.Provider>();
936 // Mapping from instrumentation class names to info about them.
937 final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
938 new ArrayMap<ComponentName, PackageParser.Instrumentation>();
940 // Mapping from permission names to info about them.
941 final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
942 new ArrayMap<String, PackageParser.PermissionGroup>();
944 // Packages whose data we have transfered into another package, thus
945 // should no longer exist.
946 final ArraySet<String> mTransferedPackages = new ArraySet<String>();
948 // Broadcast actions that are only available to the system.
949 @GuardedBy("mProtectedBroadcasts")
950 final ArraySet<String> mProtectedBroadcasts = new ArraySet<>();
952 /** List of packages waiting for verification. */
953 final SparseArray<PackageVerificationState> mPendingVerification
954 = new SparseArray<PackageVerificationState>();
956 /** Set of packages associated with each app op permission. */
957 final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
959 final PackageInstallerService mInstallerService;
961 private final PackageDexOptimizer mPackageDexOptimizer;
962 // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
963 // is used by other apps).
964 private final DexManager mDexManager;
966 private AtomicInteger mNextMoveId = new AtomicInteger();
967 private final MoveCallbacks mMoveCallbacks;
969 private final OnPermissionChangeListeners mOnPermissionChangeListeners;
971 // Cache of users who need badging.
972 SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
974 /** Token for keys in mPendingVerification. */
975 private int mPendingVerificationToken = 0;
977 volatile boolean mSystemReady;
978 volatile boolean mSafeMode;
979 volatile boolean mHasSystemUidErrors;
980 private volatile boolean mEphemeralAppsDisabled;
982 ApplicationInfo mAndroidApplication;
983 final ActivityInfo mResolveActivity = new ActivityInfo();
984 final ResolveInfo mResolveInfo = new ResolveInfo();
985 ComponentName mResolveComponentName;
986 PackageParser.Package mPlatformPackage;
987 ComponentName mCustomResolverComponentName;
989 boolean mResolverReplaced = false;
991 private final @Nullable ComponentName mIntentFilterVerifierComponent;
992 private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
994 private int mIntentFilterVerificationToken = 0;
996 /** The service connection to the ephemeral resolver */
997 final EphemeralResolverConnection mInstantAppResolverConnection;
998 /** Component used to show resolver settings for Instant Apps */
999 final ComponentName mInstantAppResolverSettingsComponent;
1001 /** Activity used to install instant applications */
1002 ActivityInfo mInstantAppInstallerActivity;
1003 final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
1005 final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
1006 = new SparseArray<IntentFilterVerificationState>();
1008 final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
1010 // List of packages names to keep cached, even if they are uninstalled for all users
1011 private List<String> mKeepUninstalledPackages;
1013 private UserManagerInternal mUserManagerInternal;
1015 private DeviceIdleController.LocalService mDeviceIdleController;
1017 private File mCacheDir;
1019 private ArraySet<String> mPrivappPermissionsViolations;
1021 private Future<?> mPrepareAppDataFuture;
1023 private static class IFVerificationParams {
1024 PackageParser.Package pkg;
1029 public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
1030 int _userId, int _verifierUid) {
1032 replacing = _replacing;
1034 replacing = _replacing;
1035 verifierUid = _verifierUid;
1039 private interface IntentFilterVerifier<T extends IntentFilter> {
1040 boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
1041 T filter, String packageName);
1042 void startVerifications(int userId);
1043 void receiveVerificationResponse(int verificationId);
1046 private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
1047 private Context mContext;
1048 private ComponentName mIntentFilterVerifierComponent;
1049 private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
1051 public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
1053 mIntentFilterVerifierComponent = verifierComponent;
1056 private String getDefaultScheme() {
1057 return IntentFilter.SCHEME_HTTPS;
1061 public void startVerifications(int userId) {
1062 // Launch verifications requests
1063 int count = mCurrentIntentFilterVerifications.size();
1064 for (int n=0; n<count; n++) {
1065 int verificationId = mCurrentIntentFilterVerifications.get(n);
1066 final IntentFilterVerificationState ivs =
1067 mIntentFilterVerificationStates.get(verificationId);
1069 String packageName = ivs.getPackageName();
1071 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1072 final int filterCount = filters.size();
1073 ArraySet<String> domainsSet = new ArraySet<>();
1074 for (int m=0; m<filterCount; m++) {
1075 PackageParser.ActivityIntentInfo filter = filters.get(m);
1076 domainsSet.addAll(filter.getHostsList());
1078 synchronized (mPackages) {
1079 if (mSettings.createIntentFilterVerificationIfNeededLPw(
1080 packageName, domainsSet) != null) {
1081 scheduleWriteSettingsLocked();
1084 sendVerificationRequest(verificationId, ivs);
1086 mCurrentIntentFilterVerifications.clear();
1089 private void sendVerificationRequest(int verificationId, IntentFilterVerificationState ivs) {
1090 Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
1091 verificationIntent.putExtra(
1092 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
1094 verificationIntent.putExtra(
1095 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
1096 getDefaultScheme());
1097 verificationIntent.putExtra(
1098 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
1099 ivs.getHostsString());
1100 verificationIntent.putExtra(
1101 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
1102 ivs.getPackageName());
1103 verificationIntent.setComponent(mIntentFilterVerifierComponent);
1104 verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
1106 DeviceIdleController.LocalService idleController = getDeviceIdleController();
1107 idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
1108 mIntentFilterVerifierComponent.getPackageName(), getVerificationTimeout(),
1109 UserHandle.USER_SYSTEM, true, "intent filter verifier");
1111 mContext.sendBroadcastAsUser(verificationIntent, UserHandle.SYSTEM);
1112 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1113 "Sending IntentFilter verification broadcast");
1116 public void receiveVerificationResponse(int verificationId) {
1117 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1119 final boolean verified = ivs.isVerified();
1121 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1122 final int count = filters.size();
1123 if (DEBUG_DOMAIN_VERIFICATION) {
1124 Slog.i(TAG, "Received verification response " + verificationId
1125 + " for " + count + " filters, verified=" + verified);
1127 for (int n=0; n<count; n++) {
1128 PackageParser.ActivityIntentInfo filter = filters.get(n);
1129 filter.setVerified(verified);
1131 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
1132 + " verified with result:" + verified + " and hosts:"
1133 + ivs.getHostsString());
1136 mIntentFilterVerificationStates.remove(verificationId);
1138 final String packageName = ivs.getPackageName();
1139 IntentFilterVerificationInfo ivi = null;
1141 synchronized (mPackages) {
1142 ivi = mSettings.getIntentFilterVerificationLPr(packageName);
1145 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
1146 + verificationId + " packageName:" + packageName);
1149 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1150 "Updating IntentFilterVerificationInfo for package " + packageName
1151 +" verificationId:" + verificationId);
1153 synchronized (mPackages) {
1155 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
1157 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
1159 scheduleWriteSettingsLocked();
1161 final int userId = ivs.getUserId();
1162 if (userId != UserHandle.USER_ALL) {
1163 final int userStatus =
1164 mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
1166 int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1167 boolean needUpdate = false;
1169 // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
1170 // already been set by the User thru the Disambiguation dialog
1171 switch (userStatus) {
1172 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
1174 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1176 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
1181 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
1183 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1193 mSettings.updateIntentFilterVerificationStatusLPw(
1194 packageName, updatedStatus, userId);
1195 scheduleWritePackageRestrictionsLocked(userId);
1202 public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
1203 ActivityIntentInfo filter, String packageName) {
1204 if (!hasValidDomains(filter)) {
1207 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1209 ivs = createDomainVerificationState(verifierUid, userId, verificationId,
1212 if (DEBUG_DOMAIN_VERIFICATION) {
1213 Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
1215 ivs.addFilter(filter);
1219 private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
1220 int userId, int verificationId, String packageName) {
1221 IntentFilterVerificationState ivs = new IntentFilterVerificationState(
1222 verifierUid, userId, packageName);
1223 ivs.setPendingState();
1224 synchronized (mPackages) {
1225 mIntentFilterVerificationStates.append(verificationId, ivs);
1226 mCurrentIntentFilterVerifications.add(verificationId);
1232 private static boolean hasValidDomains(ActivityIntentInfo filter) {
1233 return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
1234 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
1235 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
1238 // Set of pending broadcasts for aggregating enable/disable of components.
1239 static class PendingPackageBroadcasts {
1240 // for each user id, a map of <package name -> components within that package>
1241 final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
1243 public PendingPackageBroadcasts() {
1244 mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
1247 public ArrayList<String> get(int userId, String packageName) {
1248 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1249 return packages.get(packageName);
1252 public void put(int userId, String packageName, ArrayList<String> components) {
1253 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1254 packages.put(packageName, components);
1257 public void remove(int userId, String packageName) {
1258 ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1259 if (packages != null) {
1260 packages.remove(packageName);
1264 public void remove(int userId) {
1265 mUidMap.remove(userId);
1268 public int userIdCount() {
1269 return mUidMap.size();
1272 public int userIdAt(int n) {
1273 return mUidMap.keyAt(n);
1276 public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1277 return mUidMap.get(userId);
1281 // total number of pending broadcast entries across all userIds
1283 for (int i = 0; i< mUidMap.size(); i++) {
1284 num += mUidMap.valueAt(i).size();
1289 public void clear() {
1293 private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1294 ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1296 map = new ArrayMap<String, ArrayList<String>>();
1297 mUidMap.put(userId, map);
1302 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1304 // Service Connection to remote media container service to copy
1305 // package uri's from external media onto secure containers
1306 // or internal storage.
1307 private IMediaContainerService mContainerService = null;
1309 static final int SEND_PENDING_BROADCAST = 1;
1310 static final int MCS_BOUND = 3;
1311 static final int END_COPY = 4;
1312 static final int INIT_COPY = 5;
1313 static final int MCS_UNBIND = 6;
1314 static final int START_CLEANING_PACKAGE = 7;
1315 static final int FIND_INSTALL_LOC = 8;
1316 static final int POST_INSTALL = 9;
1317 static final int MCS_RECONNECT = 10;
1318 static final int MCS_GIVE_UP = 11;
1319 static final int UPDATED_MEDIA_STATUS = 12;
1320 static final int WRITE_SETTINGS = 13;
1321 static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1322 static final int PACKAGE_VERIFIED = 15;
1323 static final int CHECK_PENDING_VERIFICATION = 16;
1324 static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1325 static final int INTENT_FILTER_VERIFIED = 18;
1326 static final int WRITE_PACKAGE_LIST = 19;
1327 static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
1329 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds
1331 // Delay time in millisecs
1332 static final int BROADCAST_DELAY = 10 * 1000;
1334 private static final long DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
1335 2 * 60 * 60 * 1000L; /* two hours */
1337 static UserManagerService sUserManager;
1339 // Stores a list of users whose package restrictions file needs to be updated
1340 private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1342 final private DefaultContainerConnection mDefContainerConn =
1343 new DefaultContainerConnection();
1344 class DefaultContainerConnection implements ServiceConnection {
1345 public void onServiceConnected(ComponentName name, IBinder service) {
1346 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1347 final IMediaContainerService imcs = IMediaContainerService.Stub
1348 .asInterface(Binder.allowBlocking(service));
1349 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1352 public void onServiceDisconnected(ComponentName name) {
1353 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1357 // Recordkeeping of restore-after-install operations that are currently in flight
1358 // between the Package Manager and the Backup Manager
1359 static class PostInstallData {
1360 public InstallArgs args;
1361 public PackageInstalledInfo res;
1363 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1369 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1370 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows
1372 // XML tags for backup/restore of various bits of state
1373 private static final String TAG_PREFERRED_BACKUP = "pa";
1374 private static final String TAG_DEFAULT_APPS = "da";
1375 private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1377 private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1378 private static final String TAG_ALL_GRANTS = "rt-grants";
1379 private static final String TAG_GRANT = "grant";
1380 private static final String ATTR_PACKAGE_NAME = "pkg";
1382 private static final String TAG_PERMISSION = "perm";
1383 private static final String ATTR_PERMISSION_NAME = "name";
1384 private static final String ATTR_IS_GRANTED = "g";
1385 private static final String ATTR_USER_SET = "set";
1386 private static final String ATTR_USER_FIXED = "fixed";
1387 private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1389 // System/policy permission grants are not backed up
1390 private static final int SYSTEM_RUNTIME_GRANT_MASK =
1391 FLAG_PERMISSION_POLICY_FIXED
1392 | FLAG_PERMISSION_SYSTEM_FIXED
1393 | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1395 // And we back up these user-adjusted states
1396 private static final int USER_RUNTIME_GRANT_MASK =
1397 FLAG_PERMISSION_USER_SET
1398 | FLAG_PERMISSION_USER_FIXED
1399 | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1401 final @Nullable String mRequiredVerifierPackage;
1402 final @NonNull String mRequiredInstallerPackage;
1403 final @NonNull String mRequiredUninstallerPackage;
1404 final @Nullable String mSetupWizardPackage;
1405 final @Nullable String mStorageManagerPackage;
1406 final @NonNull String mServicesSystemSharedLibraryPackageName;
1407 final @NonNull String mSharedSystemSharedLibraryPackageName;
1409 final boolean mPermissionReviewRequired;
1411 private final PackageUsage mPackageUsage = new PackageUsage();
1412 private final CompilerStats mCompilerStats = new CompilerStats();
1414 class PackageHandler extends Handler {
1415 private boolean mBound = false;
1416 final ArrayList<HandlerParams> mPendingInstalls =
1417 new ArrayList<HandlerParams>();
1419 private boolean connectToService() {
1420 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1421 " DefaultContainerService");
1422 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1423 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1424 if (mContext.bindServiceAsUser(service, mDefContainerConn,
1425 Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1426 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1430 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1434 private void disconnectService() {
1435 mContainerService = null;
1437 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1438 mContext.unbindService(mDefContainerConn);
1439 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1442 PackageHandler(Looper looper) {
1446 public void handleMessage(Message msg) {
1448 doHandleMessage(msg);
1450 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1454 void doHandleMessage(Message msg) {
1457 HandlerParams params = (HandlerParams) msg.obj;
1458 int idx = mPendingInstalls.size();
1459 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1460 // If a bind was already initiated we dont really
1461 // need to do anything. The pending install
1462 // will be processed later on.
1464 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1465 System.identityHashCode(mHandler));
1466 // If this is the only one pending we might
1467 // have to bind to the service again.
1468 if (!connectToService()) {
1469 Slog.e(TAG, "Failed to bind to media container service");
1470 params.serviceError();
1471 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1472 System.identityHashCode(mHandler));
1473 if (params.traceMethod != null) {
1474 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1475 params.traceCookie);
1479 // Once we bind to the service, the first
1480 // pending request will be processed.
1481 mPendingInstalls.add(idx, params);
1484 mPendingInstalls.add(idx, params);
1485 // Already bound to the service. Just make
1486 // sure we trigger off processing the first request.
1488 mHandler.sendEmptyMessage(MCS_BOUND);
1494 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1495 if (msg.obj != null) {
1496 mContainerService = (IMediaContainerService) msg.obj;
1497 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1498 System.identityHashCode(mHandler));
1500 if (mContainerService == null) {
1502 // Something seriously wrong since we are not bound and we are not
1503 // waiting for connection. Bail out.
1504 Slog.e(TAG, "Cannot bind to media container service");
1505 for (HandlerParams params : mPendingInstalls) {
1506 // Indicate service bind error
1507 params.serviceError();
1508 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1509 System.identityHashCode(params));
1510 if (params.traceMethod != null) {
1511 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1512 params.traceMethod, params.traceCookie);
1516 mPendingInstalls.clear();
1518 Slog.w(TAG, "Waiting to connect to media container service");
1520 } else if (mPendingInstalls.size() > 0) {
1521 HandlerParams params = mPendingInstalls.get(0);
1522 if (params != null) {
1523 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1524 System.identityHashCode(params));
1525 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1526 if (params.startCopy()) {
1527 // We are done... look for more work or to
1529 if (DEBUG_SD_INSTALL) Log.i(TAG,
1530 "Checking for more work or unbind...");
1531 // Delete pending install
1532 if (mPendingInstalls.size() > 0) {
1533 mPendingInstalls.remove(0);
1535 if (mPendingInstalls.size() == 0) {
1537 if (DEBUG_SD_INSTALL) Log.i(TAG,
1538 "Posting delayed MCS_UNBIND");
1539 removeMessages(MCS_UNBIND);
1540 Message ubmsg = obtainMessage(MCS_UNBIND);
1541 // Unbind after a little delay, to avoid
1542 // continual thrashing.
1543 sendMessageDelayed(ubmsg, 10000);
1546 // There are more pending requests in queue.
1547 // Just post MCS_BOUND message to trigger processing
1548 // of next pending install.
1549 if (DEBUG_SD_INSTALL) Log.i(TAG,
1550 "Posting MCS_BOUND for next work");
1551 mHandler.sendEmptyMessage(MCS_BOUND);
1554 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1557 // Should never happen ideally.
1558 Slog.w(TAG, "Empty queue");
1562 case MCS_RECONNECT: {
1563 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1564 if (mPendingInstalls.size() > 0) {
1566 disconnectService();
1568 if (!connectToService()) {
1569 Slog.e(TAG, "Failed to bind to media container service");
1570 for (HandlerParams params : mPendingInstalls) {
1571 // Indicate service bind error
1572 params.serviceError();
1573 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1574 System.identityHashCode(params));
1576 mPendingInstalls.clear();
1582 // If there is no actual work left, then time to unbind.
1583 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1585 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1587 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1589 disconnectService();
1591 } else if (mPendingInstalls.size() > 0) {
1592 // There are more pending requests in queue.
1593 // Just post MCS_BOUND message to trigger processing
1594 // of next pending install.
1595 mHandler.sendEmptyMessage(MCS_BOUND);
1601 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1602 HandlerParams params = mPendingInstalls.remove(0);
1603 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1604 System.identityHashCode(params));
1607 case SEND_PENDING_BROADCAST: {
1609 ArrayList<String> components[];
1612 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1613 synchronized (mPackages) {
1614 if (mPendingBroadcasts == null) {
1617 size = mPendingBroadcasts.size();
1619 // Nothing to be done. Just return
1622 packages = new String[size];
1623 components = new ArrayList[size];
1624 uids = new int[size];
1625 int i = 0; // filling out the above arrays
1627 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1628 int packageUserId = mPendingBroadcasts.userIdAt(n);
1629 Iterator<Map.Entry<String, ArrayList<String>>> it
1630 = mPendingBroadcasts.packagesForUserId(packageUserId)
1631 .entrySet().iterator();
1632 while (it.hasNext() && i < size) {
1633 Map.Entry<String, ArrayList<String>> ent = it.next();
1634 packages[i] = ent.getKey();
1635 components[i] = ent.getValue();
1636 PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1637 uids[i] = (ps != null)
1638 ? UserHandle.getUid(packageUserId, ps.appId)
1644 mPendingBroadcasts.clear();
1647 for (int i = 0; i < size; i++) {
1648 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1650 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1653 case START_CLEANING_PACKAGE: {
1654 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1655 final String packageName = (String)msg.obj;
1656 final int userId = msg.arg1;
1657 final boolean andCode = msg.arg2 != 0;
1658 synchronized (mPackages) {
1659 if (userId == UserHandle.USER_ALL) {
1660 int[] users = sUserManager.getUserIds();
1661 for (int user : users) {
1662 mSettings.addPackageToCleanLPw(
1663 new PackageCleanItem(user, packageName, andCode));
1666 mSettings.addPackageToCleanLPw(
1667 new PackageCleanItem(userId, packageName, andCode));
1670 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1671 startCleaningPackages();
1673 case POST_INSTALL: {
1674 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1676 PostInstallData data = mRunningInstalls.get(msg.arg1);
1677 final boolean didRestore = (msg.arg2 != 0);
1678 mRunningInstalls.delete(msg.arg1);
1681 InstallArgs args = data.args;
1682 PackageInstalledInfo parentRes = data.res;
1684 final boolean grantPermissions = (args.installFlags
1685 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1686 final boolean killApp = (args.installFlags
1687 & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1688 final boolean virtualPreload = ((args.installFlags
1689 & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
1690 final String[] grantedPermissions = args.installGrantPermissions;
1692 // Handle the parent package
1693 handlePackagePostInstall(parentRes, grantPermissions, killApp,
1694 virtualPreload, grantedPermissions, didRestore,
1695 args.installerPackageName, args.observer);
1697 // Handle the child packages
1698 final int childCount = (parentRes.addedChildPackages != null)
1699 ? parentRes.addedChildPackages.size() : 0;
1700 for (int i = 0; i < childCount; i++) {
1701 PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1702 handlePackagePostInstall(childRes, grantPermissions, killApp,
1703 virtualPreload, grantedPermissions, false /*didRestore*/,
1704 args.installerPackageName, args.observer);
1707 // Log tracing if needed
1708 if (args.traceMethod != null) {
1709 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1713 Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1716 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1718 case UPDATED_MEDIA_STATUS: {
1719 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1720 boolean reportStatus = msg.arg1 == 1;
1721 boolean doGc = msg.arg2 == 1;
1722 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1724 // Force a gc to clear up stale containers.
1725 Runtime.getRuntime().gc();
1727 if (msg.obj != null) {
1728 @SuppressWarnings("unchecked")
1729 Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1730 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1731 // Unload containers
1732 unloadAllContainers(args);
1736 if (DEBUG_SD_INSTALL) Log.i(TAG,
1737 "Invoking StorageManagerService call back");
1738 PackageHelper.getStorageManager().finishMediaUpdate();
1739 } catch (RemoteException e) {
1740 Log.e(TAG, "StorageManagerService not running?");
1744 case WRITE_SETTINGS: {
1745 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1746 synchronized (mPackages) {
1747 removeMessages(WRITE_SETTINGS);
1748 removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1749 mSettings.writeLPr();
1750 mDirtyUsers.clear();
1752 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1754 case WRITE_PACKAGE_RESTRICTIONS: {
1755 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1756 synchronized (mPackages) {
1757 removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1758 for (int userId : mDirtyUsers) {
1759 mSettings.writePackageRestrictionsLPr(userId);
1761 mDirtyUsers.clear();
1763 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1765 case WRITE_PACKAGE_LIST: {
1766 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1767 synchronized (mPackages) {
1768 removeMessages(WRITE_PACKAGE_LIST);
1769 mSettings.writePackageListLPr(msg.arg1);
1771 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1773 case CHECK_PENDING_VERIFICATION: {
1774 final int verificationId = msg.arg1;
1775 final PackageVerificationState state = mPendingVerification.get(verificationId);
1777 if ((state != null) && !state.timeoutExtended()) {
1778 final InstallArgs args = state.getInstallArgs();
1779 final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1781 Slog.i(TAG, "Verification timed out for " + originUri);
1782 mPendingVerification.remove(verificationId);
1784 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1786 final UserHandle user = args.getUser();
1787 if (getDefaultVerificationResponse(user)
1788 == PackageManager.VERIFICATION_ALLOW) {
1789 Slog.i(TAG, "Continuing with installation of " + originUri);
1790 state.setVerifierResponse(Binder.getCallingUid(),
1791 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1792 broadcastPackageVerified(verificationId, originUri,
1793 PackageManager.VERIFICATION_ALLOW, user);
1795 ret = args.copyApk(mContainerService, true);
1796 } catch (RemoteException e) {
1797 Slog.e(TAG, "Could not contact the ContainerService");
1800 broadcastPackageVerified(verificationId, originUri,
1801 PackageManager.VERIFICATION_REJECT, user);
1804 Trace.asyncTraceEnd(
1805 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1807 processPendingInstall(args, ret);
1808 mHandler.sendEmptyMessage(MCS_UNBIND);
1812 case PACKAGE_VERIFIED: {
1813 final int verificationId = msg.arg1;
1815 final PackageVerificationState state = mPendingVerification.get(verificationId);
1816 if (state == null) {
1817 Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1821 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1823 state.setVerifierResponse(response.callerUid, response.code);
1825 if (state.isVerificationComplete()) {
1826 mPendingVerification.remove(verificationId);
1828 final InstallArgs args = state.getInstallArgs();
1829 final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1832 if (state.isInstallAllowed()) {
1833 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1834 broadcastPackageVerified(verificationId, originUri,
1835 response.code, state.getInstallArgs().getUser());
1837 ret = args.copyApk(mContainerService, true);
1838 } catch (RemoteException e) {
1839 Slog.e(TAG, "Could not contact the ContainerService");
1842 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1845 Trace.asyncTraceEnd(
1846 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1848 processPendingInstall(args, ret);
1849 mHandler.sendEmptyMessage(MCS_UNBIND);
1854 case START_INTENT_FILTER_VERIFICATIONS: {
1855 IFVerificationParams params = (IFVerificationParams) msg.obj;
1856 verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1857 params.replacing, params.pkg);
1860 case INTENT_FILTER_VERIFIED: {
1861 final int verificationId = msg.arg1;
1863 final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1865 if (state == null) {
1866 Slog.w(TAG, "Invalid IntentFilter verification token "
1867 + verificationId + " received");
1871 final int userId = state.getUserId();
1873 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1874 "Processing IntentFilter verification with token:"
1875 + verificationId + " and userId:" + userId);
1877 final IntentFilterVerificationResponse response =
1878 (IntentFilterVerificationResponse) msg.obj;
1880 state.setVerifierResponse(response.callerUid, response.code);
1882 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1883 "IntentFilter verification with token:" + verificationId
1884 + " and userId:" + userId
1885 + " is settings verifier response with response code:"
1888 if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1889 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1890 + response.getFailedDomainsString());
1893 if (state.isVerificationComplete()) {
1894 mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1896 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1897 "IntentFilter verification with token:" + verificationId
1898 + " was not said to be complete");
1903 case INSTANT_APP_RESOLUTION_PHASE_TWO: {
1904 InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
1905 mInstantAppResolverConnection,
1906 (InstantAppRequest) msg.obj,
1907 mInstantAppInstallerActivity,
1914 private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1915 boolean killApp, boolean virtualPreload, String[] grantedPermissions,
1916 boolean launchedForRestore, String installerPackage,
1917 IPackageInstallObserver2 installObserver) {
1918 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1919 // Send the removed broadcasts
1920 if (res.removedInfo != null) {
1921 res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1924 // Now that we successfully installed the package, grant runtime
1925 // permissions if requested before broadcasting the install. Also
1926 // for legacy apps in permission review mode we clear the permission
1927 // review flag which is used to emulate runtime permissions for
1929 if (grantPermissions) {
1930 grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions);
1933 final boolean update = res.removedInfo != null
1934 && res.removedInfo.removedPackage != null;
1935 final String installerPackageName =
1936 res.installerPackageName != null
1937 ? res.installerPackageName
1938 : res.removedInfo != null
1939 ? res.removedInfo.installerPackageName
1942 // If this is the first time we have child packages for a disabled privileged
1943 // app that had no children, we grant requested runtime permissions to the new
1944 // children if the parent on the system image had them already granted.
1945 if (res.pkg.parentPackage != null) {
1946 synchronized (mPackages) {
1947 grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg);
1951 synchronized (mPackages) {
1952 mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
1955 final String packageName = res.pkg.applicationInfo.packageName;
1957 // Determine the set of users who are adding this package for
1958 // the first time vs. those who are seeing an update.
1959 int[] firstUsers = EMPTY_INT_ARRAY;
1960 int[] updateUsers = EMPTY_INT_ARRAY;
1961 final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
1962 final PackageSetting ps = (PackageSetting) res.pkg.mExtras;
1963 for (int newUser : res.newUsers) {
1964 if (ps.getInstantApp(newUser)) {
1968 firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1971 boolean isNew = true;
1972 for (int origUser : res.origUsers) {
1973 if (origUser == newUser) {
1979 firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1981 updateUsers = ArrayUtils.appendInt(updateUsers, newUser);
1985 // Send installed broadcasts if the package is not a static shared lib.
1986 if (res.pkg.staticSharedLibName == null) {
1987 mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
1989 // Send added for users that see the package for the first time
1990 // sendPackageAddedForNewUsers also deals with system apps
1991 int appId = UserHandle.getAppId(res.uid);
1992 boolean isSystem = res.pkg.applicationInfo.isSystemApp();
1993 sendPackageAddedForNewUsers(packageName, isSystem || virtualPreload,
1994 virtualPreload /*startReceiver*/, appId, firstUsers);
1996 // Send added for users that don't see the package for the first time
1997 Bundle extras = new Bundle(1);
1998 extras.putInt(Intent.EXTRA_UID, res.uid);
2000 extras.putBoolean(Intent.EXTRA_REPLACING, true);
2002 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2003 extras, 0 /*flags*/,
2004 null /*targetPackage*/, null /*finishedReceiver*/, updateUsers);
2005 if (installerPackageName != null) {
2006 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2007 extras, 0 /*flags*/,
2008 installerPackageName, null /*finishedReceiver*/, updateUsers);
2011 // Send replaced for users that don't see the package for the first time
2013 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
2014 packageName, extras, 0 /*flags*/,
2015 null /*targetPackage*/, null /*finishedReceiver*/,
2017 if (installerPackageName != null) {
2018 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
2019 extras, 0 /*flags*/,
2020 installerPackageName, null /*finishedReceiver*/, updateUsers);
2022 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
2023 null /*package*/, null /*extras*/, 0 /*flags*/,
2024 packageName /*targetPackage*/,
2025 null /*finishedReceiver*/, updateUsers);
2026 } else if (launchedForRestore && !isSystemApp(res.pkg)) {
2027 // First-install and we did a restore, so we're responsible for the
2028 // first-launch broadcast.
2030 Slog.i(TAG, "Post-restore of " + packageName
2031 + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers));
2033 sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers);
2036 // Send broadcast package appeared if forward locked/external for all users
2037 // treat asec-hosted packages like removable media on upgrade
2038 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
2039 if (DEBUG_INSTALL) {
2040 Slog.i(TAG, "upgrading pkg " + res.pkg
2041 + " is ASEC-hosted -> AVAILABLE");
2043 final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
2044 ArrayList<String> pkgList = new ArrayList<>(1);
2045 pkgList.add(packageName);
2046 sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
2050 // Work that needs to happen on first install within each user
2051 if (firstUsers != null && firstUsers.length > 0) {
2052 synchronized (mPackages) {
2053 for (int userId : firstUsers) {
2054 // If this app is a browser and it's newly-installed for some
2055 // users, clear any default-browser state in those users. The
2056 // app's nature doesn't depend on the user, so we can just check
2057 // its browser nature in any user and generalize.
2058 if (packageIsBrowser(packageName, userId)) {
2059 mSettings.setDefaultBrowserPackageNameLPw(null, userId);
2062 // We may also need to apply pending (restored) runtime
2063 // permission grants within these users.
2064 mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
2069 // Log current value of "unknown sources" setting
2070 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
2071 getUnknownSourcesSettings());
2073 // Remove the replaced package's older resources safely now
2074 // We delete after a gc for applications on sdcard.
2075 if (res.removedInfo != null && res.removedInfo.args != null) {
2076 Runtime.getRuntime().gc();
2077 synchronized (mInstallLock) {
2078 res.removedInfo.args.doPostDeleteLI(true);
2081 // Force a gc to clear up things. Ask for a background one, it's fine to go on
2082 // and not block here.
2083 VMRuntime.getRuntime().requestConcurrentGC();
2086 // Notify DexManager that the package was installed for new users.
2087 // The updated users should already be indexed and the package code paths
2088 // should not change.
2089 // Don't notify the manager for ephemeral apps as they are not expected to
2090 // survive long enough to benefit of background optimizations.
2091 for (int userId : firstUsers) {
2092 PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
2093 // There's a race currently where some install events may interleave with an uninstall.
2094 // This can lead to package info being null (b/36642664).
2096 mDexManager.notifyPackageInstalled(info, userId);
2101 // If someone is watching installs - notify them
2102 if (installObserver != null) {
2104 Bundle extras = extrasForInstallResult(res);
2105 installObserver.onPackageInstalled(res.name, res.returnCode,
2106 res.returnMsg, extras);
2107 } catch (RemoteException e) {
2108 Slog.i(TAG, "Observer no longer exists.");
2113 private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(
2114 PackageParser.Package pkg) {
2115 if (pkg.parentPackage == null) {
2118 if (pkg.requestedPermissions == null) {
2121 final PackageSetting disabledSysParentPs = mSettings
2122 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
2123 if (disabledSysParentPs == null || disabledSysParentPs.pkg == null
2124 || !disabledSysParentPs.isPrivileged()
2125 || (disabledSysParentPs.childPackageNames != null
2126 && !disabledSysParentPs.childPackageNames.isEmpty())) {
2129 final int[] allUserIds = sUserManager.getUserIds();
2130 final int permCount = pkg.requestedPermissions.size();
2131 for (int i = 0; i < permCount; i++) {
2132 String permission = pkg.requestedPermissions.get(i);
2133 BasePermission bp = mSettings.mPermissions.get(permission);
2134 if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
2137 for (int userId : allUserIds) {
2138 if (disabledSysParentPs.getPermissionsState().hasRuntimePermission(
2139 permission, userId)) {
2140 grantRuntimePermission(pkg.packageName, permission, userId);
2146 private StorageEventListener mStorageListener = new StorageEventListener() {
2148 public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
2149 if (vol.type == VolumeInfo.TYPE_PRIVATE) {
2150 if (vol.state == VolumeInfo.STATE_MOUNTED) {
2151 final String volumeUuid = vol.getFsUuid();
2153 // Clean up any users or apps that were removed or recreated
2154 // while this volume was missing
2155 sUserManager.reconcileUsers(volumeUuid);
2156 reconcileApps(volumeUuid);
2158 // Clean up any install sessions that expired or were
2159 // cancelled while this volume was missing
2160 mInstallerService.onPrivateVolumeMounted(volumeUuid);
2162 loadPrivatePackages(vol);
2164 } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2165 unloadPrivatePackages(vol);
2169 if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) {
2170 if (vol.state == VolumeInfo.STATE_MOUNTED) {
2171 updateExternalMediaStatus(true, false);
2172 } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2173 updateExternalMediaStatus(false, false);
2179 public void onVolumeForgotten(String fsUuid) {
2180 if (TextUtils.isEmpty(fsUuid)) {
2181 Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
2185 // Remove any apps installed on the forgotten volume
2186 synchronized (mPackages) {
2187 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
2188 for (PackageSetting ps : packages) {
2189 Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
2190 deletePackageVersioned(new VersionedPackage(ps.name,
2191 PackageManager.VERSION_CODE_HIGHEST),
2192 new LegacyPackageDeleteObserver(null).getBinder(),
2193 UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
2194 // Try very hard to release any references to this package
2195 // so we don't risk the system server being killed due to
2197 AttributeCache.instance().removePackage(ps.name);
2200 mSettings.onVolumeForgotten(fsUuid);
2201 mSettings.writeLPr();
2206 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
2207 String[] grantedPermissions) {
2208 for (int userId : userIds) {
2209 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions);
2213 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
2214 String[] grantedPermissions) {
2215 PackageSetting ps = (PackageSetting) pkg.mExtras;
2220 PermissionsState permissionsState = ps.getPermissionsState();
2222 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
2223 | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2225 final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
2226 >= Build.VERSION_CODES.M;
2228 final boolean instantApp = isInstantApp(pkg.packageName, userId);
2230 for (String permission : pkg.requestedPermissions) {
2231 final BasePermission bp;
2232 synchronized (mPackages) {
2233 bp = mSettings.mPermissions.get(permission);
2235 if (bp != null && (bp.isRuntime() || bp.isDevelopment())
2236 && (!instantApp || bp.isInstant())
2237 && (supportsRuntimePermissions || !bp.isRuntimeOnly())
2238 && (grantedPermissions == null
2239 || ArrayUtils.contains(grantedPermissions, permission))) {
2240 final int flags = permissionsState.getPermissionFlags(permission, userId);
2241 if (supportsRuntimePermissions) {
2242 // Installer cannot change immutable permissions.
2243 if ((flags & immutableFlags) == 0) {
2244 grantRuntimePermission(pkg.packageName, permission, userId);
2246 } else if (mPermissionReviewRequired) {
2247 // In permission review mode we clear the review flag when we
2248 // are asked to install the app with all permissions granted.
2249 if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2250 updatePermissionFlags(permission, pkg.packageName,
2251 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, userId);
2258 Bundle extrasForInstallResult(PackageInstalledInfo res) {
2259 Bundle extras = null;
2260 switch (res.returnCode) {
2261 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2262 extras = new Bundle();
2263 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2264 res.origPermission);
2265 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2269 case PackageManager.INSTALL_SUCCEEDED: {
2270 extras = new Bundle();
2271 extras.putBoolean(Intent.EXTRA_REPLACING,
2272 res.removedInfo != null && res.removedInfo.removedPackage != null);
2279 void scheduleWriteSettingsLocked() {
2280 if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2281 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2285 void scheduleWritePackageListLocked(int userId) {
2286 if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2287 Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2289 mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2293 void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2294 final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2295 scheduleWritePackageRestrictionsLocked(userId);
2298 void scheduleWritePackageRestrictionsLocked(int userId) {
2299 final int[] userIds = (userId == UserHandle.USER_ALL)
2300 ? sUserManager.getUserIds() : new int[]{userId};
2301 for (int nextUserId : userIds) {
2302 if (!sUserManager.exists(nextUserId)) return;
2303 mDirtyUsers.add(nextUserId);
2304 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2305 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2310 public static PackageManagerService main(Context context, Installer installer,
2311 boolean factoryTest, boolean onlyCore) {
2312 // Self-check for initial settings.
2313 PackageManagerServiceCompilerMapping.checkProperties();
2315 PackageManagerService m = new PackageManagerService(context, installer,
2316 factoryTest, onlyCore);
2317 m.enableSystemUserPackages();
2318 ServiceManager.addService("package", m);
2319 final PackageManagerNative pmn = m.new PackageManagerNative();
2320 ServiceManager.addService("package_native", pmn);
2324 private void enableSystemUserPackages() {
2325 if (!UserManager.isSplitSystemUser()) {
2328 // For system user, enable apps based on the following conditions:
2329 // - app is whitelisted or belong to one of these groups:
2330 // -- system app which has no launcher icons
2331 // -- system app which has INTERACT_ACROSS_USERS permission
2332 // -- system IME app
2333 // - app is not in the blacklist
2334 AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2335 Set<String> enableApps = new ArraySet<>();
2336 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2337 | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2338 | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2339 ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2340 enableApps.addAll(wlApps);
2341 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2342 /* systemAppsOnly */ false, UserHandle.SYSTEM));
2343 ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2344 enableApps.removeAll(blApps);
2345 Log.i(TAG, "Applications installed for system user: " + enableApps);
2346 List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2348 final int allAppsSize = allAps.size();
2349 synchronized (mPackages) {
2350 for (int i = 0; i < allAppsSize; i++) {
2351 String pName = allAps.get(i);
2352 PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2353 // Should not happen, but we shouldn't be failing if it does
2354 if (pkgSetting == null) {
2357 boolean install = enableApps.contains(pName);
2358 if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2359 Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2360 + " for system user");
2361 pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2364 scheduleWritePackageRestrictionsLocked(UserHandle.USER_SYSTEM);
2368 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2369 DisplayManager displayManager = (DisplayManager) context.getSystemService(
2370 Context.DISPLAY_SERVICE);
2371 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2375 * Requests that files preopted on a secondary system partition be copied to the data partition
2376 * if possible. Note that the actual copying of the files is accomplished by init for security
2377 * reasons. This simply requests that the copy takes place and awaits confirmation of its
2378 * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2380 private static void requestCopyPreoptedFiles() {
2381 final int WAIT_TIME_MS = 100;
2382 final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2383 if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2384 SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2385 // We will wait for up to 100 seconds.
2386 final long timeStart = SystemClock.uptimeMillis();
2387 final long timeEnd = timeStart + 100 * 1000;
2388 long timeNow = timeStart;
2389 while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2391 Thread.sleep(WAIT_TIME_MS);
2392 } catch (InterruptedException e) {
2395 timeNow = SystemClock.uptimeMillis();
2396 if (timeNow > timeEnd) {
2397 SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2398 Slog.wtf(TAG, "cppreopt did not finish!");
2403 Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2407 public PackageManagerService(Context context, Installer installer,
2408 boolean factoryTest, boolean onlyCore) {
2409 LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
2410 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
2411 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2412 SystemClock.uptimeMillis());
2414 if (mSdkVersion <= 0) {
2415 Slog.w(TAG, "**** ro.build.version.sdk not set!");
2420 mPermissionReviewRequired = context.getResources().getBoolean(
2421 R.bool.config_permissionReviewRequired);
2423 mFactoryTest = factoryTest;
2424 mOnlyCore = onlyCore;
2425 mMetrics = new DisplayMetrics();
2426 mSettings = new Settings(mPackages);
2427 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2428 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2429 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2430 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2431 mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2432 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2433 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2434 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2435 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2436 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2437 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2438 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2440 String separateProcesses = SystemProperties.get("debug.separate_processes");
2441 if (separateProcesses != null && separateProcesses.length() > 0) {
2442 if ("*".equals(separateProcesses)) {
2443 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2444 mSeparateProcesses = null;
2445 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2448 mSeparateProcesses = separateProcesses.split(",");
2449 Slog.w(TAG, "Running with debug.separate_processes: "
2450 + separateProcesses);
2454 mSeparateProcesses = null;
2457 mInstaller = installer;
2458 mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2460 mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock);
2461 mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2463 mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2464 FgThread.get().getLooper());
2466 getDefaultDisplayMetrics(context, mMetrics);
2468 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
2469 SystemConfig systemConfig = SystemConfig.getInstance();
2470 mGlobalGids = systemConfig.getGlobalGids();
2471 mSystemPermissions = systemConfig.getSystemPermissions();
2472 mAvailableFeatures = systemConfig.getAvailableFeatures();
2473 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2475 mProtectedPackages = new ProtectedPackages(mContext);
2477 synchronized (mInstallLock) {
2479 synchronized (mPackages) {
2480 mHandlerThread = new ServiceThread(TAG,
2481 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2482 mHandlerThread.start();
2483 mHandler = new PackageHandler(mHandlerThread.getLooper());
2484 mProcessLoggingHandler = new ProcessLoggingHandler();
2485 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2487 mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this);
2488 mInstantAppRegistry = new InstantAppRegistry(this);
2490 File dataDir = Environment.getDataDirectory();
2491 mAppInstallDir = new File(dataDir, "app");
2492 mAppLib32InstallDir = new File(dataDir, "app-lib");
2493 mAsecInternalPath = new File(dataDir, "app-asec").getPath();
2494 mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
2495 sUserManager = new UserManagerService(context, this,
2496 new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
2498 // Propagate permission configuration in to package manager.
2499 ArrayMap<String, SystemConfig.PermissionEntry> permConfig
2500 = systemConfig.getPermissions();
2501 for (int i=0; i<permConfig.size(); i++) {
2502 SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
2503 BasePermission bp = mSettings.mPermissions.get(perm.name);
2505 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
2506 mSettings.mPermissions.put(perm.name, bp);
2508 if (perm.gids != null) {
2509 bp.setGids(perm.gids, perm.perUser);
2513 ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2514 final int builtInLibCount = libConfig.size();
2515 for (int i = 0; i < builtInLibCount; i++) {
2516 String name = libConfig.keyAt(i);
2517 String path = libConfig.valueAt(i);
2518 addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
2519 SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
2522 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
2524 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
2525 mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2526 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2528 // Clean up orphaned packages for which the code path doesn't exist
2529 // and they are an update to a system app - caused by bug/32321269
2530 final int packageSettingCount = mSettings.mPackages.size();
2531 for (int i = packageSettingCount - 1; i >= 0; i--) {
2532 PackageSetting ps = mSettings.mPackages.valueAt(i);
2533 if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2534 && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2535 mSettings.mPackages.removeAt(i);
2536 mSettings.enableSystemPackageLPw(ps.name);
2541 requestCopyPreoptedFiles();
2544 String customResolverActivity = Resources.getSystem().getString(
2545 R.string.config_customResolverActivity);
2546 if (TextUtils.isEmpty(customResolverActivity)) {
2547 customResolverActivity = null;
2549 mCustomResolverComponentName = ComponentName.unflattenFromString(
2550 customResolverActivity);
2553 long startTime = SystemClock.uptimeMillis();
2555 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2558 final String bootClassPath = System.getenv("BOOTCLASSPATH");
2559 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2561 if (bootClassPath == null) {
2562 Slog.w(TAG, "No BOOTCLASSPATH found!");
2565 if (systemServerClassPath == null) {
2566 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2569 File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2571 final VersionInfo ver = mSettings.getInternalVersion();
2572 mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2574 logCriticalInfo(Log.INFO,
2575 "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
2578 // when upgrading from pre-M, promote system app permissions from install to runtime
2579 mPromoteSystemApps =
2580 mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2582 // When upgrading from pre-N, we need to handle package extraction like first boot,
2583 // as there is no profiling data available.
2584 mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2586 mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2588 // save off the names of pre-existing system packages prior to scanning; we don't
2589 // want to automatically grant runtime permissions for new system apps
2590 if (mPromoteSystemApps) {
2591 Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2592 while (pkgSettingIter.hasNext()) {
2593 PackageSetting ps = pkgSettingIter.next();
2594 if (isSystemApp(ps)) {
2595 mExistingSystemPackages.add(ps.name);
2600 mCacheDir = preparePackageParserCache(mIsUpgrade);
2602 // Set flag to monitor and not change apk file paths when
2603 // scanning install directories.
2604 int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2606 if (mIsUpgrade || mFirstBoot) {
2607 scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2610 // Collect vendor overlay packages. (Do this before scanning any apps.)
2611 // For security and version matching reason, only consider
2612 // overlay packages if they reside in the right directory.
2613 scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags
2614 | PackageParser.PARSE_IS_SYSTEM
2615 | PackageParser.PARSE_IS_SYSTEM_DIR
2616 | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2618 mParallelPackageParserCallback.findStaticOverlayPackages();
2620 // Find base frameworks (resource packages without code).
2621 scanDirTracedLI(frameworkDir, mDefParseFlags
2622 | PackageParser.PARSE_IS_SYSTEM
2623 | PackageParser.PARSE_IS_SYSTEM_DIR
2624 | PackageParser.PARSE_IS_PRIVILEGED,
2625 scanFlags | SCAN_NO_DEX, 0);
2627 // Collected privileged system packages.
2628 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2629 scanDirTracedLI(privilegedAppDir, mDefParseFlags
2630 | PackageParser.PARSE_IS_SYSTEM
2631 | PackageParser.PARSE_IS_SYSTEM_DIR
2632 | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
2634 // Collect ordinary system packages.
2635 final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2636 scanDirTracedLI(systemAppDir, mDefParseFlags
2637 | PackageParser.PARSE_IS_SYSTEM
2638 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2640 // Collect all vendor packages.
2641 File vendorAppDir = new File("/vendor/app");
2643 vendorAppDir = vendorAppDir.getCanonicalFile();
2644 } catch (IOException e) {
2645 // failed to look up canonical path, continue with original one
2647 scanDirTracedLI(vendorAppDir, mDefParseFlags
2648 | PackageParser.PARSE_IS_SYSTEM
2649 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2651 // Collect all OEM packages.
2652 final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2653 scanDirTracedLI(oemAppDir, mDefParseFlags
2654 | PackageParser.PARSE_IS_SYSTEM
2655 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2657 // Prune any system packages that no longer exist.
2658 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
2659 // Stub packages must either be replaced with full versions in the /data
2660 // partition or be disabled.
2661 final List<String> stubSystemApps = new ArrayList<>();
2663 // do this first before mucking with mPackages for the "expecting better" case
2664 final Iterator<PackageParser.Package> pkgIterator = mPackages.values().iterator();
2665 while (pkgIterator.hasNext()) {
2666 final PackageParser.Package pkg = pkgIterator.next();
2668 stubSystemApps.add(pkg.packageName);
2672 final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2673 while (psit.hasNext()) {
2674 PackageSetting ps = psit.next();
2677 * If this is not a system app, it can't be a
2678 * disable system app.
2680 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2685 * If the package is scanned, it's not erased.
2687 final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2688 if (scannedPkg != null) {
2690 * If the system app is both scanned and in the
2691 * disabled packages list, then it must have been
2692 * added via OTA. Remove it from the currently
2693 * scanned package so the previously user-installed
2694 * application can be scanned.
2696 if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2697 logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2698 + ps.name + "; removing system app. Last known codePath="
2699 + ps.codePathString + ", installStatus=" + ps.installStatus
2700 + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2701 + scannedPkg.mVersionCode);
2702 removePackageLI(scannedPkg, true);
2703 mExpectingBetter.put(ps.name, ps.codePath);
2709 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2711 logCriticalInfo(Log.WARN, "System package " + ps.name
2712 + " no longer exists; it's data will be wiped");
2713 // Actual deletion of code and data will be handled by later
2714 // reconciliation step
2716 // we still have a disabled system package, but, it still might have
2717 // been removed. check the code path still exists and check there's
2718 // still a package. the latter can happen if an OTA keeps the same
2719 // code path, but, changes the package name.
2720 final PackageSetting disabledPs =
2721 mSettings.getDisabledSystemPkgLPr(ps.name);
2722 if (disabledPs.codePath == null || !disabledPs.codePath.exists()
2723 || disabledPs.pkg == null) {
2724 possiblyDeletedUpdatedSystemApps.add(ps.name);
2730 //look for any incomplete package installations
2731 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2732 for (int i = 0; i < deletePkgsList.size(); i++) {
2733 // Actual deletion of code and data will be handled by later
2734 // reconciliation step
2735 final String packageName = deletePkgsList.get(i).name;
2736 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
2737 synchronized (mPackages) {
2738 mSettings.removePackageLPw(packageName);
2743 deleteTempPackageFiles();
2745 final int cachedSystemApps = PackageParser.sCachedPackageReadCount.get();
2747 // Remove any shared userIDs that have no associated packages
2748 mSettings.pruneSharedUsersLPw();
2749 final long systemScanTime = SystemClock.uptimeMillis() - startTime;
2750 final int systemPackagesCount = mPackages.size();
2751 Slog.i(TAG, "Finished scanning system apps. Time: " + systemScanTime
2752 + " ms, packageCount: " + systemPackagesCount
2753 + " , timePerPackage: "
2754 + (systemPackagesCount == 0 ? 0 : systemScanTime / systemPackagesCount)
2755 + " , cached: " + cachedSystemApps);
2756 if (mIsUpgrade && systemPackagesCount > 0) {
2757 MetricsLogger.histogram(null, "ota_package_manager_system_app_avg_scan_time",
2758 ((int) systemScanTime) / systemPackagesCount);
2761 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2762 SystemClock.uptimeMillis());
2763 scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2765 scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
2766 | PackageParser.PARSE_FORWARD_LOCK,
2767 scanFlags | SCAN_REQUIRE_KNOWN, 0);
2769 // Remove disable package settings for updated system apps that were
2770 // removed via an OTA. If the update is no longer present, remove the
2771 // app completely. Otherwise, revoke their system privileges.
2772 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2773 PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2774 mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2777 if (deletedPkg == null) {
2778 // should have found an update, but, we didn't; remove everything
2779 msg = "Updated system package " + deletedAppName
2780 + " no longer exists; removing its data";
2781 // Actual deletion of code and data will be handled by later
2782 // reconciliation step
2784 // found an update; revoke system privileges
2785 msg = "Updated system package + " + deletedAppName
2786 + " no longer exists; revoking system privileges";
2788 // Don't do anything if a stub is removed from the system image. If
2789 // we were to remove the uncompressed version from the /data partition,
2790 // this is where it'd be done.
2792 final PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2793 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2794 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2796 logCriticalInfo(Log.WARN, msg);
2800 * Make sure all system apps that we expected to appear on
2801 * the userdata partition actually showed up. If they never
2802 * appeared, crawl back and revive the system version.
2804 for (int i = 0; i < mExpectingBetter.size(); i++) {
2805 final String packageName = mExpectingBetter.keyAt(i);
2806 if (!mPackages.containsKey(packageName)) {
2807 final File scanFile = mExpectingBetter.valueAt(i);
2809 logCriticalInfo(Log.WARN, "Expected better " + packageName
2810 + " but never showed up; reverting to system");
2812 int reparseFlags = mDefParseFlags;
2813 if (FileUtils.contains(privilegedAppDir, scanFile)) {
2814 reparseFlags = PackageParser.PARSE_IS_SYSTEM
2815 | PackageParser.PARSE_IS_SYSTEM_DIR
2816 | PackageParser.PARSE_IS_PRIVILEGED;
2817 } else if (FileUtils.contains(systemAppDir, scanFile)) {
2818 reparseFlags = PackageParser.PARSE_IS_SYSTEM
2819 | PackageParser.PARSE_IS_SYSTEM_DIR;
2820 } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2821 reparseFlags = PackageParser.PARSE_IS_SYSTEM
2822 | PackageParser.PARSE_IS_SYSTEM_DIR;
2823 } else if (FileUtils.contains(oemAppDir, scanFile)) {
2824 reparseFlags = PackageParser.PARSE_IS_SYSTEM
2825 | PackageParser.PARSE_IS_SYSTEM_DIR;
2827 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2831 mSettings.enableSystemPackageLPw(packageName);
2834 scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
2835 } catch (PackageManagerException e) {
2836 Slog.e(TAG, "Failed to parse original system package: "
2842 // Uncompress and install any stubbed system applications.
2843 // This must be done last to ensure all stubs are replaced or disabled.
2844 decompressSystemApplications(stubSystemApps, scanFlags);
2846 final int cachedNonSystemApps = PackageParser.sCachedPackageReadCount.get()
2849 final long dataScanTime = SystemClock.uptimeMillis() - systemScanTime - startTime;
2850 final int dataPackagesCount = mPackages.size() - systemPackagesCount;
2851 Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime
2852 + " ms, packageCount: " + dataPackagesCount
2853 + " , timePerPackage: "
2854 + (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount)
2855 + " , cached: " + cachedNonSystemApps);
2856 if (mIsUpgrade && dataPackagesCount > 0) {
2857 MetricsLogger.histogram(null, "ota_package_manager_data_app_avg_scan_time",
2858 ((int) dataScanTime) / dataPackagesCount);
2861 mExpectingBetter.clear();
2863 // Resolve the storage manager.
2864 mStorageManagerPackage = getStorageManagerPackageName();
2866 // Resolve protected action filters. Only the setup wizard is allowed to
2867 // have a high priority filter for these actions.
2868 mSetupWizardPackage = getSetupWizardPackageName();
2869 if (mProtectedFilters.size() > 0) {
2870 if (DEBUG_FILTERS && mSetupWizardPackage == null) {
2871 Slog.i(TAG, "No setup wizard;"
2872 + " All protected intents capped to priority 0");
2874 for (ActivityIntentInfo filter : mProtectedFilters) {
2875 if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
2876 if (DEBUG_FILTERS) {
2877 Slog.i(TAG, "Found setup wizard;"
2878 + " allow priority " + filter.getPriority() + ";"
2879 + " package: " + filter.activity.info.packageName
2880 + " activity: " + filter.activity.className
2881 + " priority: " + filter.getPriority());
2883 // skip setup wizard; allow it to keep the high priority filter
2886 if (DEBUG_FILTERS) {
2887 Slog.i(TAG, "Protected action; cap priority to 0;"
2888 + " package: " + filter.activity.info.packageName
2889 + " activity: " + filter.activity.className
2890 + " origPrio: " + filter.getPriority());
2892 filter.setPriority(0);
2895 mDeferProtectedFilters = false;
2896 mProtectedFilters.clear();
2898 // Now that we know all of the shared libraries, update all clients to have
2899 // the correct library paths.
2900 updateAllSharedLibrariesLPw(null);
2902 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2903 // NOTE: We ignore potential failures here during a system scan (like
2904 // the rest of the commands above) because there's precious little we
2905 // can do about it. A settings error is reported, though.
2906 adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
2909 // Now that we know all the packages we are keeping,
2910 // read and update their last usage times.
2911 mPackageUsage.read(mPackages);
2912 mCompilerStats.read();
2914 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2915 SystemClock.uptimeMillis());
2916 Slog.i(TAG, "Time to scan packages: "
2917 + ((SystemClock.uptimeMillis()-startTime)/1000f)
2920 // If the platform SDK has changed since the last time we booted,
2921 // we need to re-grant app permission to catch any new ones that
2922 // appear. This is really a hack, and means that apps can in some
2923 // cases get permissions that the user didn't initially explicitly
2924 // allow... it would be nice to have some better way to handle
2926 int updateFlags = UPDATE_PERMISSIONS_ALL;
2927 if (ver.sdkVersion != mSdkVersion) {
2928 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2929 + mSdkVersion + "; regranting permissions for internal storage");
2930 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
2932 updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
2933 ver.sdkVersion = mSdkVersion;
2935 // If this is the first boot or an update from pre-M, and it is a normal
2936 // boot, then we need to initialize the default preferred apps across
2937 // all defined users.
2938 if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
2939 for (UserInfo user : sUserManager.getUsers(true)) {
2940 mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2941 applyFactoryDefaultBrowserLPw(user.id);
2942 primeDomainVerificationsLPw(user.id);
2946 // Prepare storage for system user really early during boot,
2947 // since core system apps like SettingsProvider and SystemUI
2948 // can't wait for user to start
2949 final int storageFlags;
2950 if (StorageManager.isFileEncryptedNativeOrEmulated()) {
2951 storageFlags = StorageManager.FLAG_STORAGE_DE;
2953 storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
2955 List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
2956 UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
2957 true /* onlyCoreApps */);
2958 mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
2959 TimingsTraceLog traceLog = new TimingsTraceLog("SystemServerTimingAsync",
2960 Trace.TRACE_TAG_PACKAGE_MANAGER);
2961 traceLog.traceBegin("AppDataFixup");
2963 mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
2964 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
2965 } catch (InstallerException e) {
2966 Slog.w(TAG, "Trouble fixing GIDs", e);
2968 traceLog.traceEnd();
2970 traceLog.traceBegin("AppDataPrepare");
2971 if (deferPackages == null || deferPackages.isEmpty()) {
2975 for (String pkgName : deferPackages) {
2976 PackageParser.Package pkg = null;
2977 synchronized (mPackages) {
2978 PackageSetting ps = mSettings.getPackageLPr(pkgName);
2979 if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
2984 synchronized (mInstallLock) {
2985 prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
2986 true /* maybeMigrateAppData */);
2991 traceLog.traceEnd();
2992 Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
2993 }, "prepareAppData");
2995 // If this is first boot after an OTA, and a normal boot, then
2996 // we need to clear code cache directories.
2997 // Note that we do *not* clear the application profiles. These remain valid
2998 // across OTAs and are used to drive profile verification (post OTA) and
2999 // profile compilation (without waiting to collect a fresh set of profiles).
3000 if (mIsUpgrade && !onlyCore) {
3001 Slog.i(TAG, "Build fingerprint changed; clearing code caches");
3002 for (int i = 0; i < mSettings.mPackages.size(); i++) {
3003 final PackageSetting ps = mSettings.mPackages.valueAt(i);
3004 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
3005 // No apps are running this early, so no need to freeze
3006 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
3007 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
3008 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
3011 ver.fingerprint = Build.FINGERPRINT;
3014 checkDefaultBrowser();
3016 // clear only after permissions and other defaults have been updated
3017 mExistingSystemPackages.clear();
3018 mPromoteSystemApps = false;
3020 // All the changes are done during package scanning.
3021 ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
3023 // can downgrade to reader
3024 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
3025 mSettings.writeLPr();
3026 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3027 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
3028 SystemClock.uptimeMillis());
3031 mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
3032 mRequiredInstallerPackage = getRequiredInstallerLPr();
3033 mRequiredUninstallerPackage = getRequiredUninstallerLPr();
3034 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
3035 if (mIntentFilterVerifierComponent != null) {
3036 mIntentFilterVerifier = new IntentVerifierProxy(mContext,
3037 mIntentFilterVerifierComponent);
3039 mIntentFilterVerifier = null;
3041 mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3042 PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
3043 SharedLibraryInfo.VERSION_UNDEFINED);
3044 mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3045 PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
3046 SharedLibraryInfo.VERSION_UNDEFINED);
3048 mRequiredVerifierPackage = null;
3049 mRequiredInstallerPackage = null;
3050 mRequiredUninstallerPackage = null;
3051 mIntentFilterVerifierComponent = null;
3052 mIntentFilterVerifier = null;
3053 mServicesSystemSharedLibraryPackageName = null;
3054 mSharedSystemSharedLibraryPackageName = null;
3057 mInstallerService = new PackageInstallerService(context, this);
3058 final Pair<ComponentName, String> instantAppResolverComponent =
3059 getInstantAppResolverLPr();
3060 if (instantAppResolverComponent != null) {
3061 if (DEBUG_EPHEMERAL) {
3062 Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
3064 mInstantAppResolverConnection = new EphemeralResolverConnection(
3065 mContext, instantAppResolverComponent.first,
3066 instantAppResolverComponent.second);
3067 mInstantAppResolverSettingsComponent =
3068 getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
3070 mInstantAppResolverConnection = null;
3071 mInstantAppResolverSettingsComponent = null;
3073 updateInstantAppInstallerLocked(null);
3075 // Read and update the usage of dex files.
3076 // Do this at the end of PM init so that all the packages have their
3077 // data directory reconciled.
3078 // At this point we know the code paths of the packages, so we can validate
3079 // the disk file and build the internal cache.
3080 // The usage file is expected to be small so loading and verifying it
3081 // should take a fairly small time compare to the other activities (e.g. package
3083 final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
3084 final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
3085 for (int userId : currentUserIds) {
3086 userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
3088 mDexManager.load(userPackages);
3090 MetricsLogger.histogram(null, "ota_package_manager_init_time",
3091 (int) (SystemClock.uptimeMillis() - startTime));
3093 } // synchronized (mPackages)
3094 } // synchronized (mInstallLock)
3096 // Now after opening every single application zip, make sure they
3097 // are all flushed. Not really needed, but keeps things nice and
3099 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
3100 Runtime.getRuntime().gc();
3101 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3103 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
3104 FallbackCategoryProvider.loadFallbacks();
3105 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3107 // The initial scanning above does many calls into installd while
3108 // holding the mPackages lock, but we're mostly interested in yelling
3109 // once we have a booted system.
3110 mInstaller.setWarnIfHeld(mPackages);
3112 // Expose private service for system components to use.
3113 LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
3114 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3118 * Uncompress and install stub applications.
3119 * <p>In order to save space on the system partition, some applications are shipped in a
3120 * compressed form. In addition the compressed bits for the full application, the
3121 * system image contains a tiny stub comprised of only the Android manifest.
3122 * <p>During the first boot, attempt to uncompress and install the full application. If
3123 * the application can't be installed for any reason, disable the stub and prevent
3124 * uncompressing the full application during future boots.
3125 * <p>In order to forcefully attempt an installation of a full application, go to app
3126 * settings and enable the application.
3128 private void decompressSystemApplications(@NonNull List<String> stubSystemApps, int scanFlags) {
3129 for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3130 final String pkgName = stubSystemApps.get(i);
3131 // skip if the system package is already disabled
3132 if (mSettings.isDisabledSystemPackageLPr(pkgName)) {
3133 stubSystemApps.remove(i);
3136 // skip if the package isn't installed (?!); this should never happen
3137 final PackageParser.Package pkg = mPackages.get(pkgName);
3139 stubSystemApps.remove(i);
3142 // skip if the package has been disabled by the user
3143 final PackageSetting ps = mSettings.mPackages.get(pkgName);
3145 final int enabledState = ps.getEnabled(UserHandle.USER_SYSTEM);
3146 if (enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
3147 stubSystemApps.remove(i);
3152 if (DEBUG_COMPRESSION) {
3153 Slog.i(TAG, "Uncompressing system stub; pkg: " + pkgName);
3156 // uncompress the binary to its eventual destination on /data
3157 final File scanFile = decompressPackage(pkg);
3158 if (scanFile == null) {
3162 // install the package to replace the stub on /system
3164 mSettings.disableSystemPackageLPw(pkgName, true /*replaced*/);
3165 removePackageLI(pkg, true /*chatty*/);
3166 scanPackageTracedLI(scanFile, 0 /*reparseFlags*/, scanFlags, 0, null);
3167 ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
3168 UserHandle.USER_SYSTEM, "android");
3169 stubSystemApps.remove(i);
3171 } catch (PackageManagerException e) {
3172 Slog.e(TAG, "Failed to parse uncompressed system package: " + e.getMessage());
3175 // any failed attempt to install the package will be cleaned up later
3178 // disable any stub still left; these failed to install the full application
3179 for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3180 final String pkgName = stubSystemApps.get(i);
3181 final PackageSetting ps = mSettings.mPackages.get(pkgName);
3182 ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
3183 UserHandle.USER_SYSTEM, "android");
3184 logCriticalInfo(Log.ERROR, "Stub disabled; pkg: " + pkgName);
3188 private int decompressFile(File srcFile, File dstFile) throws ErrnoException {
3189 if (DEBUG_COMPRESSION) {
3190 Slog.i(TAG, "Decompress file"
3191 + "; src: " + srcFile.getAbsolutePath()
3192 + ", dst: " + dstFile.getAbsolutePath());
3195 InputStream fileIn = new GZIPInputStream(new FileInputStream(srcFile));
3196 OutputStream fileOut = new FileOutputStream(dstFile, false /*append*/);
3198 Streams.copy(fileIn, fileOut);
3199 Os.chmod(dstFile.getAbsolutePath(), 0644);
3200 return PackageManager.INSTALL_SUCCEEDED;
3201 } catch (IOException e) {
3202 logCriticalInfo(Log.ERROR, "Failed to decompress file"
3203 + "; src: " + srcFile.getAbsolutePath()
3204 + ", dst: " + dstFile.getAbsolutePath());
3206 return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
3209 private File[] getCompressedFiles(String codePath) {
3210 final File stubCodePath = new File(codePath);
3211 final String stubName = stubCodePath.getName();
3213 // The layout of a compressed package on a given partition is as follows :
3215 // Compressed artifacts:
3217 // /partition/ModuleName/foo.gz
3218 // /partation/ModuleName/bar.gz
3222 // /partition/ModuleName-Stub/ModuleName-Stub.apk
3224 // In other words, stub is on the same partition as the compressed artifacts
3225 // and in a directory that's suffixed with "-Stub".
3226 int idx = stubName.lastIndexOf(STUB_SUFFIX);
3227 if (idx < 0 || (stubName.length() != (idx + STUB_SUFFIX.length()))) {
3231 final File stubParentDir = stubCodePath.getParentFile();
3232 if (stubParentDir == null) {
3233 Slog.e(TAG, "Unable to determine stub parent dir for codePath: " + codePath);
3237 final File compressedPath = new File(stubParentDir, stubName.substring(0, idx));
3238 final File[] files = compressedPath.listFiles(new FilenameFilter() {
3240 public boolean accept(File dir, String name) {
3241 return name.toLowerCase().endsWith(COMPRESSED_EXTENSION);
3245 if (DEBUG_COMPRESSION && files != null && files.length > 0) {
3246 Slog.i(TAG, "getCompressedFiles[" + codePath + "]: " + Arrays.toString(files));
3252 private boolean compressedFileExists(String codePath) {
3253 final File[] compressedFiles = getCompressedFiles(codePath);
3254 return compressedFiles != null && compressedFiles.length > 0;
3258 * Decompresses the given package on the system image onto
3259 * the /data partition.
3260 * @return The directory the package was decompressed into. Otherwise, {@code null}.
3262 private File decompressPackage(PackageParser.Package pkg) {
3263 final File[] compressedFiles = getCompressedFiles(pkg.codePath);
3264 if (compressedFiles == null || compressedFiles.length == 0) {
3265 if (DEBUG_COMPRESSION) {
3266 Slog.i(TAG, "No files to decompress: " + pkg.baseCodePath);
3270 final File dstCodePath =
3271 getNextCodePath(Environment.getDataAppDirectory(null), pkg.packageName);
3272 int ret = PackageManager.INSTALL_SUCCEEDED;
3274 Os.mkdir(dstCodePath.getAbsolutePath(), 0755);
3275 Os.chmod(dstCodePath.getAbsolutePath(), 0755);
3276 for (File srcFile : compressedFiles) {
3277 final String srcFileName = srcFile.getName();
3278 final String dstFileName = srcFileName.substring(
3279 0, srcFileName.length() - COMPRESSED_EXTENSION.length());
3280 final File dstFile = new File(dstCodePath, dstFileName);
3281 ret = decompressFile(srcFile, dstFile);
3282 if (ret != PackageManager.INSTALL_SUCCEEDED) {
3283 logCriticalInfo(Log.ERROR, "Failed to decompress"
3284 + "; pkg: " + pkg.packageName
3285 + ", file: " + dstFileName);
3289 } catch (ErrnoException e) {
3290 logCriticalInfo(Log.ERROR, "Failed to decompress"
3291 + "; pkg: " + pkg.packageName
3292 + ", err: " + e.errno);
3294 if (ret == PackageManager.INSTALL_SUCCEEDED) {
3295 final File libraryRoot = new File(dstCodePath, LIB_DIR_NAME);
3296 NativeLibraryHelper.Handle handle = null;
3298 handle = NativeLibraryHelper.Handle.create(dstCodePath);
3299 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
3300 null /*abiOverride*/);
3301 } catch (IOException e) {
3302 logCriticalInfo(Log.ERROR, "Failed to extract native libraries"
3303 + "; pkg: " + pkg.packageName);
3304 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
3306 IoUtils.closeQuietly(handle);
3309 if (ret != PackageManager.INSTALL_SUCCEEDED) {
3310 if (dstCodePath == null || !dstCodePath.exists()) {
3313 removeCodePathLI(dstCodePath);
3320 private void updateInstantAppInstallerLocked(String modifiedPackage) {
3321 // we're only interested in updating the installer appliction when 1) it's not
3322 // already set or 2) the modified package is the installer
3323 if (mInstantAppInstallerActivity != null
3324 && !mInstantAppInstallerActivity.getComponentName().getPackageName()
3325 .equals(modifiedPackage)) {
3328 setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
3331 private static File preparePackageParserCache(boolean isUpgrade) {
3332 if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
3336 // Disable package parsing on eng builds to allow for faster incremental development.
3341 if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
3342 Slog.i(TAG, "Disabling package parser cache due to system property.");
3346 // The base directory for the package parser cache lives under /data/system/.
3347 final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(),
3349 if (cacheBaseDir == null) {
3353 // If this is a system upgrade scenario, delete the contents of the package cache dir.
3354 // This also serves to "GC" unused entries when the package cache version changes (which
3355 // can only happen during upgrades).
3357 FileUtils.deleteContents(cacheBaseDir);
3361 // Return the versioned package cache directory. This is something like
3362 // "/data/system/package_cache/1"
3363 File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3365 // The following is a workaround to aid development on non-numbered userdebug
3366 // builds or cases where "adb sync" is used on userdebug builds. If we detect that
3367 // the system partition is newer.
3369 // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
3370 // that starts with "eng." to signify that this is an engineering build and not
3371 // destined for release.
3372 if (Build.IS_USERDEBUG && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
3373 Slog.w(TAG, "Wiping cache directory because the system partition changed.");
3375 // Heuristic: If the /system directory has been modified recently due to an "adb sync"
3376 // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
3377 // in general and should not be used for production changes. In this specific case,
3378 // we know that they will work.
3379 File frameworkDir = new File(Environment.getRootDirectory(), "framework");
3380 if (cacheDir.lastModified() < frameworkDir.lastModified()) {
3381 FileUtils.deleteContents(cacheBaseDir);
3382 cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3390 public boolean isFirstBoot() {
3391 // allow instant applications
3396 public boolean isOnlyCoreApps() {
3397 // allow instant applications
3402 public boolean isUpgrade() {
3403 // allow instant applications
3407 private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
3408 final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
3410 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3411 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3412 UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3413 if (matches.size() == 1) {
3414 return matches.get(0).getComponentInfo().packageName;
3415 } else if (matches.size() == 0) {
3416 Log.e(TAG, "There should probably be a verifier, but, none were found");
3419 throw new RuntimeException("There must be exactly one verifier; found " + matches);
3422 private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
3423 synchronized (mPackages) {
3424 SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version);
3425 if (libraryEntry == null) {
3426 throw new IllegalStateException("Missing required shared library:" + name);
3428 return libraryEntry.apk;
3432 private @NonNull String getRequiredInstallerLPr() {
3433 final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
3434 intent.addCategory(Intent.CATEGORY_DEFAULT);
3435 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3437 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3438 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3439 UserHandle.USER_SYSTEM);
3440 if (matches.size() == 1) {
3441 ResolveInfo resolveInfo = matches.get(0);
3442 if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3443 throw new RuntimeException("The installer must be a privileged app");
3445 return matches.get(0).getComponentInfo().packageName;
3447 throw new RuntimeException("There must be exactly one installer; found " + matches);
3451 private @NonNull String getRequiredUninstallerLPr() {
3452 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
3453 intent.addCategory(Intent.CATEGORY_DEFAULT);
3454 intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
3456 final ResolveInfo resolveInfo = resolveIntent(intent, null,
3457 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3458 UserHandle.USER_SYSTEM);
3459 if (resolveInfo == null ||
3460 mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
3461 throw new RuntimeException("There must be exactly one uninstaller; found "
3464 return resolveInfo.getComponentInfo().packageName;
3467 private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3468 final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3470 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3471 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3472 UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3473 ResolveInfo best = null;
3474 final int N = matches.size();
3475 for (int i = 0; i < N; i++) {
3476 final ResolveInfo cur = matches.get(i);
3477 final String packageName = cur.getComponentInfo().packageName;
3478 if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3479 packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3483 if (best == null || cur.priority > best.priority) {
3489 return best.getComponentInfo().getComponentName();
3491 Slog.w(TAG, "Intent filter verifier not found");
3496 public @Nullable ComponentName getInstantAppResolverComponent() {
3497 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3500 synchronized (mPackages) {
3501 final Pair<ComponentName, String> instantAppResolver = getInstantAppResolverLPr();
3502 if (instantAppResolver == null) {
3505 return instantAppResolver.first;
3509 private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
3510 final String[] packageArray =
3511 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3512 if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3513 if (DEBUG_EPHEMERAL) {
3514 Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3519 final int callingUid = Binder.getCallingUid();
3520 final int resolveFlags =
3521 MATCH_DIRECT_BOOT_AWARE
3522 | MATCH_DIRECT_BOOT_UNAWARE
3523 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3524 String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
3525 final Intent resolverIntent = new Intent(actionName);
3526 List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3527 resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3528 // temporarily look for the old action
3529 if (resolvers.size() == 0) {
3530 if (DEBUG_EPHEMERAL) {
3531 Slog.d(TAG, "Ephemeral resolver not found with new action; try old one");
3533 actionName = Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE;
3534 resolverIntent.setAction(actionName);
3535 resolvers = queryIntentServicesInternal(resolverIntent, null,
3536 resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3538 final int N = resolvers.size();
3540 if (DEBUG_EPHEMERAL) {
3541 Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3546 final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3547 for (int i = 0; i < N; i++) {
3548 final ResolveInfo info = resolvers.get(i);
3550 if (info.serviceInfo == null) {
3554 final String packageName = info.serviceInfo.packageName;
3555 if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3556 if (DEBUG_EPHEMERAL) {
3557 Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3558 + " pkg: " + packageName + ", info:" + info);
3563 if (DEBUG_EPHEMERAL) {
3564 Slog.v(TAG, "Ephemeral resolver found;"
3565 + " pkg: " + packageName + ", info:" + info);
3567 return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
3569 if (DEBUG_EPHEMERAL) {
3570 Slog.v(TAG, "Ephemeral resolver NOT found");
3575 private @Nullable ActivityInfo getInstantAppInstallerLPr() {
3576 final Intent intent = new Intent(Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE);
3577 intent.addCategory(Intent.CATEGORY_DEFAULT);
3578 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3580 final int resolveFlags =
3581 MATCH_DIRECT_BOOT_AWARE
3582 | MATCH_DIRECT_BOOT_UNAWARE
3583 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3584 List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3585 resolveFlags, UserHandle.USER_SYSTEM);
3586 // temporarily look for the old action
3587 if (matches.isEmpty()) {
3588 if (DEBUG_EPHEMERAL) {
3589 Slog.d(TAG, "Ephemeral installer not found with new action; try old one");
3591 intent.setAction(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
3592 matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3593 resolveFlags, UserHandle.USER_SYSTEM);
3595 Iterator<ResolveInfo> iter = matches.iterator();
3596 while (iter.hasNext()) {
3597 final ResolveInfo rInfo = iter.next();
3598 final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3600 final PermissionsState permissionsState = ps.getPermissionsState();
3601 if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)) {
3607 if (matches.size() == 0) {
3609 } else if (matches.size() == 1) {
3610 return (ActivityInfo) matches.get(0).getComponentInfo();
3612 throw new RuntimeException(
3613 "There must be at most one ephemeral installer; found " + matches);
3617 private @Nullable ComponentName getInstantAppResolverSettingsLPr(
3618 @NonNull ComponentName resolver) {
3619 final Intent intent = new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
3620 .addCategory(Intent.CATEGORY_DEFAULT)
3621 .setPackage(resolver.getPackageName());
3622 final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3623 List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3624 UserHandle.USER_SYSTEM);
3625 // temporarily look for the old action
3626 if (matches.isEmpty()) {
3627 if (DEBUG_EPHEMERAL) {
3628 Slog.d(TAG, "Ephemeral resolver settings not found with new action; try old one");
3630 intent.setAction(Intent.ACTION_EPHEMERAL_RESOLVER_SETTINGS);
3631 matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3632 UserHandle.USER_SYSTEM);
3634 if (matches.isEmpty()) {
3637 return matches.get(0).getComponentInfo().getComponentName();
3640 private void primeDomainVerificationsLPw(int userId) {
3641 if (DEBUG_DOMAIN_VERIFICATION) {
3642 Slog.d(TAG, "Priming domain verifications in user " + userId);
3645 SystemConfig systemConfig = SystemConfig.getInstance();
3646 ArraySet<String> packages = systemConfig.getLinkedApps();
3648 for (String packageName : packages) {
3649 PackageParser.Package pkg = mPackages.get(packageName);
3651 if (!pkg.isSystemApp()) {
3652 Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
3656 ArraySet<String> domains = null;
3657 for (PackageParser.Activity a : pkg.activities) {
3658 for (ActivityIntentInfo filter : a.intents) {
3659 if (hasValidDomains(filter)) {
3660 if (domains == null) {
3661 domains = new ArraySet<String>();
3663 domains.addAll(filter.getHostsList());
3668 if (domains != null && domains.size() > 0) {
3669 if (DEBUG_DOMAIN_VERIFICATION) {
3670 Slog.v(TAG, " + " + packageName);
3672 // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
3673 // state w.r.t. the formal app-linkage "no verification attempted" state;
3674 // and then 'always' in the per-user state actually used for intent resolution.
3675 final IntentFilterVerificationInfo ivi;
3676 ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
3677 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
3678 mSettings.updateIntentFilterVerificationStatusLPw(packageName,
3679 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
3681 Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
3682 + "' does not handle web links");
3685 Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
3689 scheduleWritePackageRestrictionsLocked(userId);
3690 scheduleWriteSettingsLocked();
3693 private void applyFactoryDefaultBrowserLPw(int userId) {
3694 // The default browser app's package name is stored in a string resource,
3695 // with a product-specific overlay used for vendor customization.
3696 String browserPkg = mContext.getResources().getString(
3697 com.android.internal.R.string.default_browser);
3698 if (!TextUtils.isEmpty(browserPkg)) {
3699 // non-empty string => required to be a known package
3700 PackageSetting ps = mSettings.mPackages.get(browserPkg);
3702 Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
3705 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3709 // Nothing valid explicitly set? Make the factory-installed browser the explicit
3710 // default. If there's more than one, just leave everything alone.
3711 if (browserPkg == null) {
3712 calculateDefaultBrowserLPw(userId);
3716 private void calculateDefaultBrowserLPw(int userId) {
3717 List<String> allBrowsers = resolveAllBrowserApps(userId);
3718 final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
3719 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3722 private List<String> resolveAllBrowserApps(int userId) {
3723 // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
3724 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3725 PackageManager.MATCH_ALL, userId);
3727 final int count = list.size();
3728 List<String> result = new ArrayList<String>(count);
3729 for (int i=0; i<count; i++) {
3730 ResolveInfo info = list.get(i);
3731 if (info.activityInfo == null
3732 || !info.handleAllWebDataURI
3733 || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
3734 || result.contains(info.activityInfo.packageName)) {
3737 result.add(info.activityInfo.packageName);
3743 private boolean packageIsBrowser(String packageName, int userId) {
3744 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3745 PackageManager.MATCH_ALL, userId);
3746 final int N = list.size();
3747 for (int i = 0; i < N; i++) {
3748 ResolveInfo info = list.get(i);
3749 if (packageName.equals(info.activityInfo.packageName)) {
3756 private void checkDefaultBrowser() {
3757 final int myUserId = UserHandle.myUserId();
3758 final String packageName = getDefaultBrowserPackageName(myUserId);
3759 if (packageName != null) {
3760 PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3762 Slog.w(TAG, "Default browser no longer installed: " + packageName);
3763 synchronized (mPackages) {
3764 applyFactoryDefaultBrowserLPw(myUserId); // leaves ambiguous when > 1
3771 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3772 throws RemoteException {
3774 return super.onTransact(code, data, reply, flags);
3775 } catch (RuntimeException e) {
3776 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3777 Slog.wtf(TAG, "Package Manager Crash", e);
3783 static int[] appendInts(int[] cur, int[] add) {
3784 if (add == null) return cur;
3785 if (cur == null) return add;
3786 final int N = add.length;
3787 for (int i=0; i<N; i++) {
3788 cur = appendInt(cur, add[i]);
3794 * Returns whether or not a full application can see an instant application.
3796 * Currently, there are three cases in which this can occur:
3798 * <li>The calling application is a "special" process. Special processes
3799 * are those with a UID < {@link Process#FIRST_APPLICATION_UID}.</li>
3800 * <li>The calling application has the permission
3801 * {@link android.Manifest.permission#ACCESS_INSTANT_APPS}.</li>
3802 * <li>The calling application is the default launcher on the
3803 * system partition.</li>
3806 private boolean canViewInstantApps(int callingUid, int userId) {
3807 if (callingUid < Process.FIRST_APPLICATION_UID) {
3810 if (mContext.checkCallingOrSelfPermission(
3811 android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED) {
3814 if (mContext.checkCallingOrSelfPermission(
3815 android.Manifest.permission.VIEW_INSTANT_APPS) == PERMISSION_GRANTED) {
3816 final ComponentName homeComponent = getDefaultHomeActivity(userId);
3817 if (homeComponent != null
3818 && isCallerSameApp(homeComponent.getPackageName(), callingUid)) {
3825 private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3826 if (!sUserManager.exists(userId)) return null;
3830 PackageParser.Package p = ps.pkg;
3834 final int callingUid = Binder.getCallingUid();
3835 // Filter out ephemeral app metadata:
3836 // * The system/shell/root can see metadata for any app
3837 // * An installed app can see metadata for 1) other installed apps
3838 // and 2) ephemeral apps that have explicitly interacted with it
3839 // * Ephemeral apps can only see their own data and exposed installed apps
3840 // * Holding a signature permission allows seeing instant apps
3841 if (filterAppAccessLPr(ps, callingUid, userId)) {
3845 final PermissionsState permissionsState = ps.getPermissionsState();
3847 // Compute GIDs only if requested
3848 final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3849 ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3850 // Compute granted permissions only if package has requested permissions
3851 final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3852 ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3853 final PackageUserState state = ps.readUserState(userId);
3855 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
3857 flags |= MATCH_ANY_USER;
3860 PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags,
3861 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3863 if (packageInfo == null) {
3867 packageInfo.packageName = packageInfo.applicationInfo.packageName =
3868 resolveExternalPackageNameLPr(p);
3874 public void checkPackageStartable(String packageName, int userId) {
3875 final int callingUid = Binder.getCallingUid();
3876 if (getInstantAppPackageName(callingUid) != null) {
3877 throw new SecurityException("Instant applications don't have access to this method");
3879 final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3880 synchronized (mPackages) {
3881 final PackageSetting ps = mSettings.mPackages.get(packageName);
3882 if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
3883 throw new SecurityException("Package " + packageName + " was not found!");
3886 if (!ps.getInstalled(userId)) {
3887 throw new SecurityException(
3888 "Package " + packageName + " was not installed for user " + userId + "!");
3891 if (mSafeMode && !ps.isSystem()) {
3892 throw new SecurityException("Package " + packageName + " not a system app!");
3895 if (mFrozenPackages.contains(packageName)) {
3896 throw new SecurityException("Package " + packageName + " is currently frozen!");
3899 if (!userKeyUnlocked && !ps.pkg.applicationInfo.isEncryptionAware()) {
3900 throw new SecurityException("Package " + packageName + " is not encryption aware!");
3906 public boolean isPackageAvailable(String packageName, int userId) {
3907 if (!sUserManager.exists(userId)) return false;
3908 final int callingUid = Binder.getCallingUid();
3909 enforceCrossUserPermission(callingUid, userId,
3910 false /*requireFullPermission*/, false /*checkShell*/, "is package available");
3911 synchronized (mPackages) {
3912 PackageParser.Package p = mPackages.get(packageName);
3914 final PackageSetting ps = (PackageSetting) p.mExtras;
3915 if (filterAppAccessLPr(ps, callingUid, userId)) {
3919 final PackageUserState state = ps.readUserState(userId);
3920 if (state != null) {
3921 return PackageParser.isAvailable(state);
3930 public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3931 return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
3932 flags, Binder.getCallingUid(), userId);
3936 public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
3937 int flags, int userId) {
3938 return getPackageInfoInternal(versionedPackage.getPackageName(),
3939 versionedPackage.getVersionCode(), flags, Binder.getCallingUid(), userId);
3943 * Important: The provided filterCallingUid is used exclusively to filter out packages
3944 * that can be seen based on user state. It's typically the original caller uid prior
3945 * to clearing. Because it can only be provided by trusted code, it's value can be
3946 * trusted and will be used as-is; unlike userId which will be validated by this method.
3948 private PackageInfo getPackageInfoInternal(String packageName, int versionCode,
3949 int flags, int filterCallingUid, int userId) {
3950 if (!sUserManager.exists(userId)) return null;
3951 flags = updateFlagsForPackage(flags, userId, packageName);
3952 enforceCrossUserPermission(Binder.getCallingUid(), userId,
3953 false /* requireFullPermission */, false /* checkShell */, "get package info");
3956 synchronized (mPackages) {
3957 // Normalize package name to handle renamed packages and static libs
3958 packageName = resolveInternalPackageNameLPr(packageName, versionCode);
3960 final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
3961 if (matchFactoryOnly) {
3962 final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
3964 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3967 if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
3970 return generatePackageInfo(ps, flags, userId);
3974 PackageParser.Package p = mPackages.get(packageName);
3975 if (matchFactoryOnly && p != null && !isSystemApp(p)) {
3978 if (DEBUG_PACKAGE_INFO)
3979 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
3981 final PackageSetting ps = (PackageSetting) p.mExtras;
3982 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3985 if (ps != null && filterAppAccessLPr(ps, filterCallingUid, userId)) {
3988 return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
3990 if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
3991 final PackageSetting ps = mSettings.mPackages.get(packageName);
3992 if (ps == null) return null;
3993 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3996 if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
3999 return generatePackageInfo(ps, flags, userId);
4005 private boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
4006 if (isComponentVisibleToInstantApp(component, TYPE_ACTIVITY)) {
4009 if (isComponentVisibleToInstantApp(component, TYPE_SERVICE)) {
4012 if (isComponentVisibleToInstantApp(component, TYPE_PROVIDER)) {
4018 private boolean isComponentVisibleToInstantApp(
4019 @Nullable ComponentName component, @ComponentType int type) {
4020 if (type == TYPE_ACTIVITY) {
4021 final PackageParser.Activity activity = mActivities.mActivities.get(component);
4022 return activity != null
4023 ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4025 } else if (type == TYPE_RECEIVER) {
4026 final PackageParser.Activity activity = mReceivers.mActivities.get(component);
4027 return activity != null
4028 ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4030 } else if (type == TYPE_SERVICE) {
4031 final PackageParser.Service service = mServices.mServices.get(component);
4032 return service != null
4033 ? (service.info.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4035 } else if (type == TYPE_PROVIDER) {
4036 final PackageParser.Provider provider = mProviders.mProviders.get(component);
4037 return provider != null
4038 ? (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4040 } else if (type == TYPE_UNKNOWN) {
4041 return isComponentVisibleToInstantApp(component);
4047 * Returns whether or not access to the application should be filtered.
4049 * Access may be limited based upon whether the calling or target applications
4050 * are instant applications.
4052 * @see #canAccessInstantApps(int)
4054 private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid,
4055 @Nullable ComponentName component, @ComponentType int componentType, int userId) {
4056 // if we're in an isolated process, get the real calling UID
4057 if (Process.isIsolated(callingUid)) {
4058 callingUid = mIsolatedOwners.get(callingUid);
4060 final String instantAppPkgName = getInstantAppPackageName(callingUid);
4061 final boolean callerIsInstantApp = instantAppPkgName != null;
4063 if (callerIsInstantApp) {
4064 // pretend the application exists, but, needs to be filtered
4069 // if the target and caller are the same application, don't filter
4070 if (isCallerSameApp(ps.name, callingUid)) {
4073 if (callerIsInstantApp) {
4074 // request for a specific component; if it hasn't been explicitly exposed, filter
4075 if (component != null) {
4076 return !isComponentVisibleToInstantApp(component, componentType);
4078 // request for application; if no components have been explicitly exposed, filter
4079 return ps.getInstantApp(userId) || !ps.pkg.visibleToInstantApps;
4081 if (ps.getInstantApp(userId)) {
4082 // caller can see all components of all instant applications, don't filter
4083 if (canViewInstantApps(callingUid, userId)) {
4086 // request for a specific instant application component, filter
4087 if (component != null) {
4090 // request for an instant application; if the caller hasn't been granted access, filter
4091 return !mInstantAppRegistry.isInstantAccessGranted(
4092 userId, UserHandle.getAppId(callingUid), ps.appId);
4098 * @see #filterAppAccessLPr(PackageSetting, int, ComponentName, boolean, int)
4100 private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid, int userId) {
4101 return filterAppAccessLPr(ps, callingUid, null, TYPE_UNKNOWN, userId);
4104 private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
4106 // Callers can access only the libs they depend on, otherwise they need to explicitly
4107 // ask for the shared libraries given the caller is allowed to access all static libs.
4108 if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
4109 // System/shell/root get to see all static libs
4110 final int appId = UserHandle.getAppId(uid);
4111 if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
4112 || appId == Process.ROOT_UID) {
4117 // No package means no static lib as it is always on internal storage
4118 if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4122 final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName,
4123 ps.pkg.staticSharedLibVersion);
4124 if (libEntry == null) {
4128 final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
4129 final String[] uidPackageNames = getPackagesForUid(resolvedUid);
4130 if (uidPackageNames == null) {
4134 for (String uidPackageName : uidPackageNames) {
4135 if (ps.name.equals(uidPackageName)) {
4138 PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
4139 if (uidPs != null) {
4140 final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
4141 libEntry.info.getName());
4145 if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getVersion()) {
4154 public String[] currentToCanonicalPackageNames(String[] names) {
4155 final int callingUid = Binder.getCallingUid();
4156 if (getInstantAppPackageName(callingUid) != null) {
4159 final String[] out = new String[names.length];
4161 synchronized (mPackages) {
4162 final int callingUserId = UserHandle.getUserId(callingUid);
4163 final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4164 for (int i=names.length-1; i>=0; i--) {
4165 final PackageSetting ps = mSettings.mPackages.get(names[i]);
4166 boolean translateName = false;
4167 if (ps != null && ps.realName != null) {
4168 final boolean targetIsInstantApp = ps.getInstantApp(callingUserId);
4169 translateName = !targetIsInstantApp
4170 || canViewInstantApps
4171 || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4172 UserHandle.getAppId(callingUid), ps.appId);
4174 out[i] = translateName ? ps.realName : names[i];
4181 public String[] canonicalToCurrentPackageNames(String[] names) {
4182 final int callingUid = Binder.getCallingUid();
4183 if (getInstantAppPackageName(callingUid) != null) {
4186 final String[] out = new String[names.length];
4188 synchronized (mPackages) {
4189 final int callingUserId = UserHandle.getUserId(callingUid);
4190 final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4191 for (int i=names.length-1; i>=0; i--) {
4192 final String cur = mSettings.getRenamedPackageLPr(names[i]);
4193 boolean translateName = false;
4195 final PackageSetting ps = mSettings.mPackages.get(names[i]);
4196 final boolean targetIsInstantApp =
4197 ps != null && ps.getInstantApp(callingUserId);
4198 translateName = !targetIsInstantApp
4199 || canViewInstantApps
4200 || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4201 UserHandle.getAppId(callingUid), ps.appId);
4203 out[i] = translateName ? cur : names[i];
4210 public int getPackageUid(String packageName, int flags, int userId) {
4211 if (!sUserManager.exists(userId)) return -1;
4212 final int callingUid = Binder.getCallingUid();
4213 flags = updateFlagsForPackage(flags, userId, packageName);
4214 enforceCrossUserPermission(callingUid, userId,
4215 false /*requireFullPermission*/, false /*checkShell*/, "getPackageUid");
4218 synchronized (mPackages) {
4219 final PackageParser.Package p = mPackages.get(packageName);
4220 if (p != null && p.isMatch(flags)) {
4221 PackageSetting ps = (PackageSetting) p.mExtras;
4222 if (filterAppAccessLPr(ps, callingUid, userId)) {
4225 return UserHandle.getUid(userId, p.applicationInfo.uid);
4227 if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4228 final PackageSetting ps = mSettings.mPackages.get(packageName);
4229 if (ps != null && ps.isMatch(flags)
4230 && !filterAppAccessLPr(ps, callingUid, userId)) {
4231 return UserHandle.getUid(userId, ps.appId);
4240 public int[] getPackageGids(String packageName, int flags, int userId) {
4241 if (!sUserManager.exists(userId)) return null;
4242 final int callingUid = Binder.getCallingUid();
4243 flags = updateFlagsForPackage(flags, userId, packageName);
4244 enforceCrossUserPermission(callingUid, userId,
4245 false /*requireFullPermission*/, false /*checkShell*/, "getPackageGids");
4248 synchronized (mPackages) {
4249 final PackageParser.Package p = mPackages.get(packageName);
4250 if (p != null && p.isMatch(flags)) {
4251 PackageSetting ps = (PackageSetting) p.mExtras;
4252 if (filterAppAccessLPr(ps, callingUid, userId)) {
4255 // TODO: Shouldn't this be checking for package installed state for userId and
4257 return ps.getPermissionsState().computeGids(userId);
4259 if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4260 final PackageSetting ps = mSettings.mPackages.get(packageName);
4261 if (ps != null && ps.isMatch(flags)
4262 && !filterAppAccessLPr(ps, callingUid, userId)) {
4263 return ps.getPermissionsState().computeGids(userId);
4271 static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) {
4272 if (bp.perm != null) {
4273 return PackageParser.generatePermissionInfo(bp.perm, flags);
4275 PermissionInfo pi = new PermissionInfo();
4277 pi.packageName = bp.sourcePackage;
4278 pi.nonLocalizedLabel = bp.name;
4279 pi.protectionLevel = bp.protectionLevel;
4284 public PermissionInfo getPermissionInfo(String name, String packageName, int flags) {
4285 final int callingUid = Binder.getCallingUid();
4286 if (getInstantAppPackageName(callingUid) != null) {
4290 synchronized (mPackages) {
4291 final BasePermission p = mSettings.mPermissions.get(name);
4295 // If the caller is an app that targets pre 26 SDK drop protection flags.
4296 PermissionInfo permissionInfo = generatePermissionInfo(p, flags);
4297 if (permissionInfo != null) {
4298 final int protectionLevel = adjustPermissionProtectionFlagsLPr(
4299 permissionInfo.protectionLevel, packageName, callingUid);
4300 if (permissionInfo.protectionLevel != protectionLevel) {
4301 // If we return different protection level, don't use the cached info
4302 if (p.perm != null && p.perm.info == permissionInfo) {
4303 permissionInfo = new PermissionInfo(permissionInfo);
4305 permissionInfo.protectionLevel = protectionLevel;
4308 return permissionInfo;
4312 private int adjustPermissionProtectionFlagsLPr(int protectionLevel,
4313 String packageName, int uid) {
4314 // Signature permission flags area always reported
4315 final int protectionLevelMasked = protectionLevel
4316 & (PermissionInfo.PROTECTION_NORMAL
4317 | PermissionInfo.PROTECTION_DANGEROUS
4318 | PermissionInfo.PROTECTION_SIGNATURE);
4319 if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
4320 return protectionLevel;
4323 // System sees all flags.
4324 final int appId = UserHandle.getAppId(uid);
4325 if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
4326 || appId == Process.SHELL_UID) {
4327 return protectionLevel;
4330 // Normalize package name to handle renamed packages and static libs
4331 packageName = resolveInternalPackageNameLPr(packageName,
4332 PackageManager.VERSION_CODE_HIGHEST);
4334 // Apps that target O see flags for all protection levels.
4335 final PackageSetting ps = mSettings.mPackages.get(packageName);
4337 return protectionLevel;
4339 if (ps.appId != appId) {
4340 return protectionLevel;
4343 final PackageParser.Package pkg = mPackages.get(packageName);
4345 return protectionLevel;
4347 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
4348 return protectionLevelMasked;
4351 return protectionLevel;
4355 public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group,
4357 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4361 synchronized (mPackages) {
4362 if (group != null && !mPermissionGroups.containsKey(group)) {
4363 // This is thrown as NameNotFoundException
4367 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
4368 for (BasePermission p : mSettings.mPermissions.values()) {
4369 if (group == null) {
4370 if (p.perm == null || p.perm.info.group == null) {
4371 out.add(generatePermissionInfo(p, flags));
4374 if (p.perm != null && group.equals(p.perm.info.group)) {
4375 out.add(PackageParser.generatePermissionInfo(p.perm, flags));
4379 return new ParceledListSlice<>(out);
4384 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
4385 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4389 synchronized (mPackages) {
4390 return PackageParser.generatePermissionGroupInfo(
4391 mPermissionGroups.get(name), flags);
4396 public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
4397 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4398 return ParceledListSlice.emptyList();
4401 synchronized (mPackages) {
4402 final int N = mPermissionGroups.size();
4403 ArrayList<PermissionGroupInfo> out
4404 = new ArrayList<PermissionGroupInfo>(N);
4405 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
4406 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
4408 return new ParceledListSlice<>(out);
4412 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
4413 int filterCallingUid, int userId) {
4414 if (!sUserManager.exists(userId)) return null;
4415 PackageSetting ps = mSettings.mPackages.get(packageName);
4417 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4420 if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4423 if (ps.pkg == null) {
4424 final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
4425 if (pInfo != null) {
4426 return pInfo.applicationInfo;
4430 ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
4431 ps.readUserState(userId), userId);
4433 ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
4441 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
4442 return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId);
4446 * Important: The provided filterCallingUid is used exclusively to filter out applications
4447 * that can be seen based on user state. It's typically the original caller uid prior
4448 * to clearing. Because it can only be provided by trusted code, it's value can be
4449 * trusted and will be used as-is; unlike userId which will be validated by this method.
4451 private ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
4452 int filterCallingUid, int userId) {
4453 if (!sUserManager.exists(userId)) return null;
4454 flags = updateFlagsForApplication(flags, userId, packageName);
4455 enforceCrossUserPermission(Binder.getCallingUid(), userId,
4456 false /* requireFullPermission */, false /* checkShell */, "get application info");
4459 synchronized (mPackages) {
4460 // Normalize package name to handle renamed packages and static libs
4461 packageName = resolveInternalPackageNameLPr(packageName,
4462 PackageManager.VERSION_CODE_HIGHEST);
4464 PackageParser.Package p = mPackages.get(packageName);
4465 if (DEBUG_PACKAGE_INFO) Log.v(
4466 TAG, "getApplicationInfo " + packageName
4469 PackageSetting ps = mSettings.mPackages.get(packageName);
4470 if (ps == null) return null;
4471 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4474 if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4477 // Note: isEnabledLP() does not apply here - always return info
4478 ApplicationInfo ai = PackageParser.generateApplicationInfo(
4479 p, flags, ps.readUserState(userId), userId);
4481 ai.packageName = resolveExternalPackageNameLPr(p);
4485 if ("android".equals(packageName)||"system".equals(packageName)) {
4486 return mAndroidApplication;
4488 if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4489 // Already generates the external package name
4490 return generateApplicationInfoFromSettingsLPw(packageName,
4491 flags, filterCallingUid, userId);
4497 private String normalizePackageNameLPr(String packageName) {
4498 String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
4499 return normalizedPackageName != null ? normalizedPackageName : packageName;
4503 public void deletePreloadsFileCache() {
4504 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
4505 throw new SecurityException("Only system or settings may call deletePreloadsFileCache");
4507 File dir = Environment.getDataPreloadsFileCacheDirectory();
4508 Slog.i(TAG, "Deleting preloaded file cache " + dir);
4509 FileUtils.deleteContents(dir);
4513 public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
4514 final int storageFlags, final IPackageDataObserver observer) {
4515 mContext.enforceCallingOrSelfPermission(
4516 android.Manifest.permission.CLEAR_APP_CACHE, null);
4517 mHandler.post(() -> {
4518 boolean success = false;
4520 freeStorage(volumeUuid, freeStorageSize, storageFlags);
4522 } catch (IOException e) {
4525 if (observer != null) {
4527 observer.onRemoveCompleted(null, success);
4528 } catch (RemoteException e) {
4536 public void freeStorage(final String volumeUuid, final long freeStorageSize,
4537 final int storageFlags, final IntentSender pi) {
4538 mContext.enforceCallingOrSelfPermission(
4539 android.Manifest.permission.CLEAR_APP_CACHE, TAG);
4540 mHandler.post(() -> {
4541 boolean success = false;
4543 freeStorage(volumeUuid, freeStorageSize, storageFlags);
4545 } catch (IOException e) {
4550 pi.sendIntent(null, success ? 1 : 0, null, null, null);
4551 } catch (SendIntentException e) {
4559 * Blocking call to clear various types of cached data across the system
4560 * until the requested bytes are available.
4562 public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
4563 final StorageManager storage = mContext.getSystemService(StorageManager.class);
4564 final File file = storage.findPathForUuid(volumeUuid);
4565 if (file.getUsableSpace() >= bytes) return;
4567 if (ENABLE_FREE_CACHE_V2) {
4568 final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
4570 final boolean aggressive = (storageFlags
4571 & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
4572 final long reservedBytes = storage.getStorageCacheBytes(file, storageFlags);
4574 // 1. Pre-flight to determine if we have any chance to succeed
4575 // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
4576 if (internalVolume && (aggressive || SystemProperties
4577 .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
4578 deletePreloadsFileCache();
4579 if (file.getUsableSpace() >= bytes) return;
4582 // 3. Consider parsed APK data (aggressive only)
4583 if (internalVolume && aggressive) {
4584 FileUtils.deleteContents(mCacheDir);
4585 if (file.getUsableSpace() >= bytes) return;
4588 // 4. Consider cached app data (above quotas)
4590 mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4591 Installer.FLAG_FREE_CACHE_V2);
4592 } catch (InstallerException ignored) {
4594 if (file.getUsableSpace() >= bytes) return;
4596 // 5. Consider shared libraries with refcount=0 and age>min cache period
4597 if (internalVolume && pruneUnusedStaticSharedLibraries(bytes,
4598 android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4599 Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
4600 DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD))) {
4604 // 6. Consider dexopt output (aggressive only)
4607 // 7. Consider installed instant apps unused longer than min cache period
4608 if (internalVolume && mInstantAppRegistry.pruneInstalledInstantApps(bytes,
4609 android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4610 Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4611 InstantAppRegistry.DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4615 // 8. Consider cached app data (below quotas)
4617 mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4618 Installer.FLAG_FREE_CACHE_V2 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
4619 } catch (InstallerException ignored) {
4621 if (file.getUsableSpace() >= bytes) return;
4623 // 9. Consider DropBox entries
4626 // 10. Consider instant meta-data (uninstalled apps) older that min cache period
4627 if (internalVolume && mInstantAppRegistry.pruneUninstalledInstantApps(bytes,
4628 android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4629 Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4630 InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4635 mInstaller.freeCache(volumeUuid, bytes, 0, 0);
4636 } catch (InstallerException ignored) {
4638 if (file.getUsableSpace() >= bytes) return;
4641 throw new IOException("Failed to free " + bytes + " on storage device at " + file);
4644 private boolean pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)
4645 throws IOException {
4646 final StorageManager storage = mContext.getSystemService(StorageManager.class);
4647 final File volume = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
4649 List<VersionedPackage> packagesToDelete = null;
4650 final long now = System.currentTimeMillis();
4652 synchronized (mPackages) {
4653 final int[] allUsers = sUserManager.getUserIds();
4654 final int libCount = mSharedLibraries.size();
4655 for (int i = 0; i < libCount; i++) {
4656 final SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4657 if (versionedLib == null) {
4660 final int versionCount = versionedLib.size();
4661 for (int j = 0; j < versionCount; j++) {
4662 SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4663 // Skip packages that are not static shared libs.
4664 if (!libInfo.isStatic()) {
4667 // Important: We skip static shared libs used for some user since
4668 // in such a case we need to keep the APK on the device. The check for
4669 // a lib being used for any user is performed by the uninstall call.
4670 final VersionedPackage declaringPackage = libInfo.getDeclaringPackage();
4671 // Resolve the package name - we use synthetic package names internally
4672 final String internalPackageName = resolveInternalPackageNameLPr(
4673 declaringPackage.getPackageName(), declaringPackage.getVersionCode());
4674 final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
4675 // Skip unused static shared libs cached less than the min period
4676 // to prevent pruning a lib needed by a subsequently installed package.
4677 if (ps == null || now - ps.lastUpdateTime < maxCachePeriod) {
4680 if (packagesToDelete == null) {
4681 packagesToDelete = new ArrayList<>();
4683 packagesToDelete.add(new VersionedPackage(internalPackageName,
4684 declaringPackage.getVersionCode()));
4689 if (packagesToDelete != null) {
4690 final int packageCount = packagesToDelete.size();
4691 for (int i = 0; i < packageCount; i++) {
4692 final VersionedPackage pkgToDelete = packagesToDelete.get(i);
4693 // Delete the package synchronously (will fail of the lib used for any user).
4694 if (deletePackageX(pkgToDelete.getPackageName(), pkgToDelete.getVersionCode(),
4695 UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS)
4696 == PackageManager.DELETE_SUCCEEDED) {
4697 if (volume.getUsableSpace() >= neededSpace) {
4708 * Update given flags based on encryption status of current user.
4710 private int updateFlags(int flags, int userId) {
4711 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4712 | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
4713 // Caller expressed an explicit opinion about what encryption
4714 // aware/unaware components they want to see, so fall through and
4715 // give them what they want
4717 // Caller expressed no opinion, so match based on user state
4718 if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
4719 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
4721 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
4727 private UserManagerInternal getUserManagerInternal() {
4728 if (mUserManagerInternal == null) {
4729 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
4731 return mUserManagerInternal;
4734 private DeviceIdleController.LocalService getDeviceIdleController() {
4735 if (mDeviceIdleController == null) {
4736 mDeviceIdleController =
4737 LocalServices.getService(DeviceIdleController.LocalService.class);
4739 return mDeviceIdleController;
4743 * Update given flags when being used to request {@link PackageInfo}.
4745 private int updateFlagsForPackage(int flags, int userId, Object cookie) {
4746 final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
4747 boolean triaged = true;
4748 if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
4749 | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
4750 // Caller is asking for component details, so they'd better be
4751 // asking for specific encryption matching behavior, or be triaged
4752 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4753 | PackageManager.MATCH_DIRECT_BOOT_AWARE
4754 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4758 if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
4759 | PackageManager.MATCH_SYSTEM_ONLY
4760 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4763 if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
4764 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
4765 "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
4766 + Debug.getCallers(5));
4767 } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
4768 && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
4769 // If the caller wants all packages and has a restricted profile associated with it,
4770 // then match all users. This is to make sure that launchers that need to access work
4771 // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
4772 // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
4773 flags |= PackageManager.MATCH_ANY_USER;
4775 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4776 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4777 + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4779 return updateFlags(flags, userId);
4783 * Update given flags when being used to request {@link ApplicationInfo}.
4785 private int updateFlagsForApplication(int flags, int userId, Object cookie) {
4786 return updateFlagsForPackage(flags, userId, cookie);
4790 * Update given flags when being used to request {@link ComponentInfo}.
4792 private int updateFlagsForComponent(int flags, int userId, Object cookie) {
4793 if (cookie instanceof Intent) {
4794 if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
4795 flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
4799 boolean triaged = true;
4800 // Caller is asking for component details, so they'd better be
4801 // asking for specific encryption matching behavior, or be triaged
4802 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4803 | PackageManager.MATCH_DIRECT_BOOT_AWARE
4804 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4807 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4808 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4809 + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4812 return updateFlags(flags, userId);
4816 * Update given intent when being used to request {@link ResolveInfo}.
4818 private Intent updateIntentForResolve(Intent intent) {
4819 if (intent.getSelector() != null) {
4820 intent = intent.getSelector();
4822 if (DEBUG_PREFERRED) {
4823 intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4829 * Update given flags when being used to request {@link ResolveInfo}.
4830 * <p>Instant apps are resolved specially, depending upon context. Minimally,
4831 * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
4832 * flag set. However, this flag is only honoured in three circumstances:
4834 * <li>when called from a system process</li>
4835 * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
4836 * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
4837 * action and a {@code android.intent.category.BROWSABLE} category</li>
4840 int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid) {
4841 return updateFlagsForResolve(flags, userId, intent, callingUid,
4842 false /*wantInstantApps*/, false /*onlyExposedExplicitly*/);
4844 int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4845 boolean wantInstantApps) {
4846 return updateFlagsForResolve(flags, userId, intent, callingUid,
4847 wantInstantApps, false /*onlyExposedExplicitly*/);
4849 int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4850 boolean wantInstantApps, boolean onlyExposedExplicitly) {
4851 // Safe mode means we shouldn't match any third-party components
4853 flags |= PackageManager.MATCH_SYSTEM_ONLY;
4855 if (getInstantAppPackageName(callingUid) != null) {
4856 // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
4857 if (onlyExposedExplicitly) {
4858 flags |= PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY;
4860 flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4861 flags |= PackageManager.MATCH_INSTANT;
4863 final boolean wantMatchInstant = (flags & PackageManager.MATCH_INSTANT) != 0;
4864 final boolean allowMatchInstant =
4866 && Intent.ACTION_VIEW.equals(intent.getAction())
4867 && hasWebURI(intent))
4868 || (wantMatchInstant && canViewInstantApps(callingUid, userId));
4869 flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
4870 | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
4871 if (!allowMatchInstant) {
4872 flags &= ~PackageManager.MATCH_INSTANT;
4875 return updateFlagsForComponent(flags, userId, intent /*cookie*/);
4879 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
4880 return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
4884 * Important: The provided filterCallingUid is used exclusively to filter out activities
4885 * that can be seen based on user state. It's typically the original caller uid prior
4886 * to clearing. Because it can only be provided by trusted code, it's value can be
4887 * trusted and will be used as-is; unlike userId which will be validated by this method.
4889 private ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
4890 int filterCallingUid, int userId) {
4891 if (!sUserManager.exists(userId)) return null;
4892 flags = updateFlagsForComponent(flags, userId, component);
4893 enforceCrossUserPermission(Binder.getCallingUid(), userId,
4894 false /* requireFullPermission */, false /* checkShell */, "get activity info");
4895 synchronized (mPackages) {
4896 PackageParser.Activity a = mActivities.mActivities.get(component);
4898 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
4899 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4900 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4901 if (ps == null) return null;
4902 if (filterAppAccessLPr(ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) {
4905 return PackageParser.generateActivityInfo(
4906 a, flags, ps.readUserState(userId), userId);
4908 if (mResolveComponentName.equals(component)) {
4909 return PackageParser.generateActivityInfo(
4910 mResolveActivity, flags, new PackageUserState(), userId);
4917 public boolean activitySupportsIntent(ComponentName component, Intent intent,
4918 String resolvedType) {
4919 synchronized (mPackages) {
4920 if (component.equals(mResolveComponentName)) {
4921 // The resolver supports EVERYTHING!
4924 final int callingUid = Binder.getCallingUid();
4925 final int callingUserId = UserHandle.getUserId(callingUid);
4926 PackageParser.Activity a = mActivities.mActivities.get(component);
4930 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4934 if (filterAppAccessLPr(ps, callingUid, component, TYPE_ACTIVITY, callingUserId)) {
4937 for (int i=0; i<a.intents.size(); i++) {
4938 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
4939 intent.getData(), intent.getCategories(), TAG) >= 0) {
4948 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
4949 if (!sUserManager.exists(userId)) return null;
4950 final int callingUid = Binder.getCallingUid();
4951 flags = updateFlagsForComponent(flags, userId, component);
4952 enforceCrossUserPermission(callingUid, userId,
4953 false /* requireFullPermission */, false /* checkShell */, "get receiver info");
4954 synchronized (mPackages) {
4955 PackageParser.Activity a = mReceivers.mActivities.get(component);
4956 if (DEBUG_PACKAGE_INFO) Log.v(
4957 TAG, "getReceiverInfo " + component + ": " + a);
4958 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4959 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4960 if (ps == null) return null;
4961 if (filterAppAccessLPr(ps, callingUid, component, TYPE_RECEIVER, userId)) {
4964 return PackageParser.generateActivityInfo(
4965 a, flags, ps.readUserState(userId), userId);
4972 public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
4973 int flags, int userId) {
4974 if (!sUserManager.exists(userId)) return null;
4975 Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
4976 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4980 flags = updateFlagsForPackage(flags, userId, null);
4982 final boolean canSeeStaticLibraries =
4983 mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
4984 == PERMISSION_GRANTED
4985 || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
4986 == PERMISSION_GRANTED
4987 || canRequestPackageInstallsInternal(packageName,
4988 PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId,
4989 false /* throwIfPermNotDeclared*/)
4990 || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
4991 == PERMISSION_GRANTED;
4993 synchronized (mPackages) {
4994 List<SharedLibraryInfo> result = null;
4996 final int libCount = mSharedLibraries.size();
4997 for (int i = 0; i < libCount; i++) {
4998 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4999 if (versionedLib == null) {
5003 final int versionCount = versionedLib.size();
5004 for (int j = 0; j < versionCount; j++) {
5005 SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
5006 if (!canSeeStaticLibraries && libInfo.isStatic()) {
5009 final long identity = Binder.clearCallingIdentity();
5011 PackageInfo packageInfo = getPackageInfoVersioned(
5012 libInfo.getDeclaringPackage(), flags
5013 | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
5014 if (packageInfo == null) {
5018 Binder.restoreCallingIdentity(identity);
5021 SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(),
5022 libInfo.getVersion(), libInfo.getType(),
5023 libInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(libInfo,
5026 if (result == null) {
5027 result = new ArrayList<>();
5029 result.add(resLibInfo);
5033 return result != null ? new ParceledListSlice<>(result) : null;
5037 private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
5038 SharedLibraryInfo libInfo, int flags, int userId) {
5039 List<VersionedPackage> versionedPackages = null;
5040 final int packageCount = mSettings.mPackages.size();
5041 for (int i = 0; i < packageCount; i++) {
5042 PackageSetting ps = mSettings.mPackages.valueAt(i);
5048 if (!ps.getUserState().get(userId).isAvailable(flags)) {
5052 final String libName = libInfo.getName();
5053 if (libInfo.isStatic()) {
5054 final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
5058 if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getVersion()) {
5061 if (versionedPackages == null) {
5062 versionedPackages = new ArrayList<>();
5064 // If the dependent is a static shared lib, use the public package name
5065 String dependentPackageName = ps.name;
5066 if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) {
5067 dependentPackageName = ps.pkg.manifestPackageName;
5069 versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
5070 } else if (ps.pkg != null) {
5071 if (ArrayUtils.contains(ps.pkg.usesLibraries, libName)
5072 || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) {
5073 if (versionedPackages == null) {
5074 versionedPackages = new ArrayList<>();
5076 versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
5081 return versionedPackages;
5085 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
5086 if (!sUserManager.exists(userId)) return null;
5087 final int callingUid = Binder.getCallingUid();
5088 flags = updateFlagsForComponent(flags, userId, component);
5089 enforceCrossUserPermission(callingUid, userId,
5090 false /* requireFullPermission */, false /* checkShell */, "get service info");
5091 synchronized (mPackages) {
5092 PackageParser.Service s = mServices.mServices.get(component);
5093 if (DEBUG_PACKAGE_INFO) Log.v(
5094 TAG, "getServiceInfo " + component + ": " + s);
5095 if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
5096 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5097 if (ps == null) return null;
5098 if (filterAppAccessLPr(ps, callingUid, component, TYPE_SERVICE, userId)) {
5101 return PackageParser.generateServiceInfo(
5102 s, flags, ps.readUserState(userId), userId);
5109 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
5110 if (!sUserManager.exists(userId)) return null;
5111 final int callingUid = Binder.getCallingUid();
5112 flags = updateFlagsForComponent(flags, userId, component);
5113 enforceCrossUserPermission(callingUid, userId,
5114 false /* requireFullPermission */, false /* checkShell */, "get provider info");
5115 synchronized (mPackages) {
5116 PackageParser.Provider p = mProviders.mProviders.get(component);
5117 if (DEBUG_PACKAGE_INFO) Log.v(
5118 TAG, "getProviderInfo " + component + ": " + p);
5119 if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
5120 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5121 if (ps == null) return null;
5122 if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
5125 return PackageParser.generateProviderInfo(
5126 p, flags, ps.readUserState(userId), userId);
5133 public String[] getSystemSharedLibraryNames() {
5134 // allow instant applications
5135 synchronized (mPackages) {
5136 Set<String> libs = null;
5137 final int libCount = mSharedLibraries.size();
5138 for (int i = 0; i < libCount; i++) {
5139 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
5140 if (versionedLib == null) {
5143 final int versionCount = versionedLib.size();
5144 for (int j = 0; j < versionCount; j++) {
5145 SharedLibraryEntry libEntry = versionedLib.valueAt(j);
5146 if (!libEntry.info.isStatic()) {
5148 libs = new ArraySet<>();
5150 libs.add(libEntry.info.getName());
5153 PackageSetting ps = mSettings.getPackageLPr(libEntry.apk);
5154 if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
5155 UserHandle.getUserId(Binder.getCallingUid()),
5156 PackageManager.MATCH_STATIC_SHARED_LIBRARIES)) {
5158 libs = new ArraySet<>();
5160 libs.add(libEntry.info.getName());
5167 String[] libsArray = new String[libs.size()];
5168 libs.toArray(libsArray);
5177 public @NonNull String getServicesSystemSharedLibraryPackageName() {
5178 // allow instant applications
5179 synchronized (mPackages) {
5180 return mServicesSystemSharedLibraryPackageName;
5185 public @NonNull String getSharedSystemSharedLibraryPackageName() {
5186 // allow instant applications
5187 synchronized (mPackages) {
5188 return mSharedSystemSharedLibraryPackageName;
5192 private void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
5193 for (int i = userList.length - 1; i >= 0; --i) {
5194 final int userId = userList[i];
5195 // don't add instant app to the list of updates
5196 if (pkgSetting.getInstantApp(userId)) {
5199 SparseArray<String> changedPackages = mChangedPackages.get(userId);
5200 if (changedPackages == null) {
5201 changedPackages = new SparseArray<>();
5202 mChangedPackages.put(userId, changedPackages);
5204 Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
5205 if (sequenceNumbers == null) {
5206 sequenceNumbers = new HashMap<>();
5207 mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
5209 final Integer sequenceNumber = sequenceNumbers.get(pkgSetting.name);
5210 if (sequenceNumber != null) {
5211 changedPackages.remove(sequenceNumber);
5213 changedPackages.put(mChangedPackagesSequenceNumber, pkgSetting.name);
5214 sequenceNumbers.put(pkgSetting.name, mChangedPackagesSequenceNumber);
5216 mChangedPackagesSequenceNumber++;
5220 public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
5221 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5224 synchronized (mPackages) {
5225 if (sequenceNumber >= mChangedPackagesSequenceNumber) {
5228 final SparseArray<String> changedPackages = mChangedPackages.get(userId);
5229 if (changedPackages == null) {
5232 final List<String> packageNames =
5233 new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
5234 for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
5235 final String packageName = changedPackages.get(i);
5236 if (packageName != null) {
5237 packageNames.add(packageName);
5240 return packageNames.isEmpty()
5241 ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
5246 public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
5247 // allow instant applications
5248 ArrayList<FeatureInfo> res;
5249 synchronized (mAvailableFeatures) {
5250 res = new ArrayList<>(mAvailableFeatures.size() + 1);
5251 res.addAll(mAvailableFeatures.values());
5253 final FeatureInfo fi = new FeatureInfo();
5254 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
5255 FeatureInfo.GL_ES_VERSION_UNDEFINED);
5258 return new ParceledListSlice<>(res);
5262 public boolean hasSystemFeature(String name, int version) {
5263 // allow instant applications
5264 synchronized (mAvailableFeatures) {
5265 final FeatureInfo feat = mAvailableFeatures.get(name);
5269 return feat.version >= version;
5275 public int checkPermission(String permName, String pkgName, int userId) {
5276 if (!sUserManager.exists(userId)) {
5277 return PackageManager.PERMISSION_DENIED;
5279 final int callingUid = Binder.getCallingUid();
5281 synchronized (mPackages) {
5282 final PackageParser.Package p = mPackages.get(pkgName);
5283 if (p != null && p.mExtras != null) {
5284 final PackageSetting ps = (PackageSetting) p.mExtras;
5285 if (filterAppAccessLPr(ps, callingUid, userId)) {
5286 return PackageManager.PERMISSION_DENIED;
5288 final boolean instantApp = ps.getInstantApp(userId);
5289 final PermissionsState permissionsState = ps.getPermissionsState();
5290 if (permissionsState.hasPermission(permName, userId)) {
5292 BasePermission bp = mSettings.mPermissions.get(permName);
5293 if (bp != null && bp.isInstant()) {
5294 return PackageManager.PERMISSION_GRANTED;
5297 return PackageManager.PERMISSION_GRANTED;
5300 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
5301 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
5302 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
5303 return PackageManager.PERMISSION_GRANTED;
5308 return PackageManager.PERMISSION_DENIED;
5312 public int checkUidPermission(String permName, int uid) {
5313 final int callingUid = Binder.getCallingUid();
5314 final int callingUserId = UserHandle.getUserId(callingUid);
5315 final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5316 final boolean isUidInstantApp = getInstantAppPackageName(uid) != null;
5317 final int userId = UserHandle.getUserId(uid);
5318 if (!sUserManager.exists(userId)) {
5319 return PackageManager.PERMISSION_DENIED;
5322 synchronized (mPackages) {
5323 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5325 if (obj instanceof SharedUserSetting) {
5326 if (isCallerInstantApp) {
5327 return PackageManager.PERMISSION_DENIED;
5329 } else if (obj instanceof PackageSetting) {
5330 final PackageSetting ps = (PackageSetting) obj;
5331 if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5332 return PackageManager.PERMISSION_DENIED;
5335 final SettingBase settingBase = (SettingBase) obj;
5336 final PermissionsState permissionsState = settingBase.getPermissionsState();
5337 if (permissionsState.hasPermission(permName, userId)) {
5338 if (isUidInstantApp) {
5339 BasePermission bp = mSettings.mPermissions.get(permName);
5340 if (bp != null && bp.isInstant()) {
5341 return PackageManager.PERMISSION_GRANTED;
5344 return PackageManager.PERMISSION_GRANTED;
5347 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
5348 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
5349 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
5350 return PackageManager.PERMISSION_GRANTED;
5353 ArraySet<String> perms = mSystemPermissions.get(uid);
5354 if (perms != null) {
5355 if (perms.contains(permName)) {
5356 return PackageManager.PERMISSION_GRANTED;
5358 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
5359 .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
5360 return PackageManager.PERMISSION_GRANTED;
5366 return PackageManager.PERMISSION_DENIED;
5370 public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
5371 if (UserHandle.getCallingUserId() != userId) {
5372 mContext.enforceCallingPermission(
5373 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5374 "isPermissionRevokedByPolicy for user " + userId);
5377 if (checkPermission(permission, packageName, userId)
5378 == PackageManager.PERMISSION_GRANTED) {
5382 final int callingUid = Binder.getCallingUid();
5383 if (getInstantAppPackageName(callingUid) != null) {
5384 if (!isCallerSameApp(packageName, callingUid)) {
5388 if (isInstantApp(packageName, userId)) {
5393 final long identity = Binder.clearCallingIdentity();
5395 final int flags = getPermissionFlags(permission, packageName, userId);
5396 return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
5398 Binder.restoreCallingIdentity(identity);
5403 public String getPermissionControllerPackageName() {
5404 synchronized (mPackages) {
5405 return mRequiredInstallerPackage;
5410 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
5411 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
5412 * @param checkShell whether to prevent shell from access if there's a debugging restriction
5413 * @param message the message to log on security exception
5415 void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
5416 boolean checkShell, String message) {
5418 throw new IllegalArgumentException("Invalid userId " + userId);
5421 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
5423 if (userId == UserHandle.getUserId(callingUid)) return;
5424 if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5425 if (requireFullPermission) {
5426 mContext.enforceCallingOrSelfPermission(
5427 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
5430 mContext.enforceCallingOrSelfPermission(
5431 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
5432 } catch (SecurityException se) {
5433 mContext.enforceCallingOrSelfPermission(
5434 android.Manifest.permission.INTERACT_ACROSS_USERS, message);
5440 void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
5441 if (callingUid == Process.SHELL_UID) {
5443 && sUserManager.hasUserRestriction(restriction, userHandle)) {
5444 throw new SecurityException("Shell does not have permission to access user "
5446 } else if (userHandle < 0) {
5447 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
5448 + Debug.getCallers(3));
5453 private BasePermission findPermissionTreeLP(String permName) {
5454 for(BasePermission bp : mSettings.mPermissionTrees.values()) {
5455 if (permName.startsWith(bp.name) &&
5456 permName.length() > bp.name.length() &&
5457 permName.charAt(bp.name.length()) == '.') {
5464 private BasePermission checkPermissionTreeLP(String permName) {
5465 if (permName != null) {
5466 BasePermission bp = findPermissionTreeLP(permName);
5468 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
5471 throw new SecurityException("Calling uid "
5472 + Binder.getCallingUid()
5473 + " is not allowed to add to permission tree "
5474 + bp.name + " owned by uid " + bp.uid);
5477 throw new SecurityException("No permission tree found for " + permName);
5480 static boolean compareStrings(CharSequence s1, CharSequence s2) {
5487 if (s1.getClass() != s2.getClass()) {
5490 return s1.equals(s2);
5493 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
5494 if (pi1.icon != pi2.icon) return false;
5495 if (pi1.logo != pi2.logo) return false;
5496 if (pi1.protectionLevel != pi2.protectionLevel) return false;
5497 if (!compareStrings(pi1.name, pi2.name)) return false;
5498 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
5499 // We'll take care of setting this one.
5500 if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
5501 // These are not currently stored in settings.
5502 //if (!compareStrings(pi1.group, pi2.group)) return false;
5503 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
5504 //if (pi1.labelRes != pi2.labelRes) return false;
5505 //if (pi1.descriptionRes != pi2.descriptionRes) return false;
5509 int permissionInfoFootprint(PermissionInfo info) {
5510 int size = info.name.length();
5511 if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
5512 if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
5516 int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
5518 for (BasePermission perm : mSettings.mPermissions.values()) {
5519 if (perm.uid == tree.uid) {
5520 size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
5526 void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
5527 // We calculate the max size of permissions defined by this uid and throw
5528 // if that plus the size of 'info' would exceed our stated maximum.
5529 if (tree.uid != Process.SYSTEM_UID) {
5530 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
5531 if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
5532 throw new SecurityException("Permission tree size cap exceeded");
5537 boolean addPermissionLocked(PermissionInfo info, boolean async) {
5538 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5539 throw new SecurityException("Instant apps can't add permissions");
5541 if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
5542 throw new SecurityException("Label must be specified in permission");
5544 BasePermission tree = checkPermissionTreeLP(info.name);
5545 BasePermission bp = mSettings.mPermissions.get(info.name);
5546 boolean added = bp == null;
5547 boolean changed = true;
5548 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
5550 enforcePermissionCapLocked(info, tree);
5551 bp = new BasePermission(info.name, tree.sourcePackage,
5552 BasePermission.TYPE_DYNAMIC);
5553 } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
5554 throw new SecurityException(
5555 "Not allowed to modify non-dynamic permission "
5558 if (bp.protectionLevel == fixedLevel
5559 && bp.perm.owner.equals(tree.perm.owner)
5560 && bp.uid == tree.uid
5561 && comparePermissionInfos(bp.perm.info, info)) {
5565 bp.protectionLevel = fixedLevel;
5566 info = new PermissionInfo(info);
5567 info.protectionLevel = fixedLevel;
5568 bp.perm = new PackageParser.Permission(tree.perm.owner, info);
5569 bp.perm.info.packageName = tree.perm.info.packageName;
5572 mSettings.mPermissions.put(info.name, bp);
5576 mSettings.writeLPr();
5578 scheduleWriteSettingsLocked();
5585 public boolean addPermission(PermissionInfo info) {
5586 synchronized (mPackages) {
5587 return addPermissionLocked(info, false);
5592 public boolean addPermissionAsync(PermissionInfo info) {
5593 synchronized (mPackages) {
5594 return addPermissionLocked(info, true);
5599 public void removePermission(String name) {
5600 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5601 throw new SecurityException("Instant applications don't have access to this method");
5603 synchronized (mPackages) {
5604 checkPermissionTreeLP(name);
5605 BasePermission bp = mSettings.mPermissions.get(name);
5607 if (bp.type != BasePermission.TYPE_DYNAMIC) {
5608 throw new SecurityException(
5609 "Not allowed to modify non-dynamic permission "
5612 mSettings.mPermissions.remove(name);
5613 mSettings.writeLPr();
5618 private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(
5619 PackageParser.Package pkg, BasePermission bp) {
5620 int index = pkg.requestedPermissions.indexOf(bp.name);
5622 throw new SecurityException("Package " + pkg.packageName
5623 + " has not requested permission " + bp.name);
5625 if (!bp.isRuntime() && !bp.isDevelopment()) {
5626 throw new SecurityException("Permission " + bp.name
5627 + " is not a changeable permission type");
5632 public void grantRuntimePermission(String packageName, String name, final int userId) {
5633 grantRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
5636 private void grantRuntimePermission(String packageName, String name, final int userId,
5637 boolean overridePolicy) {
5638 if (!sUserManager.exists(userId)) {
5639 Log.e(TAG, "No such user:" + userId);
5642 final int callingUid = Binder.getCallingUid();
5644 mContext.enforceCallingOrSelfPermission(
5645 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
5646 "grantRuntimePermission");
5648 enforceCrossUserPermission(callingUid, userId,
5649 true /* requireFullPermission */, true /* checkShell */,
5650 "grantRuntimePermission");
5653 final PackageSetting ps;
5655 synchronized (mPackages) {
5656 final PackageParser.Package pkg = mPackages.get(packageName);
5658 throw new IllegalArgumentException("Unknown package: " + packageName);
5660 final BasePermission bp = mSettings.mPermissions.get(name);
5662 throw new IllegalArgumentException("Unknown permission: " + name);
5664 ps = (PackageSetting) pkg.mExtras;
5666 || filterAppAccessLPr(ps, callingUid, userId)) {
5667 throw new IllegalArgumentException("Unknown package: " + packageName);
5670 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
5672 // If a permission review is required for legacy apps we represent
5673 // their permissions as always granted runtime ones since we need
5674 // to keep the review required permission flag per user while an
5675 // install permission's state is shared across all users.
5676 if (mPermissionReviewRequired
5677 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
5678 && bp.isRuntime()) {
5682 uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
5684 final PermissionsState permissionsState = ps.getPermissionsState();
5686 final int flags = permissionsState.getPermissionFlags(name, userId);
5687 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
5688 throw new SecurityException("Cannot grant system fixed permission "
5689 + name + " for package " + packageName);
5691 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
5692 throw new SecurityException("Cannot grant policy fixed permission "
5693 + name + " for package " + packageName);
5696 if (bp.isDevelopment()) {
5697 // Development permissions must be handled specially, since they are not
5698 // normal runtime permissions. For now they apply to all users.
5699 if (permissionsState.grantInstallPermission(bp) !=
5700 PermissionsState.PERMISSION_OPERATION_FAILURE) {
5701 scheduleWriteSettingsLocked();
5706 if (ps.getInstantApp(userId) && !bp.isInstant()) {
5707 throw new SecurityException("Cannot grant non-ephemeral permission"
5708 + name + " for package " + packageName);
5711 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
5712 Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
5716 final int result = permissionsState.grantRuntimePermission(bp, userId);
5718 case PermissionsState.PERMISSION_OPERATION_FAILURE: {
5722 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
5723 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
5724 mHandler.post(new Runnable() {
5727 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
5734 if (bp.isRuntime()) {
5735 logPermissionGranted(mContext, name, packageName);
5738 mOnPermissionChangeListeners.onPermissionsChanged(uid);
5740 // Not critical if that is lost - app has to request again.
5741 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5744 // Only need to do this if user is initialized. Otherwise it's a new user
5745 // and there are no processes running as the user yet and there's no need
5746 // to make an expensive call to remount processes for the changed permissions.
5747 if (READ_EXTERNAL_STORAGE.equals(name)
5748 || WRITE_EXTERNAL_STORAGE.equals(name)) {
5749 final long token = Binder.clearCallingIdentity();
5751 if (sUserManager.isInitialized(userId)) {
5752 StorageManagerInternal storageManagerInternal = LocalServices.getService(
5753 StorageManagerInternal.class);
5754 storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
5757 Binder.restoreCallingIdentity(token);
5763 public void revokeRuntimePermission(String packageName, String name, int userId) {
5764 revokeRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
5767 private void revokeRuntimePermission(String packageName, String name, int userId,
5768 boolean overridePolicy) {
5769 if (!sUserManager.exists(userId)) {
5770 Log.e(TAG, "No such user:" + userId);
5774 mContext.enforceCallingOrSelfPermission(
5775 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5776 "revokeRuntimePermission");
5778 enforceCrossUserPermission(Binder.getCallingUid(), userId,
5779 true /* requireFullPermission */, true /* checkShell */,
5780 "revokeRuntimePermission");
5784 synchronized (mPackages) {
5785 final PackageParser.Package pkg = mPackages.get(packageName);
5787 throw new IllegalArgumentException("Unknown package: " + packageName);
5789 final PackageSetting ps = (PackageSetting) pkg.mExtras;
5791 || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
5792 throw new IllegalArgumentException("Unknown package: " + packageName);
5794 final BasePermission bp = mSettings.mPermissions.get(name);
5796 throw new IllegalArgumentException("Unknown permission: " + name);
5799 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
5801 // If a permission review is required for legacy apps we represent
5802 // their permissions as always granted runtime ones since we need
5803 // to keep the review required permission flag per user while an
5804 // install permission's state is shared across all users.
5805 if (mPermissionReviewRequired
5806 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
5807 && bp.isRuntime()) {
5811 final PermissionsState permissionsState = ps.getPermissionsState();
5813 final int flags = permissionsState.getPermissionFlags(name, userId);
5814 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
5815 throw new SecurityException("Cannot revoke system fixed permission "
5816 + name + " for package " + packageName);
5818 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
5819 throw new SecurityException("Cannot revoke policy fixed permission "
5820 + name + " for package " + packageName);
5823 if (bp.isDevelopment()) {
5824 // Development permissions must be handled specially, since they are not
5825 // normal runtime permissions. For now they apply to all users.
5826 if (permissionsState.revokeInstallPermission(bp) !=
5827 PermissionsState.PERMISSION_OPERATION_FAILURE) {
5828 scheduleWriteSettingsLocked();
5833 if (permissionsState.revokeRuntimePermission(bp, userId) ==
5834 PermissionsState.PERMISSION_OPERATION_FAILURE) {
5838 if (bp.isRuntime()) {
5839 logPermissionRevoked(mContext, name, packageName);
5842 mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
5844 // Critical, after this call app should never have the permission.
5845 mSettings.writeRuntimePermissionsForUserLPr(userId, true);
5847 appId = UserHandle.getAppId(pkg.applicationInfo.uid);
5850 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
5854 * We might auto-grant permissions if any permission of the group is already granted. Hence if
5855 * the group of a granted permission changes we need to revoke it to avoid having permissions of
5856 * the new group auto-granted.
5858 * @param newPackage The new package that was installed
5859 * @param oldPackage The old package that was updated
5860 * @param allPackageNames All package names
5862 private void revokeRuntimePermissionsIfGroupChanged(
5863 PackageParser.Package newPackage,
5864 PackageParser.Package oldPackage,
5865 ArrayList<String> allPackageNames) {
5866 final int numOldPackagePermissions = oldPackage.permissions.size();
5867 final ArrayMap<String, String> oldPermissionNameToGroupName
5868 = new ArrayMap<>(numOldPackagePermissions);
5870 for (int i = 0; i < numOldPackagePermissions; i++) {
5871 final PackageParser.Permission permission = oldPackage.permissions.get(i);
5873 if (permission.group != null) {
5874 oldPermissionNameToGroupName.put(permission.info.name,
5875 permission.group.info.name);
5879 final int numNewPackagePermissions = newPackage.permissions.size();
5880 for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions;
5881 newPermissionNum++) {
5882 final PackageParser.Permission newPermission =
5883 newPackage.permissions.get(newPermissionNum);
5884 final int newProtection = newPermission.info.protectionLevel;
5886 if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
5887 final String permissionName = newPermission.info.name;
5888 final String newPermissionGroupName =
5889 newPermission.group == null ? null : newPermission.group.info.name;
5890 final String oldPermissionGroupName = oldPermissionNameToGroupName.get(
5893 if (newPermissionGroupName != null
5894 && !newPermissionGroupName.equals(oldPermissionGroupName)) {
5895 final List<UserInfo> users = mContext.getSystemService(UserManager.class)
5898 final int numUsers = users.size();
5899 for (int userNum = 0; userNum < numUsers; userNum++) {
5900 final int userId = users.get(userNum).id;
5901 final int numPackages = allPackageNames.size();
5903 for (int packageNum = 0; packageNum < numPackages; packageNum++) {
5904 final String packageName = allPackageNames.get(packageNum);
5906 if (checkPermission(permissionName, packageName, userId)
5907 == PackageManager.PERMISSION_GRANTED) {
5908 EventLog.writeEvent(0x534e4554, "72710897",
5909 newPackage.applicationInfo.uid,
5910 "Revoking permission", permissionName, "from package",
5911 packageName, "as the group changed from",
5912 oldPermissionGroupName, "to", newPermissionGroupName);
5915 revokeRuntimePermission(packageName, permissionName, userId,
5917 } catch (IllegalArgumentException e) {
5918 Slog.e(TAG, "Could not revoke " + permissionName + " from "
5931 * Get the first event id for the permission.
5933 * <p>There are four events for each permission: <ul>
5934 * <li>Request permission: first id + 0</li>
5935 * <li>Grant permission: first id + 1</li>
5936 * <li>Request for permission denied: first id + 2</li>
5937 * <li>Revoke permission: first id + 3</li>
5940 * @param name name of the permission
5942 * @return The first event id for the permission
5944 private static int getBaseEventId(@NonNull String name) {
5945 int eventIdIndex = ALL_DANGEROUS_PERMISSIONS.indexOf(name);
5947 if (eventIdIndex == -1) {
5948 if (AppOpsManager.permissionToOpCode(name) == AppOpsManager.OP_NONE
5950 Log.i(TAG, "Unknown permission " + name);
5952 return MetricsEvent.ACTION_PERMISSION_REQUEST_UNKNOWN;
5954 // Most likely #ALL_DANGEROUS_PERMISSIONS needs to be updated.
5957 // - EventLogger#ALL_DANGEROUS_PERMISSIONS
5958 // - metrics_constants.proto
5959 throw new IllegalStateException("Unknown permission " + name);
5963 return MetricsEvent.ACTION_PERMISSION_REQUEST_READ_CALENDAR + eventIdIndex * 4;
5967 * Log that a permission was revoked.
5969 * @param context Context of the caller
5970 * @param name name of the permission
5971 * @param packageName package permission if for
5973 private static void logPermissionRevoked(@NonNull Context context, @NonNull String name,
5974 @NonNull String packageName) {
5975 MetricsLogger.action(context, getBaseEventId(name) + 3, packageName);
5979 * Log that a permission request was granted.
5981 * @param context Context of the caller
5982 * @param name name of the permission
5983 * @param packageName package permission if for
5985 private static void logPermissionGranted(@NonNull Context context, @NonNull String name,
5986 @NonNull String packageName) {
5987 MetricsLogger.action(context, getBaseEventId(name) + 1, packageName);
5991 public void resetRuntimePermissions() {
5992 mContext.enforceCallingOrSelfPermission(
5993 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5994 "revokeRuntimePermission");
5996 int callingUid = Binder.getCallingUid();
5997 if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5998 mContext.enforceCallingOrSelfPermission(
5999 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
6000 "resetRuntimePermissions");
6003 synchronized (mPackages) {
6004 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
6005 for (int userId : UserManagerService.getInstance().getUserIds()) {
6006 final int packageCount = mPackages.size();
6007 for (int i = 0; i < packageCount; i++) {
6008 PackageParser.Package pkg = mPackages.valueAt(i);
6009 if (!(pkg.mExtras instanceof PackageSetting)) {
6012 PackageSetting ps = (PackageSetting) pkg.mExtras;
6013 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
6020 public int getPermissionFlags(String name, String packageName, int userId) {
6021 if (!sUserManager.exists(userId)) {
6025 enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
6027 final int callingUid = Binder.getCallingUid();
6028 enforceCrossUserPermission(callingUid, userId,
6029 true /* requireFullPermission */, false /* checkShell */,
6030 "getPermissionFlags");
6032 synchronized (mPackages) {
6033 final PackageParser.Package pkg = mPackages.get(packageName);
6037 final BasePermission bp = mSettings.mPermissions.get(name);
6041 final PackageSetting ps = (PackageSetting) pkg.mExtras;
6043 || filterAppAccessLPr(ps, callingUid, userId)) {
6046 PermissionsState permissionsState = ps.getPermissionsState();
6047 return permissionsState.getPermissionFlags(name, userId);
6052 public void updatePermissionFlags(String name, String packageName, int flagMask,
6053 int flagValues, int userId) {
6054 if (!sUserManager.exists(userId)) {
6058 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
6060 final int callingUid = Binder.getCallingUid();
6061 enforceCrossUserPermission(callingUid, userId,
6062 true /* requireFullPermission */, true /* checkShell */,
6063 "updatePermissionFlags");
6065 // Only the system can change these flags and nothing else.
6066 if (getCallingUid() != Process.SYSTEM_UID) {
6067 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
6068 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
6069 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
6070 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
6071 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
6074 synchronized (mPackages) {
6075 final PackageParser.Package pkg = mPackages.get(packageName);
6077 throw new IllegalArgumentException("Unknown package: " + packageName);
6079 final PackageSetting ps = (PackageSetting) pkg.mExtras;
6081 || filterAppAccessLPr(ps, callingUid, userId)) {
6082 throw new IllegalArgumentException("Unknown package: " + packageName);
6085 final BasePermission bp = mSettings.mPermissions.get(name);
6087 throw new IllegalArgumentException("Unknown permission: " + name);
6090 PermissionsState permissionsState = ps.getPermissionsState();
6092 boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
6094 if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
6095 // Install and runtime permissions are stored in different places,
6096 // so figure out what permission changed and persist the change.
6097 if (permissionsState.getInstallPermissionState(name) != null) {
6098 scheduleWriteSettingsLocked();
6099 } else if (permissionsState.getRuntimePermissionState(name, userId) != null
6101 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
6108 * Update the permission flags for all packages and runtime permissions of a user in order
6109 * to allow device or profile owner to remove POLICY_FIXED.
6112 public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
6113 if (!sUserManager.exists(userId)) {
6117 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps");
6119 enforceCrossUserPermission(Binder.getCallingUid(), userId,
6120 true /* requireFullPermission */, true /* checkShell */,
6121 "updatePermissionFlagsForAllApps");
6123 // Only the system can change system fixed flags.
6124 if (getCallingUid() != Process.SYSTEM_UID) {
6125 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
6126 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
6129 synchronized (mPackages) {
6130 boolean changed = false;
6131 final int packageCount = mPackages.size();
6132 for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
6133 final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
6134 final PackageSetting ps = (PackageSetting) pkg.mExtras;
6138 PermissionsState permissionsState = ps.getPermissionsState();
6139 changed |= permissionsState.updatePermissionFlagsForAllPermissions(
6140 userId, flagMask, flagValues);
6143 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
6148 private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
6149 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
6150 != PackageManager.PERMISSION_GRANTED
6151 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
6152 != PackageManager.PERMISSION_GRANTED) {
6153 throw new SecurityException(message + " requires "
6154 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
6155 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
6160 public boolean shouldShowRequestPermissionRationale(String permissionName,
6161 String packageName, int userId) {
6162 if (UserHandle.getCallingUserId() != userId) {
6163 mContext.enforceCallingPermission(
6164 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
6165 "canShowRequestPermissionRationale for user " + userId);
6168 final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
6169 if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
6173 if (checkPermission(permissionName, packageName, userId)
6174 == PackageManager.PERMISSION_GRANTED) {
6180 final long identity = Binder.clearCallingIdentity();
6182 flags = getPermissionFlags(permissionName,
6183 packageName, userId);
6185 Binder.restoreCallingIdentity(identity);
6188 final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
6189 | PackageManager.FLAG_PERMISSION_POLICY_FIXED
6190 | PackageManager.FLAG_PERMISSION_USER_FIXED;
6192 if ((flags & fixedFlags) != 0) {
6196 return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
6200 public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
6201 mContext.enforceCallingOrSelfPermission(
6202 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
6203 "addOnPermissionsChangeListener");
6205 synchronized (mPackages) {
6206 mOnPermissionChangeListeners.addListenerLocked(listener);
6211 public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
6212 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6213 throw new SecurityException("Instant applications don't have access to this method");
6215 synchronized (mPackages) {
6216 mOnPermissionChangeListeners.removeListenerLocked(listener);
6221 public boolean isProtectedBroadcast(String actionName) {
6222 // allow instant applications
6223 synchronized (mProtectedBroadcasts) {
6224 if (mProtectedBroadcasts.contains(actionName)) {
6226 } else if (actionName != null) {
6227 // TODO: remove these terrible hacks
6228 if (actionName.startsWith("android.net.netmon.lingerExpired")
6229 || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
6230 || actionName.startsWith("com.android.internal.telephony.data-reconnect")
6231 || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
6240 public int checkSignatures(String pkg1, String pkg2) {
6241 synchronized (mPackages) {
6242 final PackageParser.Package p1 = mPackages.get(pkg1);
6243 final PackageParser.Package p2 = mPackages.get(pkg2);
6244 if (p1 == null || p1.mExtras == null
6245 || p2 == null || p2.mExtras == null) {
6246 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6248 final int callingUid = Binder.getCallingUid();
6249 final int callingUserId = UserHandle.getUserId(callingUid);
6250 final PackageSetting ps1 = (PackageSetting) p1.mExtras;
6251 final PackageSetting ps2 = (PackageSetting) p2.mExtras;
6252 if (filterAppAccessLPr(ps1, callingUid, callingUserId)
6253 || filterAppAccessLPr(ps2, callingUid, callingUserId)) {
6254 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6256 return compareSignatures(p1.mSignatures, p2.mSignatures);
6261 public int checkUidSignatures(int uid1, int uid2) {
6262 final int callingUid = Binder.getCallingUid();
6263 final int callingUserId = UserHandle.getUserId(callingUid);
6264 final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
6265 // Map to base uids.
6266 uid1 = UserHandle.getAppId(uid1);
6267 uid2 = UserHandle.getAppId(uid2);
6269 synchronized (mPackages) {
6272 Object obj = mSettings.getUserIdLPr(uid1);
6274 if (obj instanceof SharedUserSetting) {
6275 if (isCallerInstantApp) {
6276 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6278 s1 = ((SharedUserSetting)obj).signatures.mSignatures;
6279 } else if (obj instanceof PackageSetting) {
6280 final PackageSetting ps = (PackageSetting) obj;
6281 if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
6282 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6284 s1 = ps.signatures.mSignatures;
6286 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6289 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6291 obj = mSettings.getUserIdLPr(uid2);
6293 if (obj instanceof SharedUserSetting) {
6294 if (isCallerInstantApp) {
6295 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6297 s2 = ((SharedUserSetting)obj).signatures.mSignatures;
6298 } else if (obj instanceof PackageSetting) {
6299 final PackageSetting ps = (PackageSetting) obj;
6300 if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
6301 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6303 s2 = ps.signatures.mSignatures;
6305 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6308 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6310 return compareSignatures(s1, s2);
6315 * This method should typically only be used when granting or revoking
6316 * permissions, since the app may immediately restart after this call.
6318 * If you're doing surgery on app code/data, use {@link PackageFreezer} to
6319 * guard your work against the app being relaunched.
6321 private void killUid(int appId, int userId, String reason) {
6322 final long identity = Binder.clearCallingIdentity();
6324 IActivityManager am = ActivityManager.getService();
6327 am.killUid(appId, userId, reason);
6328 } catch (RemoteException e) {
6329 /* ignore - same process */
6333 Binder.restoreCallingIdentity(identity);
6338 * Compares two sets of signatures. Returns:
6340 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
6342 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
6344 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
6346 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
6348 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
6350 static int compareSignatures(Signature[] s1, Signature[] s2) {
6353 ? PackageManager.SIGNATURE_NEITHER_SIGNED
6354 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
6358 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
6361 if (s1.length != s2.length) {
6362 return PackageManager.SIGNATURE_NO_MATCH;
6365 // Since both signature sets are of size 1, we can compare without HashSets.
6366 if (s1.length == 1) {
6367 return s1[0].equals(s2[0]) ?
6368 PackageManager.SIGNATURE_MATCH :
6369 PackageManager.SIGNATURE_NO_MATCH;
6372 ArraySet<Signature> set1 = new ArraySet<Signature>();
6373 for (Signature sig : s1) {
6376 ArraySet<Signature> set2 = new ArraySet<Signature>();
6377 for (Signature sig : s2) {
6380 // Make sure s2 contains all signatures in s1.
6381 if (set1.equals(set2)) {
6382 return PackageManager.SIGNATURE_MATCH;
6384 return PackageManager.SIGNATURE_NO_MATCH;
6388 * If the database version for this type of package (internal storage or
6389 * external storage) is less than the version where package signatures
6390 * were updated, return true.
6392 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
6393 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
6394 return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
6398 * Used for backward compatibility to make sure any packages with
6399 * certificate chains get upgraded to the new style. {@code existingSigs}
6400 * will be in the old format (since they were stored on disk from before the
6401 * system upgrade) and {@code scannedSigs} will be in the newer format.
6403 private int compareSignaturesCompat(PackageSignatures existingSigs,
6404 PackageParser.Package scannedPkg) {
6405 if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
6406 return PackageManager.SIGNATURE_NO_MATCH;
6409 ArraySet<Signature> existingSet = new ArraySet<Signature>();
6410 for (Signature sig : existingSigs.mSignatures) {
6411 existingSet.add(sig);
6413 ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
6414 for (Signature sig : scannedPkg.mSignatures) {
6416 Signature[] chainSignatures = sig.getChainSignatures();
6417 for (Signature chainSig : chainSignatures) {
6418 scannedCompatSet.add(chainSig);
6420 } catch (CertificateEncodingException e) {
6421 scannedCompatSet.add(sig);
6425 * Make sure the expanded scanned set contains all signatures in the
6428 if (scannedCompatSet.equals(existingSet)) {
6429 // Migrate the old signatures to the new scheme.
6430 existingSigs.assignSignatures(scannedPkg.mSignatures);
6431 // The new KeySets will be re-added later in the scanning process.
6432 synchronized (mPackages) {
6433 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
6435 return PackageManager.SIGNATURE_MATCH;
6437 return PackageManager.SIGNATURE_NO_MATCH;
6440 private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
6441 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
6442 return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
6445 private int compareSignaturesRecover(PackageSignatures existingSigs,
6446 PackageParser.Package scannedPkg) {
6447 if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
6448 return PackageManager.SIGNATURE_NO_MATCH;
6453 if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
6454 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
6455 + scannedPkg.packageName);
6456 return PackageManager.SIGNATURE_MATCH;
6458 } catch (CertificateException e) {
6459 msg = e.getMessage();
6462 logCriticalInfo(Log.INFO,
6463 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
6464 return PackageManager.SIGNATURE_NO_MATCH;
6468 public List<String> getAllPackages() {
6469 final int callingUid = Binder.getCallingUid();
6470 final int callingUserId = UserHandle.getUserId(callingUid);
6471 synchronized (mPackages) {
6472 if (canViewInstantApps(callingUid, callingUserId)) {
6473 return new ArrayList<String>(mPackages.keySet());
6475 final String instantAppPkgName = getInstantAppPackageName(callingUid);
6476 final List<String> result = new ArrayList<>();
6477 if (instantAppPkgName != null) {
6478 // caller is an instant application; filter unexposed applications
6479 for (PackageParser.Package pkg : mPackages.values()) {
6480 if (!pkg.visibleToInstantApps) {
6483 result.add(pkg.packageName);
6486 // caller is a normal application; filter instant applications
6487 for (PackageParser.Package pkg : mPackages.values()) {
6488 final PackageSetting ps =
6489 pkg.mExtras != null ? (PackageSetting) pkg.mExtras : null;
6491 && ps.getInstantApp(callingUserId)
6492 && !mInstantAppRegistry.isInstantAccessGranted(
6493 callingUserId, UserHandle.getAppId(callingUid), ps.appId)) {
6496 result.add(pkg.packageName);
6504 public String[] getPackagesForUid(int uid) {
6505 final int callingUid = Binder.getCallingUid();
6506 final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
6507 final int userId = UserHandle.getUserId(uid);
6508 uid = UserHandle.getAppId(uid);
6510 synchronized (mPackages) {
6511 Object obj = mSettings.getUserIdLPr(uid);
6512 if (obj instanceof SharedUserSetting) {
6513 if (isCallerInstantApp) {
6516 final SharedUserSetting sus = (SharedUserSetting) obj;
6517 final int N = sus.packages.size();
6518 String[] res = new String[N];
6519 final Iterator<PackageSetting> it = sus.packages.iterator();
6521 while (it.hasNext()) {
6522 PackageSetting ps = it.next();
6523 if (ps.getInstalled(userId)) {
6526 res = ArrayUtils.removeElement(String.class, res, res[i]);
6530 } else if (obj instanceof PackageSetting) {
6531 final PackageSetting ps = (PackageSetting) obj;
6532 if (ps.getInstalled(userId) && !filterAppAccessLPr(ps, callingUid, userId)) {
6533 return new String[]{ps.name};
6541 public String getNameForUid(int uid) {
6542 final int callingUid = Binder.getCallingUid();
6543 if (getInstantAppPackageName(callingUid) != null) {
6546 synchronized (mPackages) {
6547 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6548 if (obj instanceof SharedUserSetting) {
6549 final SharedUserSetting sus = (SharedUserSetting) obj;
6550 return sus.name + ":" + sus.userId;
6551 } else if (obj instanceof PackageSetting) {
6552 final PackageSetting ps = (PackageSetting) obj;
6553 if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6563 public String[] getNamesForUids(int[] uids) {
6564 if (uids == null || uids.length == 0) {
6567 final int callingUid = Binder.getCallingUid();
6568 if (getInstantAppPackageName(callingUid) != null) {
6571 final String[] names = new String[uids.length];
6572 synchronized (mPackages) {
6573 for (int i = uids.length - 1; i >= 0; i--) {
6574 final int uid = uids[i];
6575 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6576 if (obj instanceof SharedUserSetting) {
6577 final SharedUserSetting sus = (SharedUserSetting) obj;
6578 names[i] = "shared:" + sus.name;
6579 } else if (obj instanceof PackageSetting) {
6580 final PackageSetting ps = (PackageSetting) obj;
6581 if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6595 public int getUidForSharedUser(String sharedUserName) {
6596 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6599 if (sharedUserName == null) {
6603 synchronized (mPackages) {
6604 SharedUserSetting suid;
6606 suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
6610 } catch (PackageManagerException ignore) {
6611 // can't happen, but, still need to catch it
6618 public int getFlagsForUid(int uid) {
6619 final int callingUid = Binder.getCallingUid();
6620 if (getInstantAppPackageName(callingUid) != null) {
6623 synchronized (mPackages) {
6624 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6625 if (obj instanceof SharedUserSetting) {
6626 final SharedUserSetting sus = (SharedUserSetting) obj;
6627 return sus.pkgFlags;
6628 } else if (obj instanceof PackageSetting) {
6629 final PackageSetting ps = (PackageSetting) obj;
6630 if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6640 public int getPrivateFlagsForUid(int uid) {
6641 final int callingUid = Binder.getCallingUid();
6642 if (getInstantAppPackageName(callingUid) != null) {
6645 synchronized (mPackages) {
6646 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6647 if (obj instanceof SharedUserSetting) {
6648 final SharedUserSetting sus = (SharedUserSetting) obj;
6649 return sus.pkgPrivateFlags;
6650 } else if (obj instanceof PackageSetting) {
6651 final PackageSetting ps = (PackageSetting) obj;
6652 if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6655 return ps.pkgPrivateFlags;
6662 public boolean isUidPrivileged(int uid) {
6663 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6666 uid = UserHandle.getAppId(uid);
6668 synchronized (mPackages) {
6669 Object obj = mSettings.getUserIdLPr(uid);
6670 if (obj instanceof SharedUserSetting) {
6671 final SharedUserSetting sus = (SharedUserSetting) obj;
6672 final Iterator<PackageSetting> it = sus.packages.iterator();
6673 while (it.hasNext()) {
6674 if (it.next().isPrivileged()) {
6678 } else if (obj instanceof PackageSetting) {
6679 final PackageSetting ps = (PackageSetting) obj;
6680 return ps.isPrivileged();
6687 public String[] getAppOpPermissionPackages(String permissionName) {
6688 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6691 synchronized (mPackages) {
6692 ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
6696 return pkgs.toArray(new String[pkgs.size()]);
6701 public ResolveInfo resolveIntent(Intent intent, String resolvedType,
6702 int flags, int userId) {
6703 return resolveIntentInternal(
6704 intent, resolvedType, flags, userId, false /*includeInstantApps*/);
6707 private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
6708 int flags, int userId, boolean resolveForStart) {
6710 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
6712 if (!sUserManager.exists(userId)) return null;
6713 final int callingUid = Binder.getCallingUid();
6714 flags = updateFlagsForResolve(flags, userId, intent, callingUid, resolveForStart);
6715 enforceCrossUserPermission(callingUid, userId,
6716 false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
6718 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6719 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
6720 flags, callingUid, userId, resolveForStart, true /*allowDynamicSplits*/);
6721 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6723 final ResolveInfo bestChoice =
6724 chooseBestActivity(intent, resolvedType, flags, query, userId);
6727 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6732 public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
6733 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
6734 throw new SecurityException(
6735 "findPersistentPreferredActivity can only be run by the system");
6737 if (!sUserManager.exists(userId)) {
6740 final int callingUid = Binder.getCallingUid();
6741 intent = updateIntentForResolve(intent);
6742 final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
6743 final int flags = updateFlagsForResolve(
6744 0, userId, intent, callingUid, false /*includeInstantApps*/);
6745 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6747 synchronized (mPackages) {
6748 return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
6754 public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
6755 IntentFilter filter, int match, ComponentName activity) {
6756 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6759 final int userId = UserHandle.getCallingUserId();
6760 if (DEBUG_PREFERRED) {
6761 Log.v(TAG, "setLastChosenActivity intent=" + intent
6762 + " resolvedType=" + resolvedType
6764 + " filter=" + filter
6766 + " activity=" + activity);
6767 filter.dump(new PrintStreamPrinter(System.out), " ");
6769 intent.setComponent(null);
6770 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6772 // Find any earlier preferred or last chosen entries and nuke them
6773 findPreferredActivity(intent, resolvedType,
6774 flags, query, 0, false, true, false, userId);
6775 // Add the new activity as the last chosen for this filter
6776 addPreferredActivityInternal(filter, match, null, activity, false, userId,
6777 "Setting last chosen");
6781 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
6782 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6785 final int userId = UserHandle.getCallingUserId();
6786 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
6787 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6789 return findPreferredActivity(intent, resolvedType, flags, query, 0,
6790 false, false, false, userId);
6794 * Returns whether or not instant apps have been disabled remotely.
6796 private boolean isEphemeralDisabled() {
6797 return mEphemeralAppsDisabled;
6800 private boolean isInstantAppAllowed(
6801 Intent intent, List<ResolveInfo> resolvedActivities, int userId,
6802 boolean skipPackageCheck) {
6803 if (mInstantAppResolverConnection == null) {
6806 if (mInstantAppInstallerActivity == null) {
6809 if (intent.getComponent() != null) {
6812 if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
6815 if (!skipPackageCheck && intent.getPackage() != null) {
6818 final boolean isWebUri = hasWebURI(intent);
6819 if (!isWebUri || intent.getData().getHost() == null) {
6822 // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
6823 // Or if there's already an ephemeral app installed that handles the action
6824 synchronized (mPackages) {
6825 final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
6826 for (int n = 0; n < count; n++) {
6827 final ResolveInfo info = resolvedActivities.get(n);
6828 final String packageName = info.activityInfo.packageName;
6829 final PackageSetting ps = mSettings.mPackages.get(packageName);
6831 // only check domain verification status if the app is not a browser
6832 if (!info.handleAllWebDataURI) {
6833 // Try to get the status from User settings first
6834 final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6835 final int status = (int) (packedStatus >> 32);
6836 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
6837 || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6838 if (DEBUG_EPHEMERAL) {
6839 Slog.v(TAG, "DENY instant app;"
6840 + " pkg: " + packageName + ", status: " + status);
6845 if (ps.getInstantApp(userId)) {
6846 if (DEBUG_EPHEMERAL) {
6847 Slog.v(TAG, "DENY instant app installed;"
6848 + " pkg: " + packageName);
6855 // We've exhausted all ways to deny ephemeral application; let the system look for them.
6859 private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
6860 Intent origIntent, String resolvedType, String callingPackage,
6861 Bundle verificationBundle, int userId) {
6862 final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
6863 new InstantAppRequest(responseObj, origIntent, resolvedType,
6864 callingPackage, userId, verificationBundle, false /*resolveForStart*/));
6865 mHandler.sendMessage(msg);
6868 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
6869 int flags, List<ResolveInfo> query, int userId) {
6870 if (query != null) {
6871 final int N = query.size();
6873 return query.get(0);
6875 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
6876 // If there is more than one activity with the same priority,
6877 // then let the user decide between them.
6878 ResolveInfo r0 = query.get(0);
6879 ResolveInfo r1 = query.get(1);
6880 if (DEBUG_INTENT_MATCHING || debug) {
6881 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
6882 + r1.activityInfo.name + "=" + r1.priority);
6884 // If the first activity has a higher priority, or a different
6885 // default, then it is always desirable to pick it.
6886 if (r0.priority != r1.priority
6887 || r0.preferredOrder != r1.preferredOrder
6888 || r0.isDefault != r1.isDefault) {
6889 return query.get(0);
6891 // If we have saved a preference for a preferred activity for
6892 // this Intent, use that.
6893 ResolveInfo ri = findPreferredActivity(intent, resolvedType,
6894 flags, query, r0.priority, true, false, debug, userId);
6898 // If we have an ephemeral app, use it
6899 for (int i = 0; i < N; i++) {
6901 if (ri.activityInfo.applicationInfo.isInstantApp()) {
6902 final String packageName = ri.activityInfo.packageName;
6903 final PackageSetting ps = mSettings.mPackages.get(packageName);
6904 final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6905 final int status = (int)(packedStatus >> 32);
6906 if (status != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6911 ri = new ResolveInfo(mResolveInfo);
6912 ri.activityInfo = new ActivityInfo(ri.activityInfo);
6913 ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
6914 // If all of the options come from the same package, show the application's
6915 // label and icon instead of the generic resolver's.
6916 // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
6917 // and then throw away the ResolveInfo itself, meaning that the caller loses
6918 // the resolvePackageName. Therefore the activityInfo.labelRes above provides
6919 // a fallback for this case; we only set the target package's resources on
6920 // the ResolveInfo, not the ActivityInfo.
6921 final String intentPackage = intent.getPackage();
6922 if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
6923 final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
6924 ri.resolvePackageName = intentPackage;
6925 if (userNeedsBadging(userId)) {
6926 ri.noResourceId = true;
6928 ri.icon = appi.icon;
6930 ri.iconResourceId = appi.icon;
6931 ri.labelRes = appi.labelRes;
6933 ri.activityInfo.applicationInfo = new ApplicationInfo(
6934 ri.activityInfo.applicationInfo);
6936 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
6937 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
6939 // Make sure that the resolver is displayable in car mode
6940 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
6941 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
6949 * Return true if the given list is not empty and all of its contents have
6950 * an activityInfo with the given package name.
6952 private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
6953 if (ArrayUtils.isEmpty(list)) {
6956 for (int i = 0, N = list.size(); i < N; i++) {
6957 final ResolveInfo ri = list.get(i);
6958 final ActivityInfo ai = ri != null ? ri.activityInfo : null;
6959 if (ai == null || !packageName.equals(ai.packageName)) {
6966 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
6967 int flags, List<ResolveInfo> query, boolean debug, int userId) {
6968 final int N = query.size();
6969 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
6971 // Get the list of persistent preferred activities that handle the intent
6972 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
6973 List<PersistentPreferredActivity> pprefs = ppir != null
6974 ? ppir.queryIntent(intent, resolvedType,
6975 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6978 if (pprefs != null && pprefs.size() > 0) {
6979 final int M = pprefs.size();
6980 for (int i=0; i<M; i++) {
6981 final PersistentPreferredActivity ppa = pprefs.get(i);
6982 if (DEBUG_PREFERRED || debug) {
6983 Slog.v(TAG, "Checking PersistentPreferredActivity ds="
6984 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
6985 + "\n component=" + ppa.mComponent);
6986 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
6988 final ActivityInfo ai = getActivityInfo(ppa.mComponent,
6989 flags | MATCH_DISABLED_COMPONENTS, userId);
6990 if (DEBUG_PREFERRED || debug) {
6991 Slog.v(TAG, "Found persistent preferred activity:");
6993 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
6995 Slog.v(TAG, " null");
6999 // This previously registered persistent preferred activity
7000 // component is no longer known. Ignore it and do NOT remove it.
7003 for (int j=0; j<N; j++) {
7004 final ResolveInfo ri = query.get(j);
7005 if (!ri.activityInfo.applicationInfo.packageName
7006 .equals(ai.applicationInfo.packageName)) {
7009 if (!ri.activityInfo.name.equals(ai.name)) {
7012 // Found a persistent preference that can handle the intent.
7013 if (DEBUG_PREFERRED || debug) {
7014 Slog.v(TAG, "Returning persistent preferred activity: " +
7015 ri.activityInfo.packageName + "/" + ri.activityInfo.name);
7024 // TODO: handle preferred activities missing while user has amnesia
7025 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
7026 List<ResolveInfo> query, int priority, boolean always,
7027 boolean removeMatches, boolean debug, int userId) {
7028 if (!sUserManager.exists(userId)) return null;
7029 final int callingUid = Binder.getCallingUid();
7030 flags = updateFlagsForResolve(
7031 flags, userId, intent, callingUid, false /*includeInstantApps*/);
7032 intent = updateIntentForResolve(intent);
7034 synchronized (mPackages) {
7035 // Try to find a matching persistent preferred activity.
7036 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
7039 // If a persistent preferred activity matched, use it.
7044 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
7045 // Get the list of preferred activities that handle the intent
7046 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
7047 List<PreferredActivity> prefs = pir != null
7048 ? pir.queryIntent(intent, resolvedType,
7049 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
7052 if (prefs != null && prefs.size() > 0) {
7053 boolean changed = false;
7055 // First figure out how good the original match set is.
7056 // We will only allow preferred activities that came
7057 // from the same match quality.
7060 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
7062 final int N = query.size();
7063 for (int j=0; j<N; j++) {
7064 final ResolveInfo ri = query.get(j);
7065 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
7066 + ": 0x" + Integer.toHexString(match));
7067 if (ri.match > match) {
7072 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
7073 + Integer.toHexString(match));
7075 match &= IntentFilter.MATCH_CATEGORY_MASK;
7076 final int M = prefs.size();
7077 for (int i=0; i<M; i++) {
7078 final PreferredActivity pa = prefs.get(i);
7079 if (DEBUG_PREFERRED || debug) {
7080 Slog.v(TAG, "Checking PreferredActivity ds="
7081 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
7082 + "\n component=" + pa.mPref.mComponent);
7083 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
7085 if (pa.mPref.mMatch != match) {
7086 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
7087 + Integer.toHexString(pa.mPref.mMatch));
7090 // If it's not an "always" type preferred activity and that's what we're
7091 // looking for, skip it.
7092 if (always && !pa.mPref.mAlways) {
7093 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
7096 final ActivityInfo ai = getActivityInfo(
7097 pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
7098 | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
7100 if (DEBUG_PREFERRED || debug) {
7101 Slog.v(TAG, "Found preferred activity:");
7103 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
7105 Slog.v(TAG, " null");
7109 // This previously registered preferred activity
7110 // component is no longer known. Most likely an update
7111 // to the app was installed and in the new version this
7112 // component no longer exists. Clean it up by removing
7113 // it from the preferred activities list, and skip it.
7114 Slog.w(TAG, "Removing dangling preferred activity: "
7115 + pa.mPref.mComponent);
7116 pir.removeFilter(pa);
7120 for (int j=0; j<N; j++) {
7121 final ResolveInfo ri = query.get(j);
7122 if (!ri.activityInfo.applicationInfo.packageName
7123 .equals(ai.applicationInfo.packageName)) {
7126 if (!ri.activityInfo.name.equals(ai.name)) {
7130 if (removeMatches) {
7131 pir.removeFilter(pa);
7133 if (DEBUG_PREFERRED) {
7134 Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
7139 // Okay we found a previously set preferred or last chosen app.
7140 // If the result set is different from when this
7141 // was created, and is not a subset of the preferred set, we need to
7142 // clear it and re-ask the user their preference, if we're looking for
7143 // an "always" type entry.
7144 if (always && !pa.mPref.sameSet(query)) {
7145 if (pa.mPref.isSuperset(query)) {
7146 // some components of the set are no longer present in
7147 // the query, but the preferred activity can still be reused
7148 if (DEBUG_PREFERRED) {
7149 Slog.i(TAG, "Result set changed, but PreferredActivity is"
7150 + " still valid as only non-preferred components"
7151 + " were removed for " + intent + " type "
7154 // remove obsolete components and re-add the up-to-date filter
7155 PreferredActivity freshPa = new PreferredActivity(pa,
7157 pa.mPref.discardObsoleteComponents(query),
7158 pa.mPref.mComponent,
7160 pir.removeFilter(pa);
7161 pir.addFilter(freshPa);
7165 "Result set changed, dropping preferred activity for "
7166 + intent + " type " + resolvedType);
7167 if (DEBUG_PREFERRED) {
7168 Slog.v(TAG, "Removing preferred activity since set changed "
7169 + pa.mPref.mComponent);
7171 pir.removeFilter(pa);
7172 // Re-add the filter as a "last chosen" entry (!always)
7173 PreferredActivity lastChosen = new PreferredActivity(
7174 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
7175 pir.addFilter(lastChosen);
7181 // Yay! Either the set matched or we're looking for the last chosen
7182 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
7183 + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
7189 if (DEBUG_PREFERRED) {
7190 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
7192 scheduleWritePackageRestrictionsLocked(userId);
7197 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
7202 * Returns if intent can be forwarded from the sourceUserId to the targetUserId
7205 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
7207 mContext.enforceCallingOrSelfPermission(
7208 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
7209 List<CrossProfileIntentFilter> matches =
7210 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
7211 if (matches != null) {
7212 int size = matches.size();
7213 for (int i = 0; i < size; i++) {
7214 if (matches.get(i).getTargetUserId() == targetUserId) return true;
7217 if (hasWebURI(intent)) {
7218 // cross-profile app linking works only towards the parent.
7219 final int callingUid = Binder.getCallingUid();
7220 final UserInfo parent = getProfileParent(sourceUserId);
7221 synchronized(mPackages) {
7222 int flags = updateFlagsForResolve(0, parent.id, intent, callingUid,
7223 false /*includeInstantApps*/);
7224 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
7225 intent, resolvedType, flags, sourceUserId, parent.id);
7226 return xpDomainInfo != null;
7232 private UserInfo getProfileParent(int userId) {
7233 final long identity = Binder.clearCallingIdentity();
7235 return sUserManager.getProfileParent(userId);
7237 Binder.restoreCallingIdentity(identity);
7241 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
7242 String resolvedType, int userId) {
7243 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
7244 if (resolver != null) {
7245 return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
7251 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
7252 String resolvedType, int flags, int userId) {
7254 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
7256 return new ParceledListSlice<>(
7257 queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
7259 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7264 * Returns the package name of the calling Uid if it's an instant app. If it isn't
7265 * instant, returns {@code null}.
7267 private String getInstantAppPackageName(int callingUid) {
7268 synchronized (mPackages) {
7269 // If the caller is an isolated app use the owner's uid for the lookup.
7270 if (Process.isIsolated(callingUid)) {
7271 callingUid = mIsolatedOwners.get(callingUid);
7273 final int appId = UserHandle.getAppId(callingUid);
7274 final Object obj = mSettings.getUserIdLPr(appId);
7275 if (obj instanceof PackageSetting) {
7276 final PackageSetting ps = (PackageSetting) obj;
7277 final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
7278 return isInstantApp ? ps.pkg.packageName : null;
7284 private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
7285 String resolvedType, int flags, int userId) {
7286 return queryIntentActivitiesInternal(
7287 intent, resolvedType, flags, Binder.getCallingUid(), userId,
7288 false /*resolveForStart*/, true /*allowDynamicSplits*/);
7291 private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
7292 String resolvedType, int flags, int filterCallingUid, int userId,
7293 boolean resolveForStart, boolean allowDynamicSplits) {
7294 if (!sUserManager.exists(userId)) return Collections.emptyList();
7295 final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
7296 enforceCrossUserPermission(Binder.getCallingUid(), userId,
7297 false /* requireFullPermission */, false /* checkShell */,
7298 "query intent activities");
7299 final String pkgName = intent.getPackage();
7300 ComponentName comp = intent.getComponent();
7302 if (intent.getSelector() != null) {
7303 intent = intent.getSelector();
7304 comp = intent.getComponent();
7308 flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart,
7309 comp != null || pkgName != null /*onlyExposedExplicitly*/);
7311 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7312 final ActivityInfo ai = getActivityInfo(comp, flags, userId);
7314 // When specifying an explicit component, we prevent the activity from being
7315 // used when either 1) the calling package is normal and the activity is within
7316 // an ephemeral application or 2) the calling package is ephemeral and the
7317 // activity is not visible to ephemeral applications.
7318 final boolean matchInstantApp =
7319 (flags & PackageManager.MATCH_INSTANT) != 0;
7320 final boolean matchVisibleToInstantAppOnly =
7321 (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7322 final boolean matchExplicitlyVisibleOnly =
7323 (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
7324 final boolean isCallerInstantApp =
7325 instantAppPkgName != null;
7326 final boolean isTargetSameInstantApp =
7327 comp.getPackageName().equals(instantAppPkgName);
7328 final boolean isTargetInstantApp =
7329 (ai.applicationInfo.privateFlags
7330 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7331 final boolean isTargetVisibleToInstantApp =
7332 (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
7333 final boolean isTargetExplicitlyVisibleToInstantApp =
7334 isTargetVisibleToInstantApp
7335 && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
7336 final boolean isTargetHiddenFromInstantApp =
7337 !isTargetVisibleToInstantApp
7338 || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
7339 final boolean blockResolution =
7340 !isTargetSameInstantApp
7341 && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7342 || (matchVisibleToInstantAppOnly && isCallerInstantApp
7343 && isTargetHiddenFromInstantApp));
7344 if (!blockResolution) {
7345 final ResolveInfo ri = new ResolveInfo();
7346 ri.activityInfo = ai;
7350 return applyPostResolutionFilter(
7351 list, instantAppPkgName, allowDynamicSplits, filterCallingUid, userId);
7355 boolean sortResult = false;
7356 boolean addEphemeral = false;
7357 List<ResolveInfo> result;
7358 final boolean ephemeralDisabled = isEphemeralDisabled();
7359 synchronized (mPackages) {
7360 if (pkgName == null) {
7361 List<CrossProfileIntentFilter> matchingFilters =
7362 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
7363 // Check for results that need to skip the current profile.
7364 ResolveInfo xpResolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent,
7365 resolvedType, flags, userId);
7366 if (xpResolveInfo != null) {
7367 List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
7368 xpResult.add(xpResolveInfo);
7369 return applyPostResolutionFilter(
7370 filterIfNotSystemUser(xpResult, userId), instantAppPkgName,
7371 allowDynamicSplits, filterCallingUid, userId);
7374 // Check for results in the current profile.
7375 result = filterIfNotSystemUser(mActivities.queryIntent(
7376 intent, resolvedType, flags, userId), userId);
7377 addEphemeral = !ephemeralDisabled
7378 && isInstantAppAllowed(intent, result, userId, false /*skipPackageCheck*/);
7379 // Check for cross profile results.
7380 boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
7381 xpResolveInfo = queryCrossProfileIntents(
7382 matchingFilters, intent, resolvedType, flags, userId,
7383 hasNonNegativePriorityResult);
7384 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
7385 boolean isVisibleToUser = filterIfNotSystemUser(
7386 Collections.singletonList(xpResolveInfo), userId).size() > 0;
7387 if (isVisibleToUser) {
7388 result.add(xpResolveInfo);
7392 if (hasWebURI(intent)) {
7393 CrossProfileDomainInfo xpDomainInfo = null;
7394 final UserInfo parent = getProfileParent(userId);
7395 if (parent != null) {
7396 xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
7397 flags, userId, parent.id);
7399 if (xpDomainInfo != null) {
7400 if (xpResolveInfo != null) {
7401 // If we didn't remove it, the cross-profile ResolveInfo would be twice
7403 result.remove(xpResolveInfo);
7405 if (result.size() == 0 && !addEphemeral) {
7406 // No result in current profile, but found candidate in parent user.
7407 // And we are not going to add emphemeral app, so we can return the
7408 // result straight away.
7409 result.add(xpDomainInfo.resolveInfo);
7410 return applyPostResolutionFilter(result, instantAppPkgName,
7411 allowDynamicSplits, filterCallingUid, userId);
7413 } else if (result.size() <= 1 && !addEphemeral) {
7414 // No result in parent user and <= 1 result in current profile, and we
7415 // are not going to add emphemeral app, so we can return the result without
7416 // further processing.
7417 return applyPostResolutionFilter(result, instantAppPkgName,
7418 allowDynamicSplits, filterCallingUid, userId);
7420 // We have more than one candidate (combining results from current and parent
7421 // profile), so we need filtering and sorting.
7422 result = filterCandidatesWithDomainPreferredActivitiesLPr(
7423 intent, flags, result, xpDomainInfo, userId);
7427 final PackageParser.Package pkg = mPackages.get(pkgName);
7430 result = filterIfNotSystemUser(
7431 mActivities.queryIntentForPackage(
7432 intent, resolvedType, flags, pkg.activities, userId),
7435 if (result == null || result.size() == 0) {
7436 // the caller wants to resolve for a particular package; however, there
7437 // were no installed results, so, try to find an ephemeral result
7438 addEphemeral = !ephemeralDisabled
7439 && isInstantAppAllowed(
7440 intent, null /*result*/, userId, true /*skipPackageCheck*/);
7441 if (result == null) {
7442 result = new ArrayList<>();
7448 result = maybeAddInstantAppInstaller(
7449 result, intent, resolvedType, flags, userId, resolveForStart);
7452 Collections.sort(result, mResolvePrioritySorter);
7454 return applyPostResolutionFilter(
7455 result, instantAppPkgName, allowDynamicSplits, filterCallingUid, userId);
7458 private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent,
7459 String resolvedType, int flags, int userId, boolean resolveForStart) {
7460 // first, check to see if we've got an instant app already installed
7461 final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
7462 ResolveInfo localInstantApp = null;
7463 boolean blockResolution = false;
7464 if (!alreadyResolvedLocally) {
7465 final List<ResolveInfo> instantApps = mActivities.queryIntent(intent, resolvedType,
7467 | PackageManager.GET_RESOLVED_FILTER
7468 | PackageManager.MATCH_INSTANT
7469 | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY,
7471 for (int i = instantApps.size() - 1; i >= 0; --i) {
7472 final ResolveInfo info = instantApps.get(i);
7473 final String packageName = info.activityInfo.packageName;
7474 final PackageSetting ps = mSettings.mPackages.get(packageName);
7475 if (ps.getInstantApp(userId)) {
7476 final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
7477 final int status = (int)(packedStatus >> 32);
7478 final int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
7479 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7480 // there's a local instant application installed, but, the user has
7481 // chosen to never use it; skip resolution and don't acknowledge
7482 // an instant application is even available
7483 if (DEBUG_EPHEMERAL) {
7484 Slog.v(TAG, "Instant app marked to never run; pkg: " + packageName);
7486 blockResolution = true;
7489 // we have a locally installed instant application; skip resolution
7490 // but acknowledge there's an instant application available
7491 if (DEBUG_EPHEMERAL) {
7492 Slog.v(TAG, "Found installed instant app; pkg: " + packageName);
7494 localInstantApp = info;
7500 // no app installed, let's see if one's available
7501 AuxiliaryResolveInfo auxiliaryResponse = null;
7502 if (!blockResolution) {
7503 if (localInstantApp == null) {
7504 // we don't have an instant app locally, resolve externally
7505 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
7506 final InstantAppRequest requestObject = new InstantAppRequest(
7507 null /*responseObj*/, intent /*origIntent*/, resolvedType,
7508 null /*callingPackage*/, userId, null /*verificationBundle*/,
7511 InstantAppResolver.doInstantAppResolutionPhaseOne(
7512 mContext, mInstantAppResolverConnection, requestObject);
7513 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7515 // we have an instant application locally, but, we can't admit that since
7516 // callers shouldn't be able to determine prior browsing. create a dummy
7517 // auxiliary response so the downstream code behaves as if there's an
7518 // instant application available externally. when it comes time to start
7519 // the instant application, we'll do the right thing.
7520 final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
7521 auxiliaryResponse = new AuxiliaryResolveInfo(
7522 ai.packageName, null /*splitName*/, null /*failureActivity*/,
7523 ai.versionCode, null /*failureIntent*/);
7526 if (auxiliaryResponse != null) {
7527 if (DEBUG_EPHEMERAL) {
7528 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7530 final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
7531 final PackageSetting ps =
7532 mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
7534 ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
7535 mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
7536 ephemeralInstaller.activityInfo.launchToken = auxiliaryResponse.token;
7537 ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
7538 // make sure this resolver is the default
7539 ephemeralInstaller.isDefault = true;
7540 ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7541 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7542 // add a non-generic filter
7543 ephemeralInstaller.filter = new IntentFilter(intent.getAction());
7544 ephemeralInstaller.filter.addDataPath(
7545 intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
7546 ephemeralInstaller.isInstantAppAvailable = true;
7547 result.add(ephemeralInstaller);
7553 private static class CrossProfileDomainInfo {
7554 /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
7555 ResolveInfo resolveInfo;
7556 /* Best domain verification status of the activities found in the other profile */
7557 int bestDomainVerificationStatus;
7560 private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
7561 String resolvedType, int flags, int sourceUserId, int parentUserId) {
7562 if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
7566 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
7567 resolvedType, flags, parentUserId);
7569 if (resultTargetUser == null || resultTargetUser.isEmpty()) {
7572 CrossProfileDomainInfo result = null;
7573 int size = resultTargetUser.size();
7574 for (int i = 0; i < size; i++) {
7575 ResolveInfo riTargetUser = resultTargetUser.get(i);
7576 // Intent filter verification is only for filters that specify a host. So don't return
7577 // those that handle all web uris.
7578 if (riTargetUser.handleAllWebDataURI) {
7581 String packageName = riTargetUser.activityInfo.packageName;
7582 PackageSetting ps = mSettings.mPackages.get(packageName);
7586 long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
7587 int status = (int)(verificationState >> 32);
7588 if (result == null) {
7589 result = new CrossProfileDomainInfo();
7590 result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
7591 sourceUserId, parentUserId);
7592 result.bestDomainVerificationStatus = status;
7594 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
7595 result.bestDomainVerificationStatus);
7598 // Don't consider matches with status NEVER across profiles.
7599 if (result != null && result.bestDomainVerificationStatus
7600 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7607 * Verification statuses are ordered from the worse to the best, except for
7608 * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
7610 private int bestDomainVerificationStatus(int status1, int status2) {
7611 if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7614 if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7617 return (int) MathUtils.max(status1, status2);
7620 private boolean isUserEnabled(int userId) {
7621 long callingId = Binder.clearCallingIdentity();
7623 UserInfo userInfo = sUserManager.getUserInfo(userId);
7624 return userInfo != null && userInfo.isEnabled();
7626 Binder.restoreCallingIdentity(callingId);
7631 * Filter out activities with systemUserOnly flag set, when current user is not System.
7633 * @return filtered list
7635 private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
7636 if (userId == UserHandle.USER_SYSTEM) {
7637 return resolveInfos;
7639 for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7640 ResolveInfo info = resolveInfos.get(i);
7641 if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
7642 resolveInfos.remove(i);
7645 return resolveInfos;
7649 * Filters out ephemeral activities.
7650 * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
7651 * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
7653 * @param resolveInfos The pre-filtered list of resolved activities
7654 * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
7656 * @return A filtered list of resolved activities.
7658 private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
7659 String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid, int userId) {
7660 for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7661 final ResolveInfo info = resolveInfos.get(i);
7662 // allow activities that are defined in the provided package
7663 if (allowDynamicSplits
7664 && info.activityInfo.splitName != null
7665 && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
7666 info.activityInfo.splitName)) {
7667 if (mInstantAppInstallerInfo == null) {
7668 if (DEBUG_INSTALL) {
7669 Slog.v(TAG, "No installer - not adding it to the ResolveInfo list");
7671 resolveInfos.remove(i);
7674 // requested activity is defined in a split that hasn't been installed yet.
7675 // add the installer to the resolve list
7676 if (DEBUG_INSTALL) {
7677 Slog.v(TAG, "Adding installer to the ResolveInfo list");
7679 final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7680 final ComponentName installFailureActivity = findInstallFailureActivity(
7681 info.activityInfo.packageName, filterCallingUid, userId);
7682 installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7683 info.activityInfo.packageName, info.activityInfo.splitName,
7684 installFailureActivity,
7685 info.activityInfo.applicationInfo.versionCode,
7686 null /*failureIntent*/);
7687 installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7688 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7689 // add a non-generic filter
7690 installerInfo.filter = new IntentFilter();
7692 // This resolve info may appear in the chooser UI, so let us make it
7693 // look as the one it replaces as far as the user is concerned which
7694 // requires loading the correct label and icon for the resolve info.
7695 installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7696 installerInfo.labelRes = info.resolveLabelResId();
7697 installerInfo.icon = info.resolveIconResId();
7699 // propagate priority/preferred order/default
7700 installerInfo.priority = info.priority;
7701 installerInfo.preferredOrder = info.preferredOrder;
7702 installerInfo.isDefault = info.isDefault;
7703 resolveInfos.set(i, installerInfo);
7706 // caller is a full app, don't need to apply any other filtering
7707 if (ephemeralPkgName == null) {
7709 } else if (ephemeralPkgName.equals(info.activityInfo.packageName)) {
7710 // caller is same app; don't need to apply any other filtering
7713 // allow activities that have been explicitly exposed to ephemeral apps
7714 final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
7716 && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7719 resolveInfos.remove(i);
7721 return resolveInfos;
7725 * Returns the activity component that can handle install failures.
7726 * <p>By default, the instant application installer handles failures. However, an
7727 * application may want to handle failures on its own. Applications do this by
7728 * creating an activity with an intent filter that handles the action
7729 * {@link Intent#ACTION_INSTALL_FAILURE}.
7731 private @Nullable ComponentName findInstallFailureActivity(
7732 String packageName, int filterCallingUid, int userId) {
7733 final Intent failureActivityIntent = new Intent(Intent.ACTION_INSTALL_FAILURE);
7734 failureActivityIntent.setPackage(packageName);
7735 // IMPORTANT: disallow dynamic splits to avoid an infinite loop
7736 final List<ResolveInfo> result = queryIntentActivitiesInternal(
7737 failureActivityIntent, null /*resolvedType*/, 0 /*flags*/, filterCallingUid, userId,
7738 false /*resolveForStart*/, false /*allowDynamicSplits*/);
7739 final int NR = result.size();
7741 for (int i = 0; i < NR; i++) {
7742 final ResolveInfo info = result.get(i);
7743 if (info.activityInfo.splitName != null) {
7746 return new ComponentName(packageName, info.activityInfo.name);
7753 * @param resolveInfos list of resolve infos in descending priority order
7754 * @return if the list contains a resolve info with non-negative priority
7756 private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
7757 return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
7760 private static boolean hasWebURI(Intent intent) {
7761 if (intent.getData() == null) {
7764 final String scheme = intent.getScheme();
7765 if (TextUtils.isEmpty(scheme)) {
7768 return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
7771 private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
7772 int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
7774 final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
7776 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7777 Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
7781 ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
7782 ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
7783 ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
7784 ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
7785 ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
7786 ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
7788 synchronized (mPackages) {
7789 final int count = candidates.size();
7790 // First, try to use linked apps. Partition the candidates into four lists:
7791 // one for the final results, one for the "do not use ever", one for "undefined status"
7792 // and finally one for "browser app type".
7793 for (int n=0; n<count; n++) {
7794 ResolveInfo info = candidates.get(n);
7795 String packageName = info.activityInfo.packageName;
7796 PackageSetting ps = mSettings.mPackages.get(packageName);
7798 // Add to the special match all list (Browser use case)
7799 if (info.handleAllWebDataURI) {
7800 matchAllList.add(info);
7803 // Try to get the status from User settings first
7804 long packedStatus = getDomainVerificationStatusLPr(ps, userId);
7805 int status = (int)(packedStatus >> 32);
7806 int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
7807 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
7808 if (DEBUG_DOMAIN_VERIFICATION || debug) {
7809 Slog.i(TAG, " + always: " + info.activityInfo.packageName
7810 + " : linkgen=" + linkGeneration);
7812 // Use link-enabled generation as preferredOrder, i.e.
7813 // prefer newly-enabled over earlier-enabled.
7814 info.preferredOrder = linkGeneration;
7815 alwaysList.add(info);
7816 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7817 if (DEBUG_DOMAIN_VERIFICATION || debug) {
7818 Slog.i(TAG, " + never: " + info.activityInfo.packageName);
7820 neverList.add(info);
7821 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
7822 if (DEBUG_DOMAIN_VERIFICATION || debug) {
7823 Slog.i(TAG, " + always-ask: " + info.activityInfo.packageName);
7825 alwaysAskList.add(info);
7826 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
7827 status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
7828 if (DEBUG_DOMAIN_VERIFICATION || debug) {
7829 Slog.i(TAG, " + ask: " + info.activityInfo.packageName);
7831 undefinedList.add(info);
7836 // We'll want to include browser possibilities in a few cases
7837 boolean includeBrowser = false;
7839 // First try to add the "always" resolution(s) for the current user, if any
7840 if (alwaysList.size() > 0) {
7841 result.addAll(alwaysList);
7843 // Add all undefined apps as we want them to appear in the disambiguation dialog.
7844 result.addAll(undefinedList);
7845 // Maybe add one for the other profile.
7846 if (xpDomainInfo != null && (
7847 xpDomainInfo.bestDomainVerificationStatus
7848 != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
7849 result.add(xpDomainInfo.resolveInfo);
7851 includeBrowser = true;
7854 // The presence of any 'always ask' alternatives means we'll also offer browsers.
7855 // If there were 'always' entries their preferred order has been set, so we also
7856 // back that off to make the alternatives equivalent
7857 if (alwaysAskList.size() > 0) {
7858 for (ResolveInfo i : result) {
7859 i.preferredOrder = 0;
7861 result.addAll(alwaysAskList);
7862 includeBrowser = true;
7865 if (includeBrowser) {
7866 // Also add browsers (all of them or only the default one)
7867 if (DEBUG_DOMAIN_VERIFICATION) {
7868 Slog.v(TAG, " ...including browsers in candidate set");
7870 if ((matchFlags & MATCH_ALL) != 0) {
7871 result.addAll(matchAllList);
7873 // Browser/generic handling case. If there's a default browser, go straight
7874 // to that (but only if there is no other higher-priority match).
7875 final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
7876 int maxMatchPrio = 0;
7877 ResolveInfo defaultBrowserMatch = null;
7878 final int numCandidates = matchAllList.size();
7879 for (int n = 0; n < numCandidates; n++) {
7880 ResolveInfo info = matchAllList.get(n);
7881 // track the highest overall match priority...
7882 if (info.priority > maxMatchPrio) {
7883 maxMatchPrio = info.priority;
7885 // ...and the highest-priority default browser match
7886 if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
7887 if (defaultBrowserMatch == null
7888 || (defaultBrowserMatch.priority < info.priority)) {
7890 Slog.v(TAG, "Considering default browser match " + info);
7892 defaultBrowserMatch = info;
7896 if (defaultBrowserMatch != null
7897 && defaultBrowserMatch.priority >= maxMatchPrio
7898 && !TextUtils.isEmpty(defaultBrowserPackageName))
7901 Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
7903 result.add(defaultBrowserMatch);
7905 result.addAll(matchAllList);
7909 // If there is nothing selected, add all candidates and remove the ones that the user
7910 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
7911 if (result.size() == 0) {
7912 result.addAll(candidates);
7913 result.removeAll(neverList);
7917 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7918 Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
7920 for (ResolveInfo info : result) {
7921 Slog.v(TAG, " + " + info.activityInfo);
7927 // Returns a packed value as a long:
7929 // high 'int'-sized word: link status: undefined/ask/never/always.
7930 // low 'int'-sized word: relative priority among 'always' results.
7931 private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
7932 long result = ps.getDomainVerificationStatusForUser(userId);
7933 // if none available, get the master status
7934 if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
7935 if (ps.getIntentFilterVerificationInfo() != null) {
7936 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
7942 private ResolveInfo querySkipCurrentProfileIntents(
7943 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7944 int flags, int sourceUserId) {
7945 if (matchingFilters != null) {
7946 int size = matchingFilters.size();
7947 for (int i = 0; i < size; i ++) {
7948 CrossProfileIntentFilter filter = matchingFilters.get(i);
7949 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
7950 // Checking if there are activities in the target user that can handle the
7952 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7953 resolvedType, flags, sourceUserId);
7954 if (resolveInfo != null) {
7963 // Return matching ResolveInfo in target user if any.
7964 private ResolveInfo queryCrossProfileIntents(
7965 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7966 int flags, int sourceUserId, boolean matchInCurrentProfile) {
7967 if (matchingFilters != null) {
7968 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
7969 // match the same intent. For performance reasons, it is better not to
7970 // run queryIntent twice for the same userId
7971 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
7972 int size = matchingFilters.size();
7973 for (int i = 0; i < size; i++) {
7974 CrossProfileIntentFilter filter = matchingFilters.get(i);
7975 int targetUserId = filter.getTargetUserId();
7976 boolean skipCurrentProfile =
7977 (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
7978 boolean skipCurrentProfileIfNoMatchFound =
7979 (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
7980 if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
7981 && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
7982 // Checking if there are activities in the target user that can handle the
7984 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7985 resolvedType, flags, sourceUserId);
7986 if (resolveInfo != null) return resolveInfo;
7987 alreadyTriedUserIds.put(targetUserId, true);
7995 * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
7996 * will forward the intent to the filter's target user.
7997 * Otherwise, returns null.
7999 private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
8000 String resolvedType, int flags, int sourceUserId) {
8001 int targetUserId = filter.getTargetUserId();
8002 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
8003 resolvedType, flags, targetUserId);
8004 if (resultTargetUser != null && isUserEnabled(targetUserId)) {
8005 // If all the matches in the target profile are suspended, return null.
8006 for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
8007 if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
8008 & ApplicationInfo.FLAG_SUSPENDED) == 0) {
8009 return createForwardingResolveInfoUnchecked(filter, sourceUserId,
8017 private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
8018 int sourceUserId, int targetUserId) {
8019 ResolveInfo forwardingResolveInfo = new ResolveInfo();
8020 long ident = Binder.clearCallingIdentity();
8021 boolean targetIsProfile;
8023 targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
8025 Binder.restoreCallingIdentity(ident);
8028 if (targetIsProfile) {
8029 className = FORWARD_INTENT_TO_MANAGED_PROFILE;
8031 className = FORWARD_INTENT_TO_PARENT;
8033 ComponentName forwardingActivityComponentName = new ComponentName(
8034 mAndroidApplication.packageName, className);
8035 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
8037 if (!targetIsProfile) {
8038 forwardingActivityInfo.showUserIcon = targetUserId;
8039 forwardingResolveInfo.noResourceId = true;
8041 forwardingResolveInfo.activityInfo = forwardingActivityInfo;
8042 forwardingResolveInfo.priority = 0;
8043 forwardingResolveInfo.preferredOrder = 0;
8044 forwardingResolveInfo.match = 0;
8045 forwardingResolveInfo.isDefault = true;
8046 forwardingResolveInfo.filter = filter;
8047 forwardingResolveInfo.targetUserId = targetUserId;
8048 return forwardingResolveInfo;
8052 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
8053 Intent[] specifics, String[] specificTypes, Intent intent,
8054 String resolvedType, int flags, int userId) {
8055 return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
8056 specificTypes, intent, resolvedType, flags, userId));
8059 private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
8060 Intent[] specifics, String[] specificTypes, Intent intent,
8061 String resolvedType, int flags, int userId) {
8062 if (!sUserManager.exists(userId)) return Collections.emptyList();
8063 final int callingUid = Binder.getCallingUid();
8064 flags = updateFlagsForResolve(flags, userId, intent, callingUid,
8065 false /*includeInstantApps*/);
8066 enforceCrossUserPermission(callingUid, userId,
8067 false /*requireFullPermission*/, false /*checkShell*/,
8068 "query intent activity options");
8069 final String resultsAction = intent.getAction();
8071 final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
8072 | PackageManager.GET_RESOLVED_FILTER, userId);
8074 if (DEBUG_INTENT_MATCHING) {
8075 Log.v(TAG, "Query " + intent + ": " + results);
8078 int specificsPos = 0;
8081 // todo: note that the algorithm used here is O(N^2). This
8082 // isn't a problem in our current environment, but if we start running
8083 // into situations where we have more than 5 or 10 matches then this
8084 // should probably be changed to something smarter...
8086 // First we go through and resolve each of the specific items
8087 // that were supplied, taking care of removing any corresponding
8088 // duplicate items in the generic resolve list.
8089 if (specifics != null) {
8090 for (int i=0; i<specifics.length; i++) {
8091 final Intent sintent = specifics[i];
8092 if (sintent == null) {
8096 if (DEBUG_INTENT_MATCHING) {
8097 Log.v(TAG, "Specific #" + i + ": " + sintent);
8100 String action = sintent.getAction();
8101 if (resultsAction != null && resultsAction.equals(action)) {
8102 // If this action was explicitly requested, then don't
8103 // remove things that have it.
8107 ResolveInfo ri = null;
8108 ActivityInfo ai = null;
8110 ComponentName comp = sintent.getComponent();
8114 specificTypes != null ? specificTypes[i] : null,
8119 if (ri == mResolveInfo) {
8120 // ACK! Must do something better with this.
8122 ai = ri.activityInfo;
8123 comp = new ComponentName(ai.applicationInfo.packageName,
8126 ai = getActivityInfo(comp, flags, userId);
8132 // Look for any generic query activities that are duplicates
8133 // of this specific one, and remove them from the results.
8134 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
8137 for (j=specificsPos; j<N; j++) {
8138 ResolveInfo sri = results.get(j);
8139 if ((sri.activityInfo.name.equals(comp.getClassName())
8140 && sri.activityInfo.applicationInfo.packageName.equals(
8141 comp.getPackageName()))
8142 || (action != null && sri.filter.matchAction(action))) {
8144 if (DEBUG_INTENT_MATCHING) Log.v(
8145 TAG, "Removing duplicate item from " + j
8146 + " due to specific " + specificsPos);
8155 // Add this specific item to its proper place.
8157 ri = new ResolveInfo();
8158 ri.activityInfo = ai;
8160 results.add(specificsPos, ri);
8161 ri.specificIndex = i;
8166 // Now we go through the remaining generic results and remove any
8167 // duplicate actions that are found here.
8169 for (int i=specificsPos; i<N-1; i++) {
8170 final ResolveInfo rii = results.get(i);
8171 if (rii.filter == null) {
8175 // Iterate over all of the actions of this result's intent
8176 // filter... typically this should be just one.
8177 final Iterator<String> it = rii.filter.actionsIterator();
8181 while (it.hasNext()) {
8182 final String action = it.next();
8183 if (resultsAction != null && resultsAction.equals(action)) {
8184 // If this action was explicitly requested, then don't
8185 // remove things that have it.
8188 for (int j=i+1; j<N; j++) {
8189 final ResolveInfo rij = results.get(j);
8190 if (rij.filter != null && rij.filter.hasAction(action)) {
8192 if (DEBUG_INTENT_MATCHING) Log.v(
8193 TAG, "Removing duplicate item from " + j
8194 + " due to action " + action + " at " + i);
8201 // If the caller didn't request filter information, drop it now
8202 // so we don't have to marshall/unmarshall it.
8203 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
8208 // Filter out the caller activity if so requested.
8209 if (caller != null) {
8211 for (int i=0; i<N; i++) {
8212 ActivityInfo ainfo = results.get(i).activityInfo;
8213 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
8214 && caller.getClassName().equals(ainfo.name)) {
8221 // If the caller didn't request filter information,
8222 // drop them now so we don't have to
8223 // marshall/unmarshall it.
8224 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
8226 for (int i=0; i<N; i++) {
8227 results.get(i).filter = null;
8231 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
8236 public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
8237 String resolvedType, int flags, int userId) {
8238 return new ParceledListSlice<>(
8239 queryIntentReceiversInternal(intent, resolvedType, flags, userId,
8240 false /*allowDynamicSplits*/));
8243 private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
8244 String resolvedType, int flags, int userId, boolean allowDynamicSplits) {
8245 if (!sUserManager.exists(userId)) return Collections.emptyList();
8246 final int callingUid = Binder.getCallingUid();
8247 enforceCrossUserPermission(callingUid, userId,
8248 false /*requireFullPermission*/, false /*checkShell*/,
8249 "query intent receivers");
8250 final String instantAppPkgName = getInstantAppPackageName(callingUid);
8251 flags = updateFlagsForResolve(flags, userId, intent, callingUid,
8252 false /*includeInstantApps*/);
8253 ComponentName comp = intent.getComponent();
8255 if (intent.getSelector() != null) {
8256 intent = intent.getSelector();
8257 comp = intent.getComponent();
8261 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
8262 final ActivityInfo ai = getReceiverInfo(comp, flags, userId);
8264 // When specifying an explicit component, we prevent the activity from being
8265 // used when either 1) the calling package is normal and the activity is within
8266 // an instant application or 2) the calling package is ephemeral and the
8267 // activity is not visible to instant applications.
8268 final boolean matchInstantApp =
8269 (flags & PackageManager.MATCH_INSTANT) != 0;
8270 final boolean matchVisibleToInstantAppOnly =
8271 (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
8272 final boolean matchExplicitlyVisibleOnly =
8273 (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
8274 final boolean isCallerInstantApp =
8275 instantAppPkgName != null;
8276 final boolean isTargetSameInstantApp =
8277 comp.getPackageName().equals(instantAppPkgName);
8278 final boolean isTargetInstantApp =
8279 (ai.applicationInfo.privateFlags
8280 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
8281 final boolean isTargetVisibleToInstantApp =
8282 (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
8283 final boolean isTargetExplicitlyVisibleToInstantApp =
8284 isTargetVisibleToInstantApp
8285 && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
8286 final boolean isTargetHiddenFromInstantApp =
8287 !isTargetVisibleToInstantApp
8288 || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
8289 final boolean blockResolution =
8290 !isTargetSameInstantApp
8291 && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
8292 || (matchVisibleToInstantAppOnly && isCallerInstantApp
8293 && isTargetHiddenFromInstantApp));
8294 if (!blockResolution) {
8295 ResolveInfo ri = new ResolveInfo();
8296 ri.activityInfo = ai;
8300 return applyPostResolutionFilter(
8301 list, instantAppPkgName, allowDynamicSplits, callingUid, userId);
8305 synchronized (mPackages) {
8306 String pkgName = intent.getPackage();
8307 if (pkgName == null) {
8308 final List<ResolveInfo> result =
8309 mReceivers.queryIntent(intent, resolvedType, flags, userId);
8310 return applyPostResolutionFilter(
8311 result, instantAppPkgName, allowDynamicSplits, callingUid, userId);
8313 final PackageParser.Package pkg = mPackages.get(pkgName);
8315 final List<ResolveInfo> result = mReceivers.queryIntentForPackage(
8316 intent, resolvedType, flags, pkg.receivers, userId);
8317 return applyPostResolutionFilter(
8318 result, instantAppPkgName, allowDynamicSplits, callingUid, userId);
8320 return Collections.emptyList();
8325 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
8326 final int callingUid = Binder.getCallingUid();
8327 return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
8330 private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
8331 int userId, int callingUid) {
8332 if (!sUserManager.exists(userId)) return null;
8333 flags = updateFlagsForResolve(
8334 flags, userId, intent, callingUid, false /*includeInstantApps*/);
8335 List<ResolveInfo> query = queryIntentServicesInternal(
8336 intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
8337 if (query != null) {
8338 if (query.size() >= 1) {
8339 // If there is more than one service with the same priority,
8340 // just arbitrarily pick the first one.
8341 return query.get(0);
8348 public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
8349 String resolvedType, int flags, int userId) {
8350 final int callingUid = Binder.getCallingUid();
8351 return new ParceledListSlice<>(queryIntentServicesInternal(
8352 intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
8355 private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
8356 String resolvedType, int flags, int userId, int callingUid,
8357 boolean includeInstantApps) {
8358 if (!sUserManager.exists(userId)) return Collections.emptyList();
8359 enforceCrossUserPermission(callingUid, userId,
8360 false /*requireFullPermission*/, false /*checkShell*/,
8361 "query intent receivers");
8362 final String instantAppPkgName = getInstantAppPackageName(callingUid);
8363 flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
8364 ComponentName comp = intent.getComponent();
8366 if (intent.getSelector() != null) {
8367 intent = intent.getSelector();
8368 comp = intent.getComponent();
8372 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
8373 final ServiceInfo si = getServiceInfo(comp, flags, userId);
8375 // When specifying an explicit component, we prevent the service from being
8376 // used when either 1) the service is in an instant application and the
8377 // caller is not the same instant application or 2) the calling package is
8378 // ephemeral and the activity is not visible to ephemeral applications.
8379 final boolean matchInstantApp =
8380 (flags & PackageManager.MATCH_INSTANT) != 0;
8381 final boolean matchVisibleToInstantAppOnly =
8382 (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
8383 final boolean isCallerInstantApp =
8384 instantAppPkgName != null;
8385 final boolean isTargetSameInstantApp =
8386 comp.getPackageName().equals(instantAppPkgName);
8387 final boolean isTargetInstantApp =
8388 (si.applicationInfo.privateFlags
8389 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
8390 final boolean isTargetHiddenFromInstantApp =
8391 (si.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
8392 final boolean blockResolution =
8393 !isTargetSameInstantApp
8394 && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
8395 || (matchVisibleToInstantAppOnly && isCallerInstantApp
8396 && isTargetHiddenFromInstantApp));
8397 if (!blockResolution) {
8398 final ResolveInfo ri = new ResolveInfo();
8399 ri.serviceInfo = si;
8407 synchronized (mPackages) {
8408 String pkgName = intent.getPackage();
8409 if (pkgName == null) {
8410 return applyPostServiceResolutionFilter(
8411 mServices.queryIntent(intent, resolvedType, flags, userId),
8414 final PackageParser.Package pkg = mPackages.get(pkgName);
8416 return applyPostServiceResolutionFilter(
8417 mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
8421 return Collections.emptyList();
8425 private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
8426 String instantAppPkgName) {
8427 if (instantAppPkgName == null) {
8428 return resolveInfos;
8430 for (int i = resolveInfos.size() - 1; i >= 0; i--) {
8431 final ResolveInfo info = resolveInfos.get(i);
8432 final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
8433 // allow services that are defined in the provided package
8434 if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
8435 if (info.serviceInfo.splitName != null
8436 && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
8437 info.serviceInfo.splitName)) {
8438 // requested service is defined in a split that hasn't been installed yet.
8439 // add the installer to the resolve list
8440 if (DEBUG_EPHEMERAL) {
8441 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
8443 final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
8444 installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
8445 info.serviceInfo.packageName, info.serviceInfo.splitName,
8446 null /*failureActivity*/, info.serviceInfo.applicationInfo.versionCode,
8447 null /*failureIntent*/);
8448 // make sure this resolver is the default
8449 installerInfo.isDefault = true;
8450 installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
8451 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
8452 // add a non-generic filter
8453 installerInfo.filter = new IntentFilter();
8454 // load resources from the correct package
8455 installerInfo.resolvePackageName = info.getComponentInfo().packageName;
8456 resolveInfos.set(i, installerInfo);
8460 // allow services that have been explicitly exposed to ephemeral apps
8462 && ((info.serviceInfo.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
8465 resolveInfos.remove(i);
8467 return resolveInfos;
8471 public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
8472 String resolvedType, int flags, int userId) {
8473 return new ParceledListSlice<>(
8474 queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
8477 private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
8478 Intent intent, String resolvedType, int flags, int userId) {
8479 if (!sUserManager.exists(userId)) return Collections.emptyList();
8480 final int callingUid = Binder.getCallingUid();
8481 final String instantAppPkgName = getInstantAppPackageName(callingUid);
8482 flags = updateFlagsForResolve(flags, userId, intent, callingUid,
8483 false /*includeInstantApps*/);
8484 ComponentName comp = intent.getComponent();
8486 if (intent.getSelector() != null) {
8487 intent = intent.getSelector();
8488 comp = intent.getComponent();
8492 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
8493 final ProviderInfo pi = getProviderInfo(comp, flags, userId);
8495 // When specifying an explicit component, we prevent the provider from being
8496 // used when either 1) the provider is in an instant application and the
8497 // caller is not the same instant application or 2) the calling package is an
8498 // instant application and the provider is not visible to instant applications.
8499 final boolean matchInstantApp =
8500 (flags & PackageManager.MATCH_INSTANT) != 0;
8501 final boolean matchVisibleToInstantAppOnly =
8502 (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
8503 final boolean isCallerInstantApp =
8504 instantAppPkgName != null;
8505 final boolean isTargetSameInstantApp =
8506 comp.getPackageName().equals(instantAppPkgName);
8507 final boolean isTargetInstantApp =
8508 (pi.applicationInfo.privateFlags
8509 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
8510 final boolean isTargetHiddenFromInstantApp =
8511 (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
8512 final boolean blockResolution =
8513 !isTargetSameInstantApp
8514 && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
8515 || (matchVisibleToInstantAppOnly && isCallerInstantApp
8516 && isTargetHiddenFromInstantApp));
8517 if (!blockResolution) {
8518 final ResolveInfo ri = new ResolveInfo();
8519 ri.providerInfo = pi;
8527 synchronized (mPackages) {
8528 String pkgName = intent.getPackage();
8529 if (pkgName == null) {
8530 return applyPostContentProviderResolutionFilter(
8531 mProviders.queryIntent(intent, resolvedType, flags, userId),
8534 final PackageParser.Package pkg = mPackages.get(pkgName);
8536 return applyPostContentProviderResolutionFilter(
8537 mProviders.queryIntentForPackage(
8538 intent, resolvedType, flags, pkg.providers, userId),
8541 return Collections.emptyList();
8545 private List<ResolveInfo> applyPostContentProviderResolutionFilter(
8546 List<ResolveInfo> resolveInfos, String instantAppPkgName) {
8547 if (instantAppPkgName == null) {
8548 return resolveInfos;
8550 for (int i = resolveInfos.size() - 1; i >= 0; i--) {
8551 final ResolveInfo info = resolveInfos.get(i);
8552 final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
8553 // allow providers that are defined in the provided package
8554 if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
8555 if (info.providerInfo.splitName != null
8556 && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
8557 info.providerInfo.splitName)) {
8558 // requested provider is defined in a split that hasn't been installed yet.
8559 // add the installer to the resolve list
8560 if (DEBUG_EPHEMERAL) {
8561 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
8563 final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
8564 installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
8565 info.providerInfo.packageName, info.providerInfo.splitName,
8566 null /*failureActivity*/, info.providerInfo.applicationInfo.versionCode,
8567 null /*failureIntent*/);
8568 // make sure this resolver is the default
8569 installerInfo.isDefault = true;
8570 installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
8571 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
8572 // add a non-generic filter
8573 installerInfo.filter = new IntentFilter();
8574 // load resources from the correct package
8575 installerInfo.resolvePackageName = info.getComponentInfo().packageName;
8576 resolveInfos.set(i, installerInfo);
8580 // allow providers that have been explicitly exposed to instant applications
8582 && ((info.providerInfo.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
8585 resolveInfos.remove(i);
8587 return resolveInfos;
8591 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
8592 final int callingUid = Binder.getCallingUid();
8593 if (getInstantAppPackageName(callingUid) != null) {
8594 return ParceledListSlice.emptyList();
8596 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8597 flags = updateFlagsForPackage(flags, userId, null);
8598 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8599 enforceCrossUserPermission(callingUid, userId,
8600 true /* requireFullPermission */, false /* checkShell */,
8601 "get installed packages");
8604 synchronized (mPackages) {
8605 ArrayList<PackageInfo> list;
8606 if (listUninstalled) {
8607 list = new ArrayList<>(mSettings.mPackages.size());
8608 for (PackageSetting ps : mSettings.mPackages.values()) {
8609 if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8612 if (filterAppAccessLPr(ps, callingUid, userId)) {
8615 final PackageInfo pi = generatePackageInfo(ps, flags, userId);
8621 list = new ArrayList<>(mPackages.size());
8622 for (PackageParser.Package p : mPackages.values()) {
8623 final PackageSetting ps = (PackageSetting) p.mExtras;
8624 if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8627 if (filterAppAccessLPr(ps, callingUid, userId)) {
8630 final PackageInfo pi = generatePackageInfo((PackageSetting)
8631 p.mExtras, flags, userId);
8638 return new ParceledListSlice<>(list);
8642 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
8643 String[] permissions, boolean[] tmp, int flags, int userId) {
8645 final PermissionsState permissionsState = ps.getPermissionsState();
8646 for (int i=0; i<permissions.length; i++) {
8647 final String permission = permissions[i];
8648 if (permissionsState.hasPermission(permission, userId)) {
8655 if (numMatch == 0) {
8658 final PackageInfo pi = generatePackageInfo(ps, flags, userId);
8660 // The above might return null in cases of uninstalled apps or install-state
8661 // skew across users/profiles.
8663 if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
8664 if (numMatch == permissions.length) {
8665 pi.requestedPermissions = permissions;
8667 pi.requestedPermissions = new String[numMatch];
8669 for (int i=0; i<permissions.length; i++) {
8671 pi.requestedPermissions[numMatch] = permissions[i];
8682 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
8683 String[] permissions, int flags, int userId) {
8684 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8685 flags = updateFlagsForPackage(flags, userId, permissions);
8686 enforceCrossUserPermission(Binder.getCallingUid(), userId,
8687 true /* requireFullPermission */, false /* checkShell */,
8688 "get packages holding permissions");
8689 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8692 synchronized (mPackages) {
8693 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
8694 boolean[] tmpBools = new boolean[permissions.length];
8695 if (listUninstalled) {
8696 for (PackageSetting ps : mSettings.mPackages.values()) {
8697 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
8701 for (PackageParser.Package pkg : mPackages.values()) {
8702 PackageSetting ps = (PackageSetting)pkg.mExtras;
8704 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
8710 return new ParceledListSlice<PackageInfo>(list);
8715 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
8716 final int callingUid = Binder.getCallingUid();
8717 if (getInstantAppPackageName(callingUid) != null) {
8718 return ParceledListSlice.emptyList();
8720 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8721 flags = updateFlagsForApplication(flags, userId, null);
8722 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8725 synchronized (mPackages) {
8726 ArrayList<ApplicationInfo> list;
8727 if (listUninstalled) {
8728 list = new ArrayList<>(mSettings.mPackages.size());
8729 for (PackageSetting ps : mSettings.mPackages.values()) {
8731 int effectiveFlags = flags;
8732 if (ps.isSystem()) {
8733 effectiveFlags |= PackageManager.MATCH_ANY_USER;
8735 if (ps.pkg != null) {
8736 if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8739 if (filterAppAccessLPr(ps, callingUid, userId)) {
8742 ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
8743 ps.readUserState(userId), userId);
8745 ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
8748 // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
8749 // and already converts to externally visible package name
8750 ai = generateApplicationInfoFromSettingsLPw(ps.name,
8751 callingUid, effectiveFlags, userId);
8758 list = new ArrayList<>(mPackages.size());
8759 for (PackageParser.Package p : mPackages.values()) {
8760 if (p.mExtras != null) {
8761 PackageSetting ps = (PackageSetting) p.mExtras;
8762 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
8765 if (filterAppAccessLPr(ps, callingUid, userId)) {
8768 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
8769 ps.readUserState(userId), userId);
8771 ai.packageName = resolveExternalPackageNameLPr(p);
8778 return new ParceledListSlice<>(list);
8783 public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
8784 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8787 if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
8788 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8789 "getEphemeralApplications");
8791 enforceCrossUserPermission(Binder.getCallingUid(), userId,
8792 true /* requireFullPermission */, false /* checkShell */,
8793 "getEphemeralApplications");
8794 synchronized (mPackages) {
8795 List<InstantAppInfo> instantApps = mInstantAppRegistry
8796 .getInstantAppsLPr(userId);
8797 if (instantApps != null) {
8798 return new ParceledListSlice<>(instantApps);
8805 public boolean isInstantApp(String packageName, int userId) {
8806 enforceCrossUserPermission(Binder.getCallingUid(), userId,
8807 true /* requireFullPermission */, false /* checkShell */,
8809 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8813 synchronized (mPackages) {
8814 int callingUid = Binder.getCallingUid();
8815 if (Process.isIsolated(callingUid)) {
8816 callingUid = mIsolatedOwners.get(callingUid);
8818 final PackageSetting ps = mSettings.mPackages.get(packageName);
8819 PackageParser.Package pkg = mPackages.get(packageName);
8820 final boolean returnAllowed =
8822 && (isCallerSameApp(packageName, callingUid)
8823 || canViewInstantApps(callingUid, userId)
8824 || mInstantAppRegistry.isInstantAccessGranted(
8825 userId, UserHandle.getAppId(callingUid), ps.appId));
8826 if (returnAllowed) {
8827 return ps.getInstantApp(userId);
8834 public byte[] getInstantAppCookie(String packageName, int userId) {
8835 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8839 enforceCrossUserPermission(Binder.getCallingUid(), userId,
8840 true /* requireFullPermission */, false /* checkShell */,
8841 "getInstantAppCookie");
8842 if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8845 synchronized (mPackages) {
8846 return mInstantAppRegistry.getInstantAppCookieLPw(
8847 packageName, userId);
8852 public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
8853 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8857 enforceCrossUserPermission(Binder.getCallingUid(), userId,
8858 true /* requireFullPermission */, true /* checkShell */,
8859 "setInstantAppCookie");
8860 if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8863 synchronized (mPackages) {
8864 return mInstantAppRegistry.setInstantAppCookieLPw(
8865 packageName, cookie, userId);
8870 public Bitmap getInstantAppIcon(String packageName, int userId) {
8871 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8875 if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
8876 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8877 "getInstantAppIcon");
8879 enforceCrossUserPermission(Binder.getCallingUid(), userId,
8880 true /* requireFullPermission */, false /* checkShell */,
8881 "getInstantAppIcon");
8883 synchronized (mPackages) {
8884 return mInstantAppRegistry.getInstantAppIconLPw(
8885 packageName, userId);
8889 private boolean isCallerSameApp(String packageName, int uid) {
8890 PackageParser.Package pkg = mPackages.get(packageName);
8892 && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
8896 public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
8897 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8898 return ParceledListSlice.emptyList();
8900 return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
8903 private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
8904 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
8907 synchronized (mPackages) {
8908 final Iterator<PackageParser.Package> i = mPackages.values().iterator();
8909 final int userId = UserHandle.getCallingUserId();
8910 while (i.hasNext()) {
8911 final PackageParser.Package p = i.next();
8912 if (p.applicationInfo == null) continue;
8914 final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
8915 && !p.applicationInfo.isDirectBootAware();
8916 final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
8917 && p.applicationInfo.isDirectBootAware();
8919 if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
8920 && (!mSafeMode || isSystemApp(p))
8921 && (matchesUnaware || matchesAware)) {
8922 PackageSetting ps = mSettings.mPackages.get(p.packageName);
8924 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
8925 ps.readUserState(userId), userId);
8938 public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
8939 if (!sUserManager.exists(userId)) return null;
8940 flags = updateFlagsForComponent(flags, userId, name);
8941 final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid());
8943 synchronized (mPackages) {
8944 final PackageParser.Provider provider = mProvidersByAuthority.get(name);
8945 PackageSetting ps = provider != null
8946 ? mSettings.mPackages.get(provider.owner.packageName)
8949 final boolean isInstantApp = ps.getInstantApp(userId);
8950 // normal application; filter out instant application provider
8951 if (instantAppPkgName == null && isInstantApp) {
8954 // instant application; filter out other instant applications
8955 if (instantAppPkgName != null
8957 && !provider.owner.packageName.equals(instantAppPkgName)) {
8960 // instant application; filter out non-exposed provider
8961 if (instantAppPkgName != null
8963 && (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0) {
8966 // provider not enabled
8967 if (!mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)) {
8970 return PackageParser.generateProviderInfo(
8971 provider, flags, ps.readUserState(userId), userId);
8981 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
8982 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8986 synchronized (mPackages) {
8987 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
8988 .entrySet().iterator();
8989 final int userId = UserHandle.getCallingUserId();
8990 while (i.hasNext()) {
8991 Map.Entry<String, PackageParser.Provider> entry = i.next();
8992 PackageParser.Provider p = entry.getValue();
8993 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8995 if (ps != null && p.syncable
8996 && (!mSafeMode || (p.info.applicationInfo.flags
8997 &ApplicationInfo.FLAG_SYSTEM) != 0)) {
8998 ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
8999 ps.readUserState(userId), userId);
9001 outNames.add(entry.getKey());
9010 public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
9011 int uid, int flags, String metaDataKey) {
9012 final int callingUid = Binder.getCallingUid();
9013 final int userId = processName != null ? UserHandle.getUserId(uid)
9014 : UserHandle.getCallingUserId();
9015 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
9016 flags = updateFlagsForComponent(flags, userId, processName);
9017 ArrayList<ProviderInfo> finalList = null;
9019 synchronized (mPackages) {
9020 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
9021 while (i.hasNext()) {
9022 final PackageParser.Provider p = i.next();
9023 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
9024 if (ps != null && p.info.authority != null
9025 && (processName == null
9026 || (p.info.processName.equals(processName)
9027 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
9028 && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
9030 // See PM.queryContentProviders()'s javadoc for why we have the metaData
9032 if (metaDataKey != null
9033 && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
9036 final ComponentName component =
9037 new ComponentName(p.info.packageName, p.info.name);
9038 if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
9041 if (finalList == null) {
9042 finalList = new ArrayList<ProviderInfo>(3);
9044 ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
9045 ps.readUserState(userId), userId);
9047 finalList.add(info);
9053 if (finalList != null) {
9054 Collections.sort(finalList, mProviderInitOrderSorter);
9055 return new ParceledListSlice<ProviderInfo>(finalList);
9058 return ParceledListSlice.emptyList();
9062 public InstrumentationInfo getInstrumentationInfo(ComponentName component, int flags) {
9064 synchronized (mPackages) {
9065 final int callingUid = Binder.getCallingUid();
9066 final int callingUserId = UserHandle.getUserId(callingUid);
9067 final PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
9068 if (ps == null) return null;
9069 if (filterAppAccessLPr(ps, callingUid, component, TYPE_UNKNOWN, callingUserId)) {
9072 final PackageParser.Instrumentation i = mInstrumentation.get(component);
9073 return PackageParser.generateInstrumentationInfo(i, flags);
9078 public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
9079 String targetPackage, int flags) {
9080 final int callingUid = Binder.getCallingUid();
9081 final int callingUserId = UserHandle.getUserId(callingUid);
9082 final PackageSetting ps = mSettings.mPackages.get(targetPackage);
9083 if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
9084 return ParceledListSlice.emptyList();
9086 return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
9089 private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
9091 ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
9094 synchronized (mPackages) {
9095 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
9096 while (i.hasNext()) {
9097 final PackageParser.Instrumentation p = i.next();
9098 if (targetPackage == null
9099 || targetPackage.equals(p.info.targetPackage)) {
9100 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
9112 private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
9113 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + dir.getAbsolutePath() + "]");
9115 scanDirLI(dir, parseFlags, scanFlags, currentTime);
9117 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9121 private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
9122 final File[] files = dir.listFiles();
9123 if (ArrayUtils.isEmpty(files)) {
9124 Log.d(TAG, "No files in app dir " + dir);
9128 if (DEBUG_PACKAGE_SCANNING) {
9129 Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
9130 + " flags=0x" + Integer.toHexString(parseFlags));
9132 ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
9133 mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,
9134 mParallelPackageParserCallback);
9136 // Submit files for parsing in parallel
9138 for (File file : files) {
9139 final boolean isPackage = (isApkFile(file) || file.isDirectory())
9140 && !PackageInstallerService.isStageName(file.getName());
9142 // Ignore entries which are not packages
9145 parallelPackageParser.submit(file, parseFlags);
9149 // Process results one by one
9150 for (; fileCount > 0; fileCount--) {
9151 ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
9152 Throwable throwable = parseResult.throwable;
9153 int errorCode = PackageManager.INSTALL_SUCCEEDED;
9155 if (throwable == null) {
9156 // Static shared libraries have synthetic package names
9157 if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
9158 renameStaticSharedLibraryPackage(parseResult.pkg);
9161 if (errorCode == PackageManager.INSTALL_SUCCEEDED) {
9162 scanPackageLI(parseResult.pkg, parseResult.scanFile, parseFlags, scanFlags,
9165 } catch (PackageManagerException e) {
9166 errorCode = e.error;
9167 Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
9169 } else if (throwable instanceof PackageParser.PackageParserException) {
9170 PackageParser.PackageParserException e = (PackageParser.PackageParserException)
9172 errorCode = e.error;
9173 Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
9175 throw new IllegalStateException("Unexpected exception occurred while parsing "
9176 + parseResult.scanFile, throwable);
9179 // Delete invalid userdata apps
9180 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
9181 errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) {
9182 logCriticalInfo(Log.WARN,
9183 "Deleting invalid package at " + parseResult.scanFile);
9184 removeCodePathLI(parseResult.scanFile);
9187 parallelPackageParser.close();
9190 private static File getSettingsProblemFile() {
9191 File dataDir = Environment.getDataDirectory();
9192 File systemDir = new File(dataDir, "system");
9193 File fname = new File(systemDir, "uiderrors.txt");
9197 static void reportSettingsProblem(int priority, String msg) {
9198 logCriticalInfo(priority, msg);
9201 public static void logCriticalInfo(int priority, String msg) {
9202 Slog.println(priority, TAG, msg);
9203 EventLogTags.writePmCriticalInfo(msg);
9205 File fname = getSettingsProblemFile();
9206 FileOutputStream out = new FileOutputStream(fname, true);
9207 PrintWriter pw = new FastPrintWriter(out);
9208 SimpleDateFormat formatter = new SimpleDateFormat();
9209 String dateString = formatter.format(new Date(System.currentTimeMillis()));
9210 pw.println(dateString + ": " + msg);
9212 FileUtils.setPermissions(
9214 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
9216 } catch (java.io.IOException e) {
9220 private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) {
9221 if (srcFile.isDirectory()) {
9222 final File baseFile = new File(pkg.baseCodePath);
9223 long maxModifiedTime = baseFile.lastModified();
9224 if (pkg.splitCodePaths != null) {
9225 for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) {
9226 final File splitFile = new File(pkg.splitCodePaths[i]);
9227 maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified());
9230 return maxModifiedTime;
9232 return srcFile.lastModified();
9235 private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile,
9236 final int policyFlags) throws PackageManagerException {
9237 // When upgrading from pre-N MR1, verify the package time stamp using the package
9238 // directory and not the APK file.
9239 final long lastModifiedTime = mIsPreNMR1Upgrade
9240 ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg, srcFile);
9242 && ps.codePath.equals(srcFile)
9243 && ps.timeStamp == lastModifiedTime
9244 && !isCompatSignatureUpdateNeeded(pkg)
9245 && !isRecoverSignatureUpdateNeeded(pkg)) {
9246 long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
9247 KeySetManagerService ksms = mSettings.mKeySetManagerService;
9248 ArraySet<PublicKey> signingKs;
9249 synchronized (mPackages) {
9250 signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
9252 if (ps.signatures.mSignatures != null
9253 && ps.signatures.mSignatures.length != 0
9254 && signingKs != null) {
9255 // Optimization: reuse the existing cached certificates
9256 // if the package appears to be unchanged.
9257 pkg.mSignatures = ps.signatures.mSignatures;
9258 pkg.mSigningKeys = signingKs;
9262 Slog.w(TAG, "PackageSetting for " + ps.name
9263 + " is missing signatures. Collecting certs again to recover them.");
9265 Slog.i(TAG, srcFile.toString() + " changed; collecting certs");
9269 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
9270 PackageParser.collectCertificates(pkg, policyFlags);
9271 } catch (PackageParserException e) {
9272 throw PackageManagerException.from(e);
9274 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9279 * Traces a package scan.
9280 * @see #scanPackageLI(File, int, int, long, UserHandle)
9282 private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
9283 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
9284 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
9286 return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
9288 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9293 * Scans a package and returns the newly parsed package.
9294 * Returns {@code null} in case of errors and the error code is stored in mLastScanError
9296 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
9297 long currentTime, UserHandle user) throws PackageManagerException {
9298 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
9299 PackageParser pp = new PackageParser();
9300 pp.setSeparateProcesses(mSeparateProcesses);
9301 pp.setOnlyCoreApps(mOnlyCore);
9302 pp.setDisplayMetrics(mMetrics);
9303 pp.setCallback(mPackageParserCallback);
9305 if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
9306 parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
9309 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
9310 final PackageParser.Package pkg;
9312 pkg = pp.parsePackage(scanFile, parseFlags);
9313 } catch (PackageParserException e) {
9314 throw PackageManagerException.from(e);
9316 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9319 // Static shared libraries have synthetic package names
9320 if (pkg.applicationInfo.isStaticSharedLibrary()) {
9321 renameStaticSharedLibraryPackage(pkg);
9324 return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
9328 * Scans a package and returns the newly parsed package.
9329 * @throws PackageManagerException on a parse error.
9331 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile,
9332 final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
9333 throws PackageManagerException {
9334 // If the package has children and this is the first dive in the function
9335 // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
9336 // packages (parent and children) would be successfully scanned before the
9337 // actual scan since scanning mutates internal state and we want to atomically
9338 // install the package and its children.
9339 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9340 if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
9341 scanFlags |= SCAN_CHECK_ONLY;
9344 scanFlags &= ~SCAN_CHECK_ONLY;
9348 PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags,
9349 scanFlags, currentTime, user);
9351 // Scan the children
9352 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9353 for (int i = 0; i < childCount; i++) {
9354 PackageParser.Package childPackage = pkg.childPackages.get(i);
9355 scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags,
9360 if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9361 return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user);
9368 * Scans a package and returns the newly parsed package.
9369 * @throws PackageManagerException on a parse error.
9371 private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile,
9372 int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
9373 throws PackageManagerException {
9374 PackageSetting ps = null;
9375 PackageSetting updatedPkg;
9377 synchronized (mPackages) {
9378 // Look to see if we already know about this package.
9379 String oldName = mSettings.getRenamedPackageLPr(pkg.packageName);
9380 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
9381 // This package has been renamed to its original name. Let's
9383 ps = mSettings.getPackageLPr(oldName);
9385 // If there was no original package, see one for the real package name.
9387 ps = mSettings.getPackageLPr(pkg.packageName);
9389 // Check to see if this package could be hiding/updating a system
9390 // package. Must look for it either under the original or real
9391 // package name depending on our state.
9392 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
9393 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
9395 // If this is a package we don't know about on the system partition, we
9396 // may need to remove disabled child packages on the system partition
9397 // or may need to not add child packages if the parent apk is updated
9398 // on the data partition and no longer defines this child package.
9399 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
9400 // If this is a parent package for an updated system app and this system
9401 // app got an OTA update which no longer defines some of the child packages
9402 // we have to prune them from the disabled system packages.
9403 PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
9404 if (disabledPs != null) {
9405 final int scannedChildCount = (pkg.childPackages != null)
9406 ? pkg.childPackages.size() : 0;
9407 final int disabledChildCount = disabledPs.childPackageNames != null
9408 ? disabledPs.childPackageNames.size() : 0;
9409 for (int i = 0; i < disabledChildCount; i++) {
9410 String disabledChildPackageName = disabledPs.childPackageNames.get(i);
9411 boolean disabledPackageAvailable = false;
9412 for (int j = 0; j < scannedChildCount; j++) {
9413 PackageParser.Package childPkg = pkg.childPackages.get(j);
9414 if (childPkg.packageName.equals(disabledChildPackageName)) {
9415 disabledPackageAvailable = true;
9419 if (!disabledPackageAvailable) {
9420 mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
9427 final boolean isUpdatedPkg = updatedPkg != null;
9428 final boolean isUpdatedSystemPkg = isUpdatedPkg
9429 && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0;
9430 boolean isUpdatedPkgBetter = false;
9431 // First check if this is a system package that may involve an update
9432 if (isUpdatedSystemPkg) {
9433 // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
9434 // it needs to drop FLAG_PRIVILEGED.
9435 if (locationIsPrivileged(scanFile)) {
9436 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
9438 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
9441 if (ps != null && !ps.codePath.equals(scanFile)) {
9442 // The path has changed from what was last scanned... check the
9443 // version of the new path against what we have stored to determine
9445 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
9446 if (pkg.mVersionCode <= ps.versionCode) {
9447 // The system package has been updated and the code path does not match
9448 // Ignore entry. Skip it.
9449 if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile
9450 + " ignored: updated version " + ps.versionCode
9451 + " better than this " + pkg.mVersionCode);
9452 if (!updatedPkg.codePath.equals(scanFile)) {
9453 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
9454 + ps.name + " changing from " + updatedPkg.codePathString
9455 + " to " + scanFile);
9456 updatedPkg.codePath = scanFile;
9457 updatedPkg.codePathString = scanFile.toString();
9458 updatedPkg.resourcePath = scanFile;
9459 updatedPkg.resourcePathString = scanFile.toString();
9461 updatedPkg.pkg = pkg;
9462 updatedPkg.versionCode = pkg.mVersionCode;
9464 // Update the disabled system child packages to point to the package too.
9465 final int childCount = updatedPkg.childPackageNames != null
9466 ? updatedPkg.childPackageNames.size() : 0;
9467 for (int i = 0; i < childCount; i++) {
9468 String childPackageName = updatedPkg.childPackageNames.get(i);
9469 PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr(
9471 if (updatedChildPkg != null) {
9472 updatedChildPkg.pkg = pkg;
9473 updatedChildPkg.versionCode = pkg.mVersionCode;
9477 // The current app on the system partition is better than
9478 // what we have updated to on the data partition; switch
9479 // back to the system partition version.
9480 // At this point, its safely assumed that package installation for
9481 // apps in system partition will go through. If not there won't be a working
9482 // version of the app
9484 synchronized (mPackages) {
9485 // Just remove the loaded entries from package lists.
9486 mPackages.remove(ps.name);
9489 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
9490 + " reverting from " + ps.codePathString
9491 + ": new version " + pkg.mVersionCode
9492 + " better than installed " + ps.versionCode);
9494 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
9495 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
9496 synchronized (mInstallLock) {
9497 args.cleanUpResourcesLI();
9499 synchronized (mPackages) {
9500 mSettings.enableSystemPackageLPw(ps.name);
9502 isUpdatedPkgBetter = true;
9507 String resourcePath = null;
9508 String baseResourcePath = null;
9509 if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !isUpdatedPkgBetter) {
9510 if (ps != null && ps.resourcePathString != null) {
9511 resourcePath = ps.resourcePathString;
9512 baseResourcePath = ps.resourcePathString;
9514 // Should not happen at all. Just log an error.
9515 Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
9518 resourcePath = pkg.codePath;
9519 baseResourcePath = pkg.baseCodePath;
9522 // Set application objects path explicitly.
9523 pkg.setApplicationVolumeUuid(pkg.volumeUuid);
9524 pkg.setApplicationInfoCodePath(pkg.codePath);
9525 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
9526 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
9527 pkg.setApplicationInfoResourcePath(resourcePath);
9528 pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
9529 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
9531 // throw an exception if we have an update to a system application, but, it's not more
9532 // recent than the package we've already scanned
9533 if (isUpdatedSystemPkg && !isUpdatedPkgBetter) {
9534 // Set CPU Abis to application info.
9535 if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) {
9536 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, updatedPkg);
9537 derivePackageAbi(pkg, scanFile, cpuAbiOverride, false, mAppLib32InstallDir);
9539 pkg.applicationInfo.primaryCpuAbi = updatedPkg.primaryCpuAbiString;
9540 pkg.applicationInfo.secondaryCpuAbi = updatedPkg.secondaryCpuAbiString;
9543 throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
9544 + scanFile + " ignored: updated version " + ps.versionCode
9545 + " better than this " + pkg.mVersionCode);
9549 // An updated system app will not have the PARSE_IS_SYSTEM flag set
9551 policyFlags |= PackageParser.PARSE_IS_SYSTEM;
9553 // An updated privileged app will not have the PARSE_IS_PRIVILEGED
9554 // flag set initially
9555 if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
9556 policyFlags |= PackageParser.PARSE_IS_PRIVILEGED;
9560 // Verify certificates against what was last scanned
9561 collectCertificatesLI(ps, pkg, scanFile, policyFlags);
9564 * A new system app appeared, but we already had a non-system one of the
9565 * same name installed earlier.
9567 boolean shouldHideSystemApp = false;
9568 if (!isUpdatedPkg && ps != null
9569 && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
9571 * Check to make sure the signatures match first. If they don't,
9572 * wipe the installed application and its data.
9574 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
9575 != PackageManager.SIGNATURE_MATCH) {
9576 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
9577 + " signatures don't match existing userdata copy; removing");
9578 try (PackageFreezer freezer = freezePackage(pkg.packageName,
9579 "scanPackageInternalLI")) {
9580 deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
9585 * If the newly-added system app is an older version than the
9586 * already installed version, hide it. It will be scanned later
9587 * and re-added like an update.
9589 if (pkg.mVersionCode <= ps.versionCode) {
9590 shouldHideSystemApp = true;
9591 logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
9592 + " but new version " + pkg.mVersionCode + " better than installed "
9593 + ps.versionCode + "; hiding system");
9596 * The newly found system app is a newer version that the
9597 * one previously installed. Simply remove the
9598 * already-installed application and replace it with our own
9599 * while keeping the application data.
9601 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
9602 + " reverting from " + ps.codePathString + ": new version "
9603 + pkg.mVersionCode + " better than installed " + ps.versionCode);
9604 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
9605 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
9606 synchronized (mInstallLock) {
9607 args.cleanUpResourcesLI();
9613 // The apk is forward locked (not public) if its code and resources
9614 // are kept in different files. (except for app in either system or
9616 // TODO grab this value from PackageSettings
9617 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9618 if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
9619 policyFlags |= PackageParser.PARSE_FORWARD_LOCK;
9623 final int userId = ((user == null) ? 0 : user.getIdentifier());
9624 if (ps != null && ps.getInstantApp(userId)) {
9625 scanFlags |= SCAN_AS_INSTANT_APP;
9627 if (ps != null && ps.getVirtulalPreload(userId)) {
9628 scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
9631 // Note that we invoke the following method only if we are about to unpack an application
9632 PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags
9633 | SCAN_UPDATE_SIGNATURE, currentTime, user);
9636 * If the system app should be overridden by a previously installed
9637 * data, hide the system app now and let the /data/app scan pick it up
9640 if (shouldHideSystemApp) {
9641 synchronized (mPackages) {
9642 mSettings.disableSystemPackageLPw(pkg.packageName, true);
9649 private void renameStaticSharedLibraryPackage(PackageParser.Package pkg) {
9650 // Derive the new package synthetic package name
9651 pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER
9652 + pkg.staticSharedLibVersion);
9655 private static String fixProcessName(String defProcessName,
9656 String processName) {
9657 if (processName == null) {
9658 return defProcessName;
9663 private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
9664 throws PackageManagerException {
9665 if (pkgSetting.signatures.mSignatures != null) {
9666 // Already existing package. Make sure signatures match
9667 boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
9668 == PackageManager.SIGNATURE_MATCH;
9670 match = compareSignaturesCompat(pkgSetting.signatures, pkg)
9671 == PackageManager.SIGNATURE_MATCH;
9674 match = compareSignaturesRecover(pkgSetting.signatures, pkg)
9675 == PackageManager.SIGNATURE_MATCH;
9678 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
9679 + pkg.packageName + " signatures do not match the "
9680 + "previously installed version; ignoring!");
9684 // Check for shared user signatures
9685 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
9686 // Already existing package. Make sure signatures match
9687 boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
9688 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
9690 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
9691 == PackageManager.SIGNATURE_MATCH;
9694 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
9695 == PackageManager.SIGNATURE_MATCH;
9698 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
9699 "Package " + pkg.packageName
9700 + " has no signatures that match those in shared user "
9701 + pkgSetting.sharedUser.name + "; ignoring!");
9707 * Enforces that only the system UID or root's UID can call a method exposed
9710 * @param message used as message if SecurityException is thrown
9711 * @throws SecurityException if the caller is not system or root
9713 private static final void enforceSystemOrRoot(String message) {
9714 final int uid = Binder.getCallingUid();
9715 if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID) {
9716 throw new SecurityException(message);
9721 public void performFstrimIfNeeded() {
9722 enforceSystemOrRoot("Only the system can request fstrim");
9724 // Before everything else, see whether we need to fstrim.
9726 IStorageManager sm = PackageHelper.getStorageManager();
9728 boolean doTrim = false;
9729 final long interval = android.provider.Settings.Global.getLong(
9730 mContext.getContentResolver(),
9731 android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
9732 DEFAULT_MANDATORY_FSTRIM_INTERVAL);
9734 final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
9735 if (timeSinceLast > interval) {
9737 Slog.w(TAG, "No disk maintenance in " + timeSinceLast
9738 + "; running immediately");
9742 final boolean dexOptDialogShown;
9743 synchronized (mPackages) {
9744 dexOptDialogShown = mDexOptDialogShown;
9746 if (!isFirstBoot() && dexOptDialogShown) {
9748 ActivityManager.getService().showBootMessage(
9749 mContext.getResources().getString(
9750 R.string.android_upgrading_fstrim), true);
9751 } catch (RemoteException e) {
9754 sm.runMaintenance();
9757 Slog.e(TAG, "storageManager service unavailable!");
9759 } catch (RemoteException e) {
9760 // Can't happen; StorageManagerService is local
9765 public void updatePackagesIfNeeded() {
9766 enforceSystemOrRoot("Only the system can request package update");
9768 // We need to re-extract after an OTA.
9769 boolean causeUpgrade = isUpgrade();
9771 // First boot or factory reset.
9772 // Note: we also handle devices that are upgrading to N right now as if it is their
9773 // first boot, as they do not have profile data.
9774 boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
9776 // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
9777 boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
9779 if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
9783 List<PackageParser.Package> pkgs;
9784 synchronized (mPackages) {
9785 pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
9788 final long startTime = System.nanoTime();
9789 final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
9790 getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT),
9791 false /* bootComplete */);
9793 final int elapsedTimeSeconds =
9794 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
9796 MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
9797 MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
9798 MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
9799 MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
9800 MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
9804 * Return the prebuilt profile path given a package base code path.
9806 private static String getPrebuildProfilePath(PackageParser.Package pkg) {
9807 return pkg.baseCodePath + ".prof";
9811 * Performs dexopt on the set of packages in {@code packages} and returns an int array
9812 * containing statistics about the invocation. The array consists of three elements,
9813 * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
9814 * and {@code numberOfPackagesFailed}.
9816 private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
9817 final String compilerFilter, boolean bootComplete) {
9819 int numberOfPackagesVisited = 0;
9820 int numberOfPackagesOptimized = 0;
9821 int numberOfPackagesSkipped = 0;
9822 int numberOfPackagesFailed = 0;
9823 final int numberOfPackagesToDexopt = pkgs.size();
9825 for (PackageParser.Package pkg : pkgs) {
9826 numberOfPackagesVisited++;
9828 boolean useProfileForDexopt = false;
9830 if ((isFirstBoot() || isUpgrade()) && isSystemApp(pkg)) {
9831 // Copy over initial preopt profiles since we won't get any JIT samples for methods
9832 // that are already compiled.
9833 File profileFile = new File(getPrebuildProfilePath(pkg));
9834 // Copy profile if it exists.
9835 if (profileFile.exists()) {
9837 // We could also do this lazily before calling dexopt in
9838 // PackageDexOptimizer to prevent this happening on first boot. The issue
9839 // is that we don't have a good way to say "do this only once".
9840 if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
9841 pkg.applicationInfo.uid, pkg.packageName)) {
9842 Log.e(TAG, "Installer failed to copy system profile!");
9844 // Disabled as this causes speed-profile compilation during first boot
9845 // even if things are already compiled.
9846 // useProfileForDexopt = true;
9848 } catch (Exception e) {
9849 Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ",
9853 PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
9854 // Handle compressed APKs in this path. Only do this for stubs with profiles to
9855 // minimize the number off apps being speed-profile compiled during first boot.
9856 // The other paths will not change the filter.
9857 if (disabledPs != null && disabledPs.pkg.isStub) {
9858 // The package is the stub one, remove the stub suffix to get the normal
9859 // package and APK names.
9860 String systemProfilePath =
9861 getPrebuildProfilePath(disabledPs.pkg).replace(STUB_SUFFIX, "");
9862 profileFile = new File(systemProfilePath);
9863 // If we have a profile for a compressed APK, copy it to the reference
9865 // Note that copying the profile here will cause it to override the
9866 // reference profile every OTA even though the existing reference profile
9867 // may have more data. We can't copy during decompression since the
9868 // directories are not set up at that point.
9869 if (profileFile.exists()) {
9871 // We could also do this lazily before calling dexopt in
9872 // PackageDexOptimizer to prevent this happening on first boot. The
9873 // issue is that we don't have a good way to say "do this only
9875 if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
9876 pkg.applicationInfo.uid, pkg.packageName)) {
9877 Log.e(TAG, "Failed to copy system profile for stub package!");
9879 useProfileForDexopt = true;
9881 } catch (Exception e) {
9882 Log.e(TAG, "Failed to copy profile " +
9883 profileFile.getAbsolutePath() + " ", e);
9890 if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
9892 Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
9894 numberOfPackagesSkipped++;
9899 Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
9900 numberOfPackagesToDexopt + ": " + pkg.packageName);
9905 ActivityManager.getService().showBootMessage(
9906 mContext.getResources().getString(R.string.android_upgrading_apk,
9907 numberOfPackagesVisited, numberOfPackagesToDexopt), true);
9908 } catch (RemoteException e) {
9910 synchronized (mPackages) {
9911 mDexOptDialogShown = true;
9915 String pkgCompilerFilter = compilerFilter;
9916 if (useProfileForDexopt) {
9917 // Use background dexopt mode to try and use the profile. Note that this does not
9918 // guarantee usage of the profile.
9920 PackageManagerServiceCompilerMapping.getCompilerFilterForReason(
9921 PackageManagerService.REASON_BACKGROUND_DEXOPT);
9924 // checkProfiles is false to avoid merging profiles during boot which
9925 // might interfere with background compilation (b/28612421).
9926 // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
9927 // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
9928 // trade-off worth doing to save boot time work.
9929 int dexoptFlags = bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0;
9930 int primaryDexOptStaus = performDexOptTraced(new DexoptOptions(
9935 switch (primaryDexOptStaus) {
9936 case PackageDexOptimizer.DEX_OPT_PERFORMED:
9937 numberOfPackagesOptimized++;
9939 case PackageDexOptimizer.DEX_OPT_SKIPPED:
9940 numberOfPackagesSkipped++;
9942 case PackageDexOptimizer.DEX_OPT_FAILED:
9943 numberOfPackagesFailed++;
9946 Log.e(TAG, "Unexpected dexopt return code " + primaryDexOptStaus);
9951 return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
9952 numberOfPackagesFailed };
9956 public void notifyPackageUse(String packageName, int reason) {
9957 synchronized (mPackages) {
9958 final int callingUid = Binder.getCallingUid();
9959 final int callingUserId = UserHandle.getUserId(callingUid);
9960 if (getInstantAppPackageName(callingUid) != null) {
9961 if (!isCallerSameApp(packageName, callingUid)) {
9965 if (isInstantApp(packageName, callingUserId)) {
9969 notifyPackageUseLocked(packageName, reason);
9973 private void notifyPackageUseLocked(String packageName, int reason) {
9974 final PackageParser.Package p = mPackages.get(packageName);
9978 p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
9982 public void notifyDexLoad(String loadingPackageName, List<String> classLoaderNames,
9983 List<String> classPaths, String loaderIsa) {
9984 int userId = UserHandle.getCallingUserId();
9985 ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
9987 Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
9988 + loadingPackageName + ", user=" + userId);
9991 mDexManager.notifyDexLoad(ai, classLoaderNames, classPaths, loaderIsa, userId);
9995 public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule,
9996 IDexModuleRegisterCallback callback) {
9997 int userId = UserHandle.getCallingUserId();
9998 ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId);
9999 DexManager.RegisterDexModuleResult result;
10001 Slog.w(TAG, "Registering a dex module for a package that does not exist for the" +
10002 " calling user. package=" + packageName + ", user=" + userId);
10003 result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
10005 result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId);
10008 if (callback != null) {
10009 mHandler.post(() -> {
10011 callback.onDexModuleRegistered(dexModulePath, result.success, result.message);
10012 } catch (RemoteException e) {
10013 Slog.w(TAG, "Failed to callback after module registration " + dexModulePath, e);
10020 * Ask the package manager to perform a dex-opt with the given compiler filter.
10022 * Note: exposed only for the shell command to allow moving packages explicitly to a
10026 public boolean performDexOptMode(String packageName,
10027 boolean checkProfiles, String targetCompilerFilter, boolean force,
10028 boolean bootComplete, String splitName) {
10029 int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0) |
10030 (force ? DexoptOptions.DEXOPT_FORCE : 0) |
10031 (bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0);
10032 return performDexOpt(new DexoptOptions(packageName, targetCompilerFilter,
10033 splitName, flags));
10037 * Ask the package manager to perform a dex-opt with the given compiler filter on the
10038 * secondary dex files belonging to the given package.
10040 * Note: exposed only for the shell command to allow moving packages explicitly to a
10044 public boolean performDexOptSecondary(String packageName, String compilerFilter,
10046 int flags = DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
10047 DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
10048 DexoptOptions.DEXOPT_BOOT_COMPLETE |
10049 (force ? DexoptOptions.DEXOPT_FORCE : 0);
10050 return performDexOpt(new DexoptOptions(packageName, compilerFilter, flags));
10053 /*package*/ boolean performDexOpt(DexoptOptions options) {
10054 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
10056 } else if (isInstantApp(options.getPackageName(), UserHandle.getCallingUserId())) {
10060 if (options.isDexoptOnlySecondaryDex()) {
10061 return mDexManager.dexoptSecondaryDex(options);
10063 int dexoptStatus = performDexOptWithStatus(options);
10064 return dexoptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
10069 * Perform dexopt on the given package and return one of following result:
10070 * {@link PackageDexOptimizer#DEX_OPT_SKIPPED}
10071 * {@link PackageDexOptimizer#DEX_OPT_PERFORMED}
10072 * {@link PackageDexOptimizer#DEX_OPT_FAILED}
10074 /* package */ int performDexOptWithStatus(DexoptOptions options) {
10075 return performDexOptTraced(options);
10078 private int performDexOptTraced(DexoptOptions options) {
10079 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
10081 return performDexOptInternal(options);
10083 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10087 // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
10088 // if the package can now be considered up to date for the given filter.
10089 private int performDexOptInternal(DexoptOptions options) {
10090 PackageParser.Package p;
10091 synchronized (mPackages) {
10092 p = mPackages.get(options.getPackageName());
10094 // Package could not be found. Report failure.
10095 return PackageDexOptimizer.DEX_OPT_FAILED;
10097 mPackageUsage.maybeWriteAsync(mPackages);
10098 mCompilerStats.maybeWriteAsync();
10100 long callingId = Binder.clearCallingIdentity();
10102 synchronized (mInstallLock) {
10103 return performDexOptInternalWithDependenciesLI(p, options);
10106 Binder.restoreCallingIdentity(callingId);
10110 public ArraySet<String> getOptimizablePackages() {
10111 ArraySet<String> pkgs = new ArraySet<String>();
10112 synchronized (mPackages) {
10113 for (PackageParser.Package p : mPackages.values()) {
10114 if (PackageDexOptimizer.canOptimizePackage(p)) {
10115 pkgs.add(p.packageName);
10122 private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
10123 DexoptOptions options) {
10124 // Select the dex optimizer based on the force parameter.
10125 // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
10126 // allocate an object here.
10127 PackageDexOptimizer pdo = options.isForce()
10128 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
10129 : mPackageDexOptimizer;
10131 // Dexopt all dependencies first. Note: we ignore the return value and march on
10133 // Note that we are going to call performDexOpt on those libraries as many times as
10134 // they are referenced in packages. When we do a batch of performDexOpt (for example
10135 // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
10136 // and the first package that uses the library will dexopt it. The
10137 // others will see that the compiled code for the library is up to date.
10138 Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
10139 final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
10140 if (!deps.isEmpty()) {
10141 DexoptOptions libraryOptions = new DexoptOptions(options.getPackageName(),
10142 options.getCompilerFilter(), options.getSplitName(),
10143 options.getFlags() | DexoptOptions.DEXOPT_AS_SHARED_LIBRARY);
10144 for (PackageParser.Package depPackage : deps) {
10145 // TODO: Analyze and investigate if we (should) profile libraries.
10146 pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
10147 getOrCreateCompilerPackageStats(depPackage),
10148 mDexManager.getPackageUseInfoOrDefault(depPackage.packageName), libraryOptions);
10151 return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets,
10152 getOrCreateCompilerPackageStats(p),
10153 mDexManager.getPackageUseInfoOrDefault(p.packageName), options);
10157 * Reconcile the information we have about the secondary dex files belonging to
10158 * {@code packagName} and the actual dex files. For all dex files that were
10159 * deleted, update the internal records and delete the generated oat files.
10162 public void reconcileSecondaryDexFiles(String packageName) {
10163 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
10165 } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
10168 mDexManager.reconcileSecondaryDexFiles(packageName);
10171 // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
10172 // a reference there.
10173 /*package*/ DexManager getDexManager() {
10174 return mDexManager;
10178 * Execute the background dexopt job immediately.
10181 public boolean runBackgroundDexoptJob() {
10182 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
10185 return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext);
10188 List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
10189 if (p.usesLibraries != null || p.usesOptionalLibraries != null
10190 || p.usesStaticLibraries != null) {
10191 ArrayList<PackageParser.Package> retValue = new ArrayList<>();
10192 Set<String> collectedNames = new HashSet<>();
10193 findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
10195 retValue.remove(p);
10199 return Collections.emptyList();
10203 private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
10204 ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
10205 if (!collectedNames.contains(p.packageName)) {
10206 collectedNames.add(p.packageName);
10209 if (p.usesLibraries != null) {
10210 findSharedNonSystemLibrariesRecursive(p.usesLibraries,
10211 null, collected, collectedNames);
10213 if (p.usesOptionalLibraries != null) {
10214 findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries,
10215 null, collected, collectedNames);
10217 if (p.usesStaticLibraries != null) {
10218 findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries,
10219 p.usesStaticLibrariesVersions, collected, collectedNames);
10224 private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, int[] versions,
10225 ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
10226 final int libNameCount = libs.size();
10227 for (int i = 0; i < libNameCount; i++) {
10228 String libName = libs.get(i);
10229 int version = (versions != null && versions.length == libNameCount)
10230 ? versions[i] : PackageManager.VERSION_CODE_HIGHEST;
10231 PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version);
10232 if (libPkg != null) {
10233 findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
10238 private PackageParser.Package findSharedNonSystemLibrary(String name, int version) {
10239 synchronized (mPackages) {
10240 SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version);
10241 if (libEntry != null) {
10242 return mPackages.get(libEntry.apk);
10248 private SharedLibraryEntry getSharedLibraryEntryLPr(String name, int version) {
10249 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10250 if (versionedLib == null) {
10253 return versionedLib.get(version);
10256 private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
10257 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
10258 pkg.staticSharedLibName);
10259 if (versionedLib == null) {
10262 int previousLibVersion = -1;
10263 final int versionCount = versionedLib.size();
10264 for (int i = 0; i < versionCount; i++) {
10265 final int libVersion = versionedLib.keyAt(i);
10266 if (libVersion < pkg.staticSharedLibVersion) {
10267 previousLibVersion = Math.max(previousLibVersion, libVersion);
10270 if (previousLibVersion >= 0) {
10271 return versionedLib.get(previousLibVersion);
10276 public void shutdown() {
10277 mPackageUsage.writeNow(mPackages);
10278 mCompilerStats.writeNow();
10279 mDexManager.writePackageDexUsageNow();
10283 public void dumpProfiles(String packageName) {
10284 PackageParser.Package pkg;
10285 synchronized (mPackages) {
10286 pkg = mPackages.get(packageName);
10288 throw new IllegalArgumentException("Unknown package: " + packageName);
10291 /* Only the shell, root, or the app user should be able to dump profiles. */
10292 int callingUid = Binder.getCallingUid();
10293 if (callingUid != Process.SHELL_UID &&
10294 callingUid != Process.ROOT_UID &&
10295 callingUid != pkg.applicationInfo.uid) {
10296 throw new SecurityException("dumpProfiles");
10299 synchronized (mInstallLock) {
10300 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
10301 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
10303 List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
10304 String codePaths = TextUtils.join(";", allCodePaths);
10305 mInstaller.dumpProfiles(sharedGid, packageName, codePaths);
10306 } catch (InstallerException e) {
10307 Slog.w(TAG, "Failed to dump profiles", e);
10309 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10314 public void forceDexOpt(String packageName) {
10315 enforceSystemOrRoot("forceDexOpt");
10317 PackageParser.Package pkg;
10318 synchronized (mPackages) {
10319 pkg = mPackages.get(packageName);
10321 throw new IllegalArgumentException("Unknown package: " + packageName);
10325 synchronized (mInstallLock) {
10326 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
10328 // Whoever is calling forceDexOpt wants a compiled package.
10329 // Don't use profiles since that may cause compilation to be skipped.
10330 final int res = performDexOptInternalWithDependenciesLI(
10332 new DexoptOptions(packageName,
10333 getDefaultCompilerFilter(),
10334 DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE));
10336 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10337 if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
10338 throw new IllegalStateException("Failed to dexopt: " + res);
10343 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
10344 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10345 Slog.w(TAG, "Unable to update from " + oldPkg.name
10346 + " to " + newPkg.packageName
10347 + ": old package not in system partition");
10349 } else if (mPackages.get(oldPkg.name) != null) {
10350 Slog.w(TAG, "Unable to update from " + oldPkg.name
10351 + " to " + newPkg.packageName
10352 + ": old package still exists");
10358 void removeCodePathLI(File codePath) {
10359 if (codePath.isDirectory()) {
10361 mInstaller.rmPackageDir(codePath.getAbsolutePath());
10362 } catch (InstallerException e) {
10363 Slog.w(TAG, "Failed to remove code path", e);
10370 private int[] resolveUserIds(int userId) {
10371 return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
10374 private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
10376 Slog.wtf(TAG, "Package was null!", new Throwable());
10379 clearAppDataLeafLIF(pkg, userId, flags);
10380 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10381 for (int i = 0; i < childCount; i++) {
10382 clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
10386 private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
10387 final PackageSetting ps;
10388 synchronized (mPackages) {
10389 ps = mSettings.mPackages.get(pkg.packageName);
10391 for (int realUserId : resolveUserIds(userId)) {
10392 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
10394 mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
10396 } catch (InstallerException e) {
10397 Slog.w(TAG, String.valueOf(e));
10402 private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
10404 Slog.wtf(TAG, "Package was null!", new Throwable());
10407 destroyAppDataLeafLIF(pkg, userId, flags);
10408 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10409 for (int i = 0; i < childCount; i++) {
10410 destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
10414 private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
10415 final PackageSetting ps;
10416 synchronized (mPackages) {
10417 ps = mSettings.mPackages.get(pkg.packageName);
10419 for (int realUserId : resolveUserIds(userId)) {
10420 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
10422 mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
10424 } catch (InstallerException e) {
10425 Slog.w(TAG, String.valueOf(e));
10427 mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
10431 private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
10433 Slog.wtf(TAG, "Package was null!", new Throwable());
10436 destroyAppProfilesLeafLIF(pkg);
10437 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10438 for (int i = 0; i < childCount; i++) {
10439 destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
10443 private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
10445 mInstaller.destroyAppProfiles(pkg.packageName);
10446 } catch (InstallerException e) {
10447 Slog.w(TAG, String.valueOf(e));
10451 private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
10453 Slog.wtf(TAG, "Package was null!", new Throwable());
10456 clearAppProfilesLeafLIF(pkg);
10457 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10458 for (int i = 0; i < childCount; i++) {
10459 clearAppProfilesLeafLIF(pkg.childPackages.get(i));
10463 private void clearAppProfilesLeafLIF(PackageParser.Package pkg) {
10465 mInstaller.clearAppProfiles(pkg.packageName);
10466 } catch (InstallerException e) {
10467 Slog.w(TAG, String.valueOf(e));
10471 private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
10472 long lastUpdateTime) {
10473 // Set parent install/update time
10474 PackageSetting ps = (PackageSetting) pkg.mExtras;
10476 ps.firstInstallTime = firstInstallTime;
10477 ps.lastUpdateTime = lastUpdateTime;
10479 // Set children install/update time
10480 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10481 for (int i = 0; i < childCount; i++) {
10482 PackageParser.Package childPkg = pkg.childPackages.get(i);
10483 ps = (PackageSetting) childPkg.mExtras;
10485 ps.firstInstallTime = firstInstallTime;
10486 ps.lastUpdateTime = lastUpdateTime;
10491 private void addSharedLibraryLPr(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
10492 PackageParser.Package changingLib) {
10493 if (file.path != null) {
10494 usesLibraryFiles.add(file.path);
10497 PackageParser.Package p = mPackages.get(file.apk);
10498 if (changingLib != null && changingLib.packageName.equals(file.apk)) {
10499 // If we are doing this while in the middle of updating a library apk,
10500 // then we need to make sure to use that new apk for determining the
10501 // dependencies here. (We haven't yet finished committing the new apk
10502 // to the package manager state.)
10503 if (p == null || p.packageName.equals(changingLib.packageName)) {
10508 usesLibraryFiles.addAll(p.getAllCodePaths());
10509 if (p.usesLibraryFiles != null) {
10510 Collections.addAll(usesLibraryFiles, p.usesLibraryFiles);
10515 private void updateSharedLibrariesLPr(PackageParser.Package pkg,
10516 PackageParser.Package changingLib) throws PackageManagerException {
10520 ArraySet<String> usesLibraryFiles = null;
10521 if (pkg.usesLibraries != null) {
10522 usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries,
10523 null, null, pkg.packageName, changingLib, true,
10524 pkg.applicationInfo.targetSdkVersion, null);
10526 if (pkg.usesStaticLibraries != null) {
10527 usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries,
10528 pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests,
10529 pkg.packageName, changingLib, true,
10530 pkg.applicationInfo.targetSdkVersion, usesLibraryFiles);
10532 if (pkg.usesOptionalLibraries != null) {
10533 usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries,
10534 null, null, pkg.packageName, changingLib, false,
10535 pkg.applicationInfo.targetSdkVersion, usesLibraryFiles);
10537 if (!ArrayUtils.isEmpty(usesLibraryFiles)) {
10538 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
10540 pkg.usesLibraryFiles = null;
10544 private ArraySet<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
10545 @Nullable int[] requiredVersions, @Nullable String[][] requiredCertDigests,
10546 @NonNull String packageName, @Nullable PackageParser.Package changingLib,
10547 boolean required, int targetSdk, @Nullable ArraySet<String> outUsedLibraries)
10548 throws PackageManagerException {
10549 final int libCount = requestedLibraries.size();
10550 for (int i = 0; i < libCount; i++) {
10551 final String libName = requestedLibraries.get(i);
10552 final int libVersion = requiredVersions != null ? requiredVersions[i]
10553 : SharedLibraryInfo.VERSION_UNDEFINED;
10554 final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion);
10555 if (libEntry == null) {
10557 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10558 "Package " + packageName + " requires unavailable shared library "
10559 + libName + "; failing!");
10560 } else if (DEBUG_SHARED_LIBRARIES) {
10561 Slog.i(TAG, "Package " + packageName
10562 + " desires unavailable shared library "
10563 + libName + "; ignoring!");
10566 if (requiredVersions != null && requiredCertDigests != null) {
10567 if (libEntry.info.getVersion() != requiredVersions[i]) {
10568 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10569 "Package " + packageName + " requires unavailable static shared"
10570 + " library " + libName + " version "
10571 + libEntry.info.getVersion() + "; failing!");
10574 PackageParser.Package libPkg = mPackages.get(libEntry.apk);
10575 if (libPkg == null) {
10576 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10577 "Package " + packageName + " requires unavailable static shared"
10578 + " library; failing!");
10581 final String[] expectedCertDigests = requiredCertDigests[i];
10582 // For apps targeting O MR1 we require explicit enumeration of all certs.
10583 final String[] libCertDigests = (targetSdk > Build.VERSION_CODES.O)
10584 ? PackageUtils.computeSignaturesSha256Digests(libPkg.mSignatures)
10585 : PackageUtils.computeSignaturesSha256Digests(
10586 new Signature[]{libPkg.mSignatures[0]});
10588 // Take a shortcut if sizes don't match. Note that if an app doesn't
10589 // target O we don't parse the "additional-certificate" tags similarly
10590 // how we only consider all certs only for apps targeting O (see above).
10591 // Therefore, the size check is safe to make.
10592 if (expectedCertDigests.length != libCertDigests.length) {
10593 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10594 "Package " + packageName + " requires differently signed" +
10595 " static sDexLoadReporter.java:45.19hared library; failing!");
10598 // Use a predictable order as signature order may vary
10599 Arrays.sort(libCertDigests);
10600 Arrays.sort(expectedCertDigests);
10602 final int certCount = libCertDigests.length;
10603 for (int j = 0; j < certCount; j++) {
10604 if (!libCertDigests[j].equalsIgnoreCase(expectedCertDigests[j])) {
10605 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10606 "Package " + packageName + " requires differently signed" +
10607 " static shared library; failing!");
10612 if (outUsedLibraries == null) {
10613 outUsedLibraries = new ArraySet<>();
10615 addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib);
10618 return outUsedLibraries;
10621 private static boolean hasString(List<String> list, List<String> which) {
10622 if (list == null) {
10625 for (int i=list.size()-1; i>=0; i--) {
10626 for (int j=which.size()-1; j>=0; j--) {
10627 if (which.get(j).equals(list.get(i))) {
10635 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
10636 PackageParser.Package changingPkg) {
10637 ArrayList<PackageParser.Package> res = null;
10638 for (PackageParser.Package pkg : mPackages.values()) {
10639 if (changingPkg != null
10640 && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
10641 && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
10642 && !ArrayUtils.contains(pkg.usesStaticLibraries,
10643 changingPkg.staticSharedLibName)) {
10647 res = new ArrayList<>();
10651 updateSharedLibrariesLPr(pkg, changingPkg);
10652 } catch (PackageManagerException e) {
10653 // If a system app update or an app and a required lib missing we
10654 // delete the package and for updated system apps keep the data as
10655 // it is better for the user to reinstall than to be in an limbo
10656 // state. Also libs disappearing under an app should never happen
10658 if (!pkg.isSystemApp() || pkg.isUpdatedSystemApp()) {
10659 final int flags = pkg.isUpdatedSystemApp()
10660 ? PackageManager.DELETE_KEEP_DATA : 0;
10661 deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
10662 flags , null, true, null);
10664 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
10671 * Derive the value of the {@code cpuAbiOverride} based on the provided
10672 * value and an optional stored value from the package settings.
10674 private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
10675 String cpuAbiOverride = null;
10677 if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
10678 cpuAbiOverride = null;
10679 } else if (abiOverride != null) {
10680 cpuAbiOverride = abiOverride;
10681 } else if (settings != null) {
10682 cpuAbiOverride = settings.cpuAbiOverrideString;
10685 return cpuAbiOverride;
10688 private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
10689 final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
10690 throws PackageManagerException {
10691 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
10692 // If the package has children and this is the first dive in the function
10693 // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
10694 // whether all packages (parent and children) would be successfully scanned
10695 // before the actual scan since scanning mutates internal state and we want
10696 // to atomically install the package and its children.
10697 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10698 if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
10699 scanFlags |= SCAN_CHECK_ONLY;
10702 scanFlags &= ~SCAN_CHECK_ONLY;
10705 final PackageParser.Package scannedPkg;
10708 scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user);
10709 // Scan the children
10710 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10711 for (int i = 0; i < childCount; i++) {
10712 PackageParser.Package childPkg = pkg.childPackages.get(i);
10713 scanPackageLI(childPkg, policyFlags,
10714 scanFlags, currentTime, user);
10717 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10720 if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10721 return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user);
10727 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags,
10728 int scanFlags, long currentTime, @Nullable UserHandle user)
10729 throws PackageManagerException {
10730 boolean success = false;
10732 final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags,
10733 currentTime, user);
10737 if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
10738 // DELETE_DATA_ON_FAILURES is only used by frozen paths
10739 destroyAppDataLIF(pkg, UserHandle.USER_ALL,
10740 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
10741 destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
10747 * Returns {@code true} if the given file contains code. Otherwise {@code false}.
10749 private static boolean apkHasCode(String fileName) {
10750 StrictJarFile jarFile = null;
10752 jarFile = new StrictJarFile(fileName,
10753 false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
10754 return jarFile.findEntry("classes.dex") != null;
10755 } catch (IOException ignore) {
10758 if (jarFile != null) {
10761 } catch (IOException ignore) {}
10767 * Enforces code policy for the package. This ensures that if an APK has
10768 * declared hasCode="true" in its manifest that the APK actually contains
10771 * @throws PackageManagerException If bytecode could not be found when it should exist
10773 private static void assertCodePolicy(PackageParser.Package pkg)
10774 throws PackageManagerException {
10775 final boolean shouldHaveCode =
10776 (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
10777 if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
10778 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10779 "Package " + pkg.baseCodePath + " code is missing");
10782 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
10783 for (int i = 0; i < pkg.splitCodePaths.length; i++) {
10784 final boolean splitShouldHaveCode =
10785 (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
10786 if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
10787 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10788 "Package " + pkg.splitCodePaths[i] + " code is missing");
10794 private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,
10795 final int policyFlags, final int scanFlags, long currentTime, @Nullable UserHandle user)
10796 throws PackageManagerException {
10797 if (DEBUG_PACKAGE_SCANNING) {
10798 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
10799 Log.d(TAG, "Scanning package " + pkg.packageName);
10802 applyPolicy(pkg, policyFlags);
10804 assertPackageIsValid(pkg, policyFlags, scanFlags);
10806 // Initialize package source and resource directories
10807 final File scanFile = new File(pkg.codePath);
10808 final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
10809 final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
10811 SharedUserSetting suid = null;
10812 PackageSetting pkgSetting = null;
10814 // Getting the package setting may have a side-effect, so if we
10815 // are only checking if scan would succeed, stash a copy of the
10816 // old setting to restore at the end.
10817 PackageSetting nonMutatedPs = null;
10819 // We keep references to the derived CPU Abis from settings in oder to reuse
10820 // them in the case where we're not upgrading or booting for the first time.
10821 String primaryCpuAbiFromSettings = null;
10822 String secondaryCpuAbiFromSettings = null;
10824 final PackageParser.Package oldPkg;
10827 synchronized (mPackages) {
10828 if (pkg.mSharedUserId != null) {
10829 // SIDE EFFECTS; may potentially allocate a new shared user
10830 suid = mSettings.getSharedUserLPw(
10831 pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
10832 if (DEBUG_PACKAGE_SCANNING) {
10833 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
10834 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
10835 + "): packages=" + suid.packages);
10839 // Check if we are renaming from an original package name.
10840 PackageSetting origPackage = null;
10841 String realName = null;
10842 if (pkg.mOriginalPackages != null) {
10843 // This package may need to be renamed to a previously
10844 // installed name. Let's check on that...
10845 final String renamed = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
10846 if (pkg.mOriginalPackages.contains(renamed)) {
10847 // This package had originally been installed as the
10848 // original name, and we have already taken care of
10849 // transitioning to the new one. Just update the new
10850 // one to continue using the old name.
10851 realName = pkg.mRealPackage;
10852 if (!pkg.packageName.equals(renamed)) {
10853 // Callers into this function may have already taken
10854 // care of renaming the package; only do it here if
10855 // it is not already done.
10856 pkg.setPackageName(renamed);
10859 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
10860 if ((origPackage = mSettings.getPackageLPr(
10861 pkg.mOriginalPackages.get(i))) != null) {
10862 // We do have the package already installed under its
10863 // original name... should we use it?
10864 if (!verifyPackageUpdateLPr(origPackage, pkg)) {
10865 // New package is not compatible with original.
10866 origPackage = null;
10868 } else if (origPackage.sharedUser != null) {
10869 // Make sure uid is compatible between packages.
10870 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
10871 Slog.w(TAG, "Unable to migrate data from " + origPackage.name
10872 + " to " + pkg.packageName + ": old uid "
10873 + origPackage.sharedUser.name
10874 + " differs from " + pkg.mSharedUserId);
10875 origPackage = null;
10878 // TODO: Add case when shared user id is added [b/28144775]
10880 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
10881 + pkg.packageName + " to old name " + origPackage.name);
10889 if (mTransferedPackages.contains(pkg.packageName)) {
10890 Slog.w(TAG, "Package " + pkg.packageName
10891 + " was transferred to another, but its .apk remains");
10894 // See comments in nonMutatedPs declaration
10895 if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10896 PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
10897 if (foundPs != null) {
10898 nonMutatedPs = new PackageSetting(foundPs);
10902 if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) == 0) {
10903 PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
10904 if (foundPs != null) {
10905 primaryCpuAbiFromSettings = foundPs.primaryCpuAbiString;
10906 secondaryCpuAbiFromSettings = foundPs.secondaryCpuAbiString;
10910 pkgSetting = mSettings.getPackageLPr(pkg.packageName);
10911 if (pkgSetting != null && pkgSetting.sharedUser != suid) {
10912 PackageManagerService.reportSettingsProblem(Log.WARN,
10913 "Package " + pkg.packageName + " shared user changed from "
10914 + (pkgSetting.sharedUser != null
10915 ? pkgSetting.sharedUser.name : "<nothing>")
10917 + (suid != null ? suid.name : "<nothing>")
10918 + "; replacing with new");
10921 final PackageSetting oldPkgSetting =
10922 pkgSetting == null ? null : new PackageSetting(pkgSetting);
10923 final PackageSetting disabledPkgSetting =
10924 mSettings.getDisabledSystemPkgLPr(pkg.packageName);
10926 if (oldPkgSetting == null) {
10929 oldPkg = oldPkgSetting.pkg;
10932 String[] usesStaticLibraries = null;
10933 if (pkg.usesStaticLibraries != null) {
10934 usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
10935 pkg.usesStaticLibraries.toArray(usesStaticLibraries);
10938 if (pkgSetting == null) {
10939 final String parentPackageName = (pkg.parentPackage != null)
10940 ? pkg.parentPackage.packageName : null;
10941 final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
10942 final boolean virtualPreload = (scanFlags & SCAN_AS_VIRTUAL_PRELOAD) != 0;
10943 // REMOVE SharedUserSetting from method; update in a separate call
10944 pkgSetting = Settings.createNewSetting(pkg.packageName, origPackage,
10945 disabledPkgSetting, realName, suid, destCodeFile, destResourceFile,
10946 pkg.applicationInfo.nativeLibraryRootDir, pkg.applicationInfo.primaryCpuAbi,
10947 pkg.applicationInfo.secondaryCpuAbi, pkg.mVersionCode,
10948 pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, user,
10949 true /*allowInstall*/, instantApp, virtualPreload,
10950 parentPackageName, pkg.getChildPackageNames(),
10951 UserManagerService.getInstance(), usesStaticLibraries,
10952 pkg.usesStaticLibrariesVersions);
10953 // SIDE EFFECTS; updates system state; move elsewhere
10954 if (origPackage != null) {
10955 mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name);
10957 mSettings.addUserToSettingLPw(pkgSetting);
10959 // REMOVE SharedUserSetting from method; update in a separate call.
10961 // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
10962 // secondaryCpuAbi are not known at this point so we always update them
10963 // to null here, only to reset them at a later point.
10964 Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, suid, destCodeFile,
10965 pkg.applicationInfo.nativeLibraryDir, pkg.applicationInfo.primaryCpuAbi,
10966 pkg.applicationInfo.secondaryCpuAbi, pkg.applicationInfo.flags,
10967 pkg.applicationInfo.privateFlags, pkg.getChildPackageNames(),
10968 UserManagerService.getInstance(), usesStaticLibraries,
10969 pkg.usesStaticLibrariesVersions);
10971 // SIDE EFFECTS; persists system state to files on disk; move elsewhere
10972 mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
10974 // SIDE EFFECTS; modifies system state; move elsewhere
10975 if (pkgSetting.origPackage != null) {
10976 // If we are first transitioning from an original package,
10977 // fix up the new package's name now. We need to do this after
10978 // looking up the package under its new name, so getPackageLP
10979 // can take care of fiddling things correctly.
10980 pkg.setPackageName(origPackage.name);
10982 // File a report about this.
10983 String msg = "New package " + pkgSetting.realName
10984 + " renamed to replace old package " + pkgSetting.name;
10985 reportSettingsProblem(Log.WARN, msg);
10987 // Make a note of it.
10988 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10989 mTransferedPackages.add(origPackage.name);
10992 // No longer need to retain this.
10993 pkgSetting.origPackage = null;
10996 // SIDE EFFECTS; modifies system state; move elsewhere
10997 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) {
10998 // Make a note of it.
10999 mTransferedPackages.add(pkg.packageName);
11002 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
11003 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
11006 if ((scanFlags & SCAN_BOOTING) == 0
11007 && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
11008 // Check all shared libraries and map to their actual file path.
11009 // We only do this here for apps not on a system dir, because those
11010 // are the only ones that can fail an install due to this. We
11011 // will take care of the system apps by updating all of their
11012 // library paths after the scan is done. Also during the initial
11013 // scan don't update any libs as we do this wholesale after all
11014 // apps are scanned to avoid dependency based scanning.
11015 updateSharedLibrariesLPr(pkg, null);
11018 if (mFoundPolicyFile) {
11019 SELinuxMMAC.assignSeInfoValue(pkg);
11021 pkg.applicationInfo.uid = pkgSetting.appId;
11022 pkg.mExtras = pkgSetting;
11025 // Static shared libs have same package with different versions where
11026 // we internally use a synthetic package name to allow multiple versions
11027 // of the same package, therefore we need to compare signatures against
11028 // the package setting for the latest library version.
11029 PackageSetting signatureCheckPs = pkgSetting;
11030 if (pkg.applicationInfo.isStaticSharedLibrary()) {
11031 SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
11032 if (libraryEntry != null) {
11033 signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
11037 if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
11038 if (checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
11039 // We just determined the app is signed correctly, so bring
11040 // over the latest parsed certs.
11041 pkgSetting.signatures.mSignatures = pkg.mSignatures;
11043 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
11044 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
11045 "Package " + pkg.packageName + " upgrade keys do not match the "
11046 + "previously installed version");
11048 pkgSetting.signatures.mSignatures = pkg.mSignatures;
11049 String msg = "System package " + pkg.packageName
11050 + " signature changed; retaining data.";
11051 reportSettingsProblem(Log.WARN, msg);
11056 // SIDE EFFECTS; compareSignaturesCompat() changes KeysetManagerService
11057 verifySignaturesLP(signatureCheckPs, pkg);
11058 // We just determined the app is signed correctly, so bring
11059 // over the latest parsed certs.
11060 pkgSetting.signatures.mSignatures = pkg.mSignatures;
11061 } catch (PackageManagerException e) {
11062 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
11065 // The signature has changed, but this package is in the system
11066 // image... let's recover!
11067 pkgSetting.signatures.mSignatures = pkg.mSignatures;
11068 // However... if this package is part of a shared user, but it
11069 // doesn't match the signature of the shared user, let's fail.
11070 // What this means is that you can't change the signatures
11071 // associated with an overall shared user, which doesn't seem all
11072 // that unreasonable.
11073 if (signatureCheckPs.sharedUser != null) {
11074 if (compareSignatures(signatureCheckPs.sharedUser.signatures.mSignatures,
11075 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
11076 throw new PackageManagerException(
11077 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
11078 "Signature mismatch for shared user: "
11079 + pkgSetting.sharedUser);
11082 // File a report about this.
11083 String msg = "System package " + pkg.packageName
11084 + " signature changed; retaining data.";
11085 reportSettingsProblem(Log.WARN, msg);
11089 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
11090 // This package wants to adopt ownership of permissions from
11091 // another package.
11092 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
11093 final String origName = pkg.mAdoptPermissions.get(i);
11094 final PackageSetting orig = mSettings.getPackageLPr(origName);
11095 if (orig != null) {
11096 if (verifyPackageUpdateLPr(orig, pkg)) {
11097 Slog.i(TAG, "Adopting permissions from " + origName + " to "
11098 + pkg.packageName);
11099 // SIDE EFFECTS; updates permissions system state; move elsewhere
11100 mSettings.transferPermissionsLPw(origName, pkg.packageName);
11107 pkg.applicationInfo.processName = fixProcessName(
11108 pkg.applicationInfo.packageName,
11109 pkg.applicationInfo.processName);
11111 if (pkg != mPlatformPackage) {
11112 // Get all of our default paths setup
11113 pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
11116 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
11118 if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
11119 if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) {
11120 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
11121 final boolean extractNativeLibs = !pkg.isLibrary();
11122 derivePackageAbi(pkg, scanFile, cpuAbiOverride, extractNativeLibs,
11123 mAppLib32InstallDir);
11124 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11126 // Some system apps still use directory structure for native libraries
11127 // in which case we might end up not detecting abi solely based on apk
11128 // structure. Try to detect abi based on directory structure.
11129 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
11130 pkg.applicationInfo.primaryCpuAbi == null) {
11131 setBundledAppAbisAndRoots(pkg, pkgSetting);
11132 setNativeLibraryPaths(pkg, mAppLib32InstallDir);
11135 // This is not a first boot or an upgrade, don't bother deriving the
11136 // ABI during the scan. Instead, trust the value that was stored in the
11137 // package setting.
11138 pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
11139 pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
11141 setNativeLibraryPaths(pkg, mAppLib32InstallDir);
11143 if (DEBUG_ABI_SELECTION) {
11144 Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
11145 pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
11146 pkg.applicationInfo.secondaryCpuAbi);
11150 if ((scanFlags & SCAN_MOVE) != 0) {
11151 // We haven't run dex-opt for this move (since we've moved the compiled output too)
11152 // but we already have this packages package info in the PackageSetting. We just
11153 // use that and derive the native library path based on the new codepath.
11154 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
11155 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
11158 // Set native library paths again. For moves, the path will be updated based on the
11159 // ABIs we've determined above. For non-moves, the path will be updated based on the
11160 // ABIs we determined during compilation, but the path will depend on the final
11161 // package path (after the rename away from the stage path).
11162 setNativeLibraryPaths(pkg, mAppLib32InstallDir);
11165 // This is a special case for the "system" package, where the ABI is
11166 // dictated by the zygote configuration (and init.rc). We should keep track
11167 // of this ABI so that we can deal with "normal" applications that run under
11168 // the same UID correctly.
11169 if (mPlatformPackage == pkg) {
11170 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
11171 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
11174 // If there's a mismatch between the abi-override in the package setting
11175 // and the abiOverride specified for the install. Warn about this because we
11176 // would've already compiled the app without taking the package setting into
11178 if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
11179 if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
11180 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
11181 " for package " + pkg.packageName);
11185 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
11186 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
11187 pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
11189 // Copy the derived override back to the parsed package, so that we can
11190 // update the package settings accordingly.
11191 pkg.cpuAbiOverride = cpuAbiOverride;
11193 if (DEBUG_ABI_SELECTION) {
11194 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
11195 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
11196 + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
11199 // Push the derived path down into PackageSettings so we know what to
11200 // clean up at uninstall time.
11201 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
11203 if (DEBUG_ABI_SELECTION) {
11204 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
11205 " primary=" + pkg.applicationInfo.primaryCpuAbi +
11206 " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
11209 // SIDE EFFECTS; removes DEX files from disk; move elsewhere
11210 if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
11211 // We don't do this here during boot because we can do it all
11212 // at once after scanning all existing packages.
11214 // We also do this *before* we perform dexopt on this package, so that
11215 // we can avoid redundant dexopts, and also to make sure we've got the
11216 // code and package path correct.
11217 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
11220 if (mFactoryTest && pkg.requestedPermissions.contains(
11221 android.Manifest.permission.FACTORY_TEST)) {
11222 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
11225 if (isSystemApp(pkg)) {
11226 pkgSetting.isOrphaned = true;
11229 // Take care of first install / last update times.
11230 final long scanFileTime = getLastModifiedTime(pkg, scanFile);
11231 if (currentTime != 0) {
11232 if (pkgSetting.firstInstallTime == 0) {
11233 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
11234 } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
11235 pkgSetting.lastUpdateTime = currentTime;
11237 } else if (pkgSetting.firstInstallTime == 0) {
11238 // We need *something*. Take time time stamp of the file.
11239 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
11240 } else if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
11241 if (scanFileTime != pkgSetting.timeStamp) {
11242 // A package on the system image has changed; consider this
11243 // to be an update.
11244 pkgSetting.lastUpdateTime = scanFileTime;
11247 pkgSetting.setTimeStamp(scanFileTime);
11249 if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
11250 if (nonMutatedPs != null) {
11251 synchronized (mPackages) {
11252 mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs);
11256 final int userId = user == null ? 0 : user.getIdentifier();
11257 // Modify state for the given package setting
11258 commitPackageSettings(pkg, pkgSetting, user, scanFlags,
11259 (policyFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
11260 if (pkgSetting.getInstantApp(userId)) {
11261 mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
11265 if (oldPkg != null) {
11266 // We need to call revokeRuntimePermissionsIfGroupChanged async as permission
11267 // revokation from this method might need to kill apps which need the
11268 // mPackages lock on a different thread. This would dead lock.
11270 // Hence create a copy of all package names and pass it into
11271 // revokeRuntimePermissionsIfGroupChanged. Only for those permissions might get
11272 // revoked. If a new package is added before the async code runs the permission
11273 // won't be granted yet, hence new packages are no problem.
11274 final ArrayList<String> allPackageNames = new ArrayList<>(mPackages.keySet());
11276 AsyncTask.execute(new Runnable() {
11277 public void run() {
11278 revokeRuntimePermissionsIfGroupChanged(pkg, oldPkg, allPackageNames);
11287 * Applies policy to the parsed package based upon the given policy flags.
11288 * Ensures the package is in a good state.
11290 * Implementation detail: This method must NOT have any side effect. It would
11291 * ideally be static, but, it requires locks to read system state.
11293 private void applyPolicy(PackageParser.Package pkg, int policyFlags) {
11294 if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
11295 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
11296 if (pkg.applicationInfo.isDirectBootAware()) {
11297 // we're direct boot aware; set for all components
11298 for (PackageParser.Service s : pkg.services) {
11299 s.info.encryptionAware = s.info.directBootAware = true;
11301 for (PackageParser.Provider p : pkg.providers) {
11302 p.info.encryptionAware = p.info.directBootAware = true;
11304 for (PackageParser.Activity a : pkg.activities) {
11305 a.info.encryptionAware = a.info.directBootAware = true;
11307 for (PackageParser.Activity r : pkg.receivers) {
11308 r.info.encryptionAware = r.info.directBootAware = true;
11311 if (compressedFileExists(pkg.codePath)) {
11315 // Only allow system apps to be flagged as core apps.
11316 pkg.coreApp = false;
11317 // clear flags not applicable to regular apps
11318 pkg.applicationInfo.privateFlags &=
11319 ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
11320 pkg.applicationInfo.privateFlags &=
11321 ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
11323 pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0;
11325 if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
11326 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
11329 if (!isSystemApp(pkg)) {
11330 // Only system apps can use these features.
11331 pkg.mOriginalPackages = null;
11332 pkg.mRealPackage = null;
11333 pkg.mAdoptPermissions = null;
11338 * Asserts the parsed package is valid according to the given policy. If the
11339 * package is invalid, for whatever reason, throws {@link PackageManagerException}.
11341 * Implementation detail: This method must NOT have any side effects. It would
11342 * ideally be static, but, it requires locks to read system state.
11344 * @throws PackageManagerException If the package fails any of the validation checks
11346 private void assertPackageIsValid(PackageParser.Package pkg, int policyFlags, int scanFlags)
11347 throws PackageManagerException {
11348 if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
11349 assertCodePolicy(pkg);
11352 if (pkg.applicationInfo.getCodePath() == null ||
11353 pkg.applicationInfo.getResourcePath() == null) {
11354 // Bail out. The resource and code paths haven't been set.
11355 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
11356 "Code and resource paths haven't been set correctly");
11359 // Make sure we're not adding any bogus keyset info
11360 KeySetManagerService ksms = mSettings.mKeySetManagerService;
11361 ksms.assertScannedPackageValid(pkg);
11363 synchronized (mPackages) {
11364 // The special "android" package can only be defined once
11365 if (pkg.packageName.equals("android")) {
11366 if (mAndroidApplication != null) {
11367 Slog.w(TAG, "*************************************************");
11368 Slog.w(TAG, "Core android package being redefined. Skipping.");
11369 Slog.w(TAG, " codePath=" + pkg.codePath);
11370 Slog.w(TAG, "*************************************************");
11371 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
11372 "Core android package being redefined. Skipping.");
11376 // A package name must be unique; don't allow duplicates
11377 if (mPackages.containsKey(pkg.packageName)) {
11378 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
11379 "Application package " + pkg.packageName
11380 + " already installed. Skipping duplicate.");
11383 if (pkg.applicationInfo.isStaticSharedLibrary()) {
11384 // Static libs have a synthetic package name containing the version
11385 // but we still want the base name to be unique.
11386 if (mPackages.containsKey(pkg.manifestPackageName)) {
11387 throw new PackageManagerException(
11388 "Duplicate static shared lib provider package");
11391 // Static shared libraries should have at least O target SDK
11392 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
11393 throw new PackageManagerException(
11394 "Packages declaring static-shared libs must target O SDK or higher");
11397 // Package declaring static a shared lib cannot be instant apps
11398 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11399 throw new PackageManagerException(
11400 "Packages declaring static-shared libs cannot be instant apps");
11403 // Package declaring static a shared lib cannot be renamed since the package
11404 // name is synthetic and apps can't code around package manager internals.
11405 if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) {
11406 throw new PackageManagerException(
11407 "Packages declaring static-shared libs cannot be renamed");
11410 // Package declaring static a shared lib cannot declare child packages
11411 if (!ArrayUtils.isEmpty(pkg.childPackages)) {
11412 throw new PackageManagerException(
11413 "Packages declaring static-shared libs cannot have child packages");
11416 // Package declaring static a shared lib cannot declare dynamic libs
11417 if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
11418 throw new PackageManagerException(
11419 "Packages declaring static-shared libs cannot declare dynamic libs");
11422 // Package declaring static a shared lib cannot declare shared users
11423 if (pkg.mSharedUserId != null) {
11424 throw new PackageManagerException(
11425 "Packages declaring static-shared libs cannot declare shared users");
11428 // Static shared libs cannot declare activities
11429 if (!pkg.activities.isEmpty()) {
11430 throw new PackageManagerException(
11431 "Static shared libs cannot declare activities");
11434 // Static shared libs cannot declare services
11435 if (!pkg.services.isEmpty()) {
11436 throw new PackageManagerException(
11437 "Static shared libs cannot declare services");
11440 // Static shared libs cannot declare providers
11441 if (!pkg.providers.isEmpty()) {
11442 throw new PackageManagerException(
11443 "Static shared libs cannot declare content providers");
11446 // Static shared libs cannot declare receivers
11447 if (!pkg.receivers.isEmpty()) {
11448 throw new PackageManagerException(
11449 "Static shared libs cannot declare broadcast receivers");
11452 // Static shared libs cannot declare permission groups
11453 if (!pkg.permissionGroups.isEmpty()) {
11454 throw new PackageManagerException(
11455 "Static shared libs cannot declare permission groups");
11458 // Static shared libs cannot declare permissions
11459 if (!pkg.permissions.isEmpty()) {
11460 throw new PackageManagerException(
11461 "Static shared libs cannot declare permissions");
11464 // Static shared libs cannot declare protected broadcasts
11465 if (pkg.protectedBroadcasts != null) {
11466 throw new PackageManagerException(
11467 "Static shared libs cannot declare protected broadcasts");
11470 // Static shared libs cannot be overlay targets
11471 if (pkg.mOverlayTarget != null) {
11472 throw new PackageManagerException(
11473 "Static shared libs cannot be overlay targets");
11476 // The version codes must be ordered as lib versions
11477 int minVersionCode = Integer.MIN_VALUE;
11478 int maxVersionCode = Integer.MAX_VALUE;
11480 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
11481 pkg.staticSharedLibName);
11482 if (versionedLib != null) {
11483 final int versionCount = versionedLib.size();
11484 for (int i = 0; i < versionCount; i++) {
11485 SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
11486 final int libVersionCode = libInfo.getDeclaringPackage()
11488 if (libInfo.getVersion() < pkg.staticSharedLibVersion) {
11489 minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
11490 } else if (libInfo.getVersion() > pkg.staticSharedLibVersion) {
11491 maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
11493 minVersionCode = maxVersionCode = libVersionCode;
11498 if (pkg.mVersionCode < minVersionCode || pkg.mVersionCode > maxVersionCode) {
11499 throw new PackageManagerException("Static shared"
11500 + " lib version codes must be ordered as lib versions");
11504 // Only privileged apps and updated privileged apps can add child packages.
11505 if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
11506 if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) {
11507 throw new PackageManagerException("Only privileged apps can add child "
11508 + "packages. Ignoring package " + pkg.packageName);
11510 final int childCount = pkg.childPackages.size();
11511 for (int i = 0; i < childCount; i++) {
11512 PackageParser.Package childPkg = pkg.childPackages.get(i);
11513 if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
11514 childPkg.packageName)) {
11515 throw new PackageManagerException("Can't override child of "
11516 + "another disabled app. Ignoring package " + pkg.packageName);
11521 // If we're only installing presumed-existing packages, require that the
11522 // scanned APK is both already known and at the path previously established
11523 // for it. Previously unknown packages we pick up normally, but if we have an
11524 // a priori expectation about this package's install presence, enforce it.
11525 // With a singular exception for new system packages. When an OTA contains
11526 // a new system package, we allow the codepath to change from a system location
11527 // to the user-installed location. If we don't allow this change, any newer,
11528 // user-installed version of the application will be ignored.
11529 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
11530 if (mExpectingBetter.containsKey(pkg.packageName)) {
11531 logCriticalInfo(Log.WARN,
11532 "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
11534 PackageSetting known = mSettings.getPackageLPr(pkg.packageName);
11535 if (known != null) {
11536 if (DEBUG_PACKAGE_SCANNING) {
11537 Log.d(TAG, "Examining " + pkg.codePath
11538 + " and requiring known paths " + known.codePathString
11539 + " & " + known.resourcePathString);
11541 if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
11542 || !pkg.applicationInfo.getResourcePath().equals(
11543 known.resourcePathString)) {
11544 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
11545 "Application package " + pkg.packageName
11546 + " found at " + pkg.applicationInfo.getCodePath()
11547 + " but expected at " + known.codePathString
11551 throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
11552 "Application package " + pkg.packageName
11553 + " not found; ignoring.");
11558 // Verify that this new package doesn't have any content providers
11559 // that conflict with existing packages. Only do this if the
11560 // package isn't already installed, since we don't want to break
11561 // things that are installed.
11562 if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
11563 final int N = pkg.providers.size();
11565 for (i=0; i<N; i++) {
11566 PackageParser.Provider p = pkg.providers.get(i);
11567 if (p.info.authority != null) {
11568 String names[] = p.info.authority.split(";");
11569 for (int j = 0; j < names.length; j++) {
11570 if (mProvidersByAuthority.containsKey(names[j])) {
11571 PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
11572 final String otherPackageName =
11573 ((other != null && other.getComponentName() != null) ?
11574 other.getComponentName().getPackageName() : "?");
11575 throw new PackageManagerException(
11576 INSTALL_FAILED_CONFLICTING_PROVIDER,
11577 "Can't install because provider name " + names[j]
11578 + " (in package " + pkg.applicationInfo.packageName
11579 + ") is already used by " + otherPackageName);
11588 private boolean addSharedLibraryLPw(String path, String apk, String name, int version,
11589 int type, String declaringPackageName, int declaringVersionCode) {
11590 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
11591 if (versionedLib == null) {
11592 versionedLib = new SparseArray<>();
11593 mSharedLibraries.put(name, versionedLib);
11594 if (type == SharedLibraryInfo.TYPE_STATIC) {
11595 mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
11597 } else if (versionedLib.indexOfKey(version) >= 0) {
11600 SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name,
11601 version, type, declaringPackageName, declaringVersionCode);
11602 versionedLib.put(version, libEntry);
11606 private boolean removeSharedLibraryLPw(String name, int version) {
11607 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
11608 if (versionedLib == null) {
11611 final int libIdx = versionedLib.indexOfKey(version);
11615 SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx);
11616 versionedLib.remove(version);
11617 if (versionedLib.size() <= 0) {
11618 mSharedLibraries.remove(name);
11619 if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) {
11620 mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage()
11621 .getPackageName());
11628 * Adds a scanned package to the system. When this method is finished, the package will
11629 * be available for query, resolution, etc...
11631 private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting,
11632 UserHandle user, int scanFlags, boolean chatty) throws PackageManagerException {
11633 final String pkgName = pkg.packageName;
11634 if (mCustomResolverComponentName != null &&
11635 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
11636 setUpCustomResolverActivity(pkg);
11639 if (pkg.packageName.equals("android")) {
11640 synchronized (mPackages) {
11641 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
11642 // Set up information for our fall-back user intent resolution activity.
11643 mPlatformPackage = pkg;
11644 pkg.mVersionCode = mSdkVersion;
11645 mAndroidApplication = pkg.applicationInfo;
11646 if (!mResolverReplaced) {
11647 mResolveActivity.applicationInfo = mAndroidApplication;
11648 mResolveActivity.name = ResolverActivity.class.getName();
11649 mResolveActivity.packageName = mAndroidApplication.packageName;
11650 mResolveActivity.processName = "system:ui";
11651 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11652 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
11653 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
11654 mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
11655 mResolveActivity.exported = true;
11656 mResolveActivity.enabled = true;
11657 mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
11658 mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
11659 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
11660 | ActivityInfo.CONFIG_SCREEN_LAYOUT
11661 | ActivityInfo.CONFIG_ORIENTATION
11662 | ActivityInfo.CONFIG_KEYBOARD
11663 | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
11664 mResolveInfo.activityInfo = mResolveActivity;
11665 mResolveInfo.priority = 0;
11666 mResolveInfo.preferredOrder = 0;
11667 mResolveInfo.match = 0;
11668 mResolveComponentName = new ComponentName(
11669 mAndroidApplication.packageName, mResolveActivity.name);
11675 ArrayList<PackageParser.Package> clientLibPkgs = null;
11677 synchronized (mPackages) {
11678 boolean hasStaticSharedLibs = false;
11680 // Any app can add new static shared libraries
11681 if (pkg.staticSharedLibName != null) {
11682 // Static shared libs don't allow renaming as they have synthetic package
11683 // names to allow install of multiple versions, so use name from manifest.
11684 if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName,
11685 pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC,
11686 pkg.manifestPackageName, pkg.mVersionCode)) {
11687 hasStaticSharedLibs = true;
11689 Slog.w(TAG, "Package " + pkg.packageName + " library "
11690 + pkg.staticSharedLibName + " already exists; skipping");
11692 // Static shared libs cannot be updated once installed since they
11693 // use synthetic package name which includes the version code, so
11694 // not need to update other packages's shared lib dependencies.
11697 if (!hasStaticSharedLibs
11698 && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11699 // Only system apps can add new dynamic shared libraries.
11700 if (pkg.libraryNames != null) {
11701 for (int i = 0; i < pkg.libraryNames.size(); i++) {
11702 String name = pkg.libraryNames.get(i);
11703 boolean allowed = false;
11704 if (pkg.isUpdatedSystemApp()) {
11705 // New library entries can only be added through the
11706 // system image. This is important to get rid of a lot
11707 // of nasty edge cases: for example if we allowed a non-
11708 // system update of the app to add a library, then uninstalling
11709 // the update would make the library go away, and assumptions
11710 // we made such as through app install filtering would now
11711 // have allowed apps on the device which aren't compatible
11712 // with it. Better to just have the restriction here, be
11713 // conservative, and create many fewer cases that can negatively
11714 // impact the user experience.
11715 final PackageSetting sysPs = mSettings
11716 .getDisabledSystemPkgLPr(pkg.packageName);
11717 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
11718 for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
11719 if (name.equals(sysPs.pkg.libraryNames.get(j))) {
11729 if (!addSharedLibraryLPw(null, pkg.packageName, name,
11730 SharedLibraryInfo.VERSION_UNDEFINED,
11731 SharedLibraryInfo.TYPE_DYNAMIC,
11732 pkg.packageName, pkg.mVersionCode)) {
11733 Slog.w(TAG, "Package " + pkg.packageName + " library "
11734 + name + " already exists; skipping");
11737 Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
11738 + name + " that is not declared on system image; skipping");
11742 if ((scanFlags & SCAN_BOOTING) == 0) {
11743 // If we are not booting, we need to update any applications
11744 // that are clients of our shared library. If we are booting,
11745 // this will all be done once the scan is complete.
11746 clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
11752 if ((scanFlags & SCAN_BOOTING) != 0) {
11753 // No apps can run during boot scan, so they don't need to be frozen
11754 } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
11755 // Caller asked to not kill app, so it's probably not frozen
11756 } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
11757 // Caller asked us to ignore frozen check for some reason; they
11758 // probably didn't know the package name
11760 // We're doing major surgery on this package, so it better be frozen
11761 // right now to keep it from launching
11762 checkPackageFrozen(pkgName);
11765 // Also need to kill any apps that are dependent on the library.
11766 if (clientLibPkgs != null) {
11767 for (int i=0; i<clientLibPkgs.size(); i++) {
11768 PackageParser.Package clientPkg = clientLibPkgs.get(i);
11769 killApplication(clientPkg.applicationInfo.packageName,
11770 clientPkg.applicationInfo.uid, "update lib");
11775 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
11777 synchronized (mPackages) {
11778 // We don't expect installation to fail beyond this point
11780 // Add the new setting to mSettings
11781 mSettings.insertPackageSettingLPw(pkgSetting, pkg);
11782 // Add the new setting to mPackages
11783 mPackages.put(pkg.applicationInfo.packageName, pkg);
11784 // Make sure we don't accidentally delete its data.
11785 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
11786 while (iter.hasNext()) {
11787 PackageCleanItem item = iter.next();
11788 if (pkgName.equals(item.packageName)) {
11793 // Add the package's KeySets to the global KeySetManagerService
11794 KeySetManagerService ksms = mSettings.mKeySetManagerService;
11795 ksms.addScannedPackageLPw(pkg);
11797 int N = pkg.providers.size();
11798 StringBuilder r = null;
11800 for (i=0; i<N; i++) {
11801 PackageParser.Provider p = pkg.providers.get(i);
11802 p.info.processName = fixProcessName(pkg.applicationInfo.processName,
11803 p.info.processName);
11804 mProviders.addProvider(p);
11805 p.syncable = p.info.isSyncable;
11806 if (p.info.authority != null) {
11807 String names[] = p.info.authority.split(";");
11808 p.info.authority = null;
11809 for (int j = 0; j < names.length; j++) {
11810 if (j == 1 && p.syncable) {
11811 // We only want the first authority for a provider to possibly be
11812 // syncable, so if we already added this provider using a different
11813 // authority clear the syncable flag. We copy the provider before
11814 // changing it because the mProviders object contains a reference
11815 // to a provider that we don't want to change.
11816 // Only do this for the second authority since the resulting provider
11817 // object can be the same for all future authorities for this provider.
11818 p = new PackageParser.Provider(p);
11819 p.syncable = false;
11821 if (!mProvidersByAuthority.containsKey(names[j])) {
11822 mProvidersByAuthority.put(names[j], p);
11823 if (p.info.authority == null) {
11824 p.info.authority = names[j];
11826 p.info.authority = p.info.authority + ";" + names[j];
11828 if (DEBUG_PACKAGE_SCANNING) {
11830 Log.d(TAG, "Registered content provider: " + names[j]
11831 + ", className = " + p.info.name + ", isSyncable = "
11832 + p.info.isSyncable);
11835 PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
11836 Slog.w(TAG, "Skipping provider name " + names[j] +
11837 " (in package " + pkg.applicationInfo.packageName +
11838 "): name already used by "
11839 + ((other != null && other.getComponentName() != null)
11840 ? other.getComponentName().getPackageName() : "?"));
11846 r = new StringBuilder(256);
11850 r.append(p.info.name);
11854 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r);
11857 N = pkg.services.size();
11859 for (i=0; i<N; i++) {
11860 PackageParser.Service s = pkg.services.get(i);
11861 s.info.processName = fixProcessName(pkg.applicationInfo.processName,
11862 s.info.processName);
11863 mServices.addService(s);
11866 r = new StringBuilder(256);
11870 r.append(s.info.name);
11874 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r);
11877 N = pkg.receivers.size();
11879 for (i=0; i<N; i++) {
11880 PackageParser.Activity a = pkg.receivers.get(i);
11881 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11882 a.info.processName);
11883 mReceivers.addActivity(a, "receiver");
11886 r = new StringBuilder(256);
11890 r.append(a.info.name);
11894 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r);
11897 N = pkg.activities.size();
11899 for (i=0; i<N; i++) {
11900 PackageParser.Activity a = pkg.activities.get(i);
11901 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11902 a.info.processName);
11903 mActivities.addActivity(a, "activity");
11906 r = new StringBuilder(256);
11910 r.append(a.info.name);
11914 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r);
11917 N = pkg.permissionGroups.size();
11919 for (i=0; i<N; i++) {
11920 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
11921 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
11922 final String curPackageName = cur == null ? null : cur.info.packageName;
11923 // Dont allow ephemeral apps to define new permission groups.
11924 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11925 Slog.w(TAG, "Permission group " + pg.info.name + " from package "
11926 + pg.info.packageName
11927 + " ignored: instant apps cannot define new permission groups.");
11930 final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
11931 if (cur == null || isPackageUpdate) {
11932 mPermissionGroups.put(pg.info.name, pg);
11935 r = new StringBuilder(256);
11939 if (isPackageUpdate) {
11942 r.append(pg.info.name);
11945 Slog.w(TAG, "Permission group " + pg.info.name + " from package "
11946 + pg.info.packageName + " ignored: original from "
11947 + cur.info.packageName);
11950 r = new StringBuilder(256);
11955 r.append(pg.info.name);
11960 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r);
11963 N = pkg.permissions.size();
11965 for (i=0; i<N; i++) {
11966 PackageParser.Permission p = pkg.permissions.get(i);
11968 // Dont allow ephemeral apps to define new permissions.
11969 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11970 Slog.w(TAG, "Permission " + p.info.name + " from package "
11971 + p.info.packageName
11972 + " ignored: instant apps cannot define new permissions.");
11976 // Assume by default that we did not install this permission into the system.
11977 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
11979 // Now that permission groups have a special meaning, we ignore permission
11980 // groups for legacy apps to prevent unexpected behavior. In particular,
11981 // permissions for one app being granted to someone just because they happen
11982 // to be in a group defined by another app (before this had no implications).
11983 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
11984 p.group = mPermissionGroups.get(p.info.group);
11985 // Warn for a permission in an unknown group.
11986 if (DEBUG_PERMISSIONS && p.info.group != null && p.group == null) {
11987 Slog.i(TAG, "Permission " + p.info.name + " from package "
11988 + p.info.packageName + " in an unknown group " + p.info.group);
11992 ArrayMap<String, BasePermission> permissionMap =
11993 p.tree ? mSettings.mPermissionTrees
11994 : mSettings.mPermissions;
11995 BasePermission bp = permissionMap.get(p.info.name);
11997 // Allow system apps to redefine non-system permissions
11998 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
11999 final boolean currentOwnerIsSystem = (bp.perm != null
12000 && isSystemApp(bp.perm.owner));
12001 if (isSystemApp(p.owner)) {
12002 if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
12003 // It's a built-in permission and no owner, take ownership now
12004 bp.packageSetting = pkgSetting;
12006 bp.uid = pkg.applicationInfo.uid;
12007 bp.sourcePackage = p.info.packageName;
12008 p.info.flags |= PermissionInfo.FLAG_INSTALLED;
12009 } else if (!currentOwnerIsSystem) {
12010 String msg = "New decl " + p.owner + " of permission "
12011 + p.info.name + " is system; overriding " + bp.sourcePackage;
12012 reportSettingsProblem(Log.WARN, msg);
12019 bp = new BasePermission(p.info.name, p.info.packageName,
12020 BasePermission.TYPE_NORMAL);
12021 permissionMap.put(p.info.name, bp);
12024 if (bp.perm == null) {
12025 if (bp.sourcePackage == null
12026 || bp.sourcePackage.equals(p.info.packageName)) {
12027 BasePermission tree = findPermissionTreeLP(p.info.name);
12029 || tree.sourcePackage.equals(p.info.packageName)) {
12030 bp.packageSetting = pkgSetting;
12032 bp.uid = pkg.applicationInfo.uid;
12033 bp.sourcePackage = p.info.packageName;
12034 p.info.flags |= PermissionInfo.FLAG_INSTALLED;
12037 r = new StringBuilder(256);
12041 r.append(p.info.name);
12044 Slog.w(TAG, "Permission " + p.info.name + " from package "
12045 + p.info.packageName + " ignored: base tree "
12046 + tree.name + " is from package "
12047 + tree.sourcePackage);
12050 Slog.w(TAG, "Permission " + p.info.name + " from package "
12051 + p.info.packageName + " ignored: original from "
12052 + bp.sourcePackage);
12054 } else if (chatty) {
12056 r = new StringBuilder(256);
12061 r.append(p.info.name);
12063 if (bp.perm == p) {
12064 bp.protectionLevel = p.info.protectionLevel;
12069 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r);
12072 N = pkg.instrumentation.size();
12074 for (i=0; i<N; i++) {
12075 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
12076 a.info.packageName = pkg.applicationInfo.packageName;
12077 a.info.sourceDir = pkg.applicationInfo.sourceDir;
12078 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
12079 a.info.splitNames = pkg.splitNames;
12080 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
12081 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
12082 a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
12083 a.info.dataDir = pkg.applicationInfo.dataDir;
12084 a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
12085 a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
12086 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
12087 a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
12088 mInstrumentation.put(a.getComponentName(), a);
12091 r = new StringBuilder(256);
12095 r.append(a.info.name);
12099 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r);
12102 if (pkg.protectedBroadcasts != null) {
12103 N = pkg.protectedBroadcasts.size();
12104 synchronized (mProtectedBroadcasts) {
12105 for (i = 0; i < N; i++) {
12106 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
12112 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12116 * Derive the ABI of a non-system package located at {@code scanFile}. This information
12117 * is derived purely on the basis of the contents of {@code scanFile} and
12118 * {@code cpuAbiOverride}.
12120 * If {@code extractLibs} is true, native libraries are extracted from the app if required.
12122 private static void derivePackageAbi(PackageParser.Package pkg, File scanFile,
12123 String cpuAbiOverride, boolean extractLibs,
12124 File appLib32InstallDir)
12125 throws PackageManagerException {
12126 // Give ourselves some initial paths; we'll come back for another
12127 // pass once we've determined ABI below.
12128 setNativeLibraryPaths(pkg, appLib32InstallDir);
12130 // We would never need to extract libs for forward-locked and external packages,
12131 // since the container service will do it for us. We shouldn't attempt to
12132 // extract libs from system app when it was not updated.
12133 if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
12134 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
12135 extractLibs = false;
12138 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
12139 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
12141 NativeLibraryHelper.Handle handle = null;
12143 handle = NativeLibraryHelper.Handle.create(pkg);
12144 // TODO(multiArch): This can be null for apps that didn't go through the
12145 // usual installation process. We can calculate it again, like we
12146 // do during install time.
12148 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
12150 final File nativeLibraryRoot = new File(nativeLibraryRootStr);
12152 // Null out the abis so that they can be recalculated.
12153 pkg.applicationInfo.primaryCpuAbi = null;
12154 pkg.applicationInfo.secondaryCpuAbi = null;
12155 if (isMultiArch(pkg.applicationInfo)) {
12156 // Warn if we've set an abiOverride for multi-lib packages..
12157 // By definition, we need to copy both 32 and 64 bit libraries for
12159 if (pkg.cpuAbiOverride != null
12160 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
12161 Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
12164 int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
12165 int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
12166 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
12168 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
12169 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
12170 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
12171 useIsaSpecificSubdirs);
12173 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
12174 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
12176 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12179 // Shared library native code should be in the APK zip aligned
12180 if (abi32 >= 0 && pkg.isLibrary() && extractLibs) {
12181 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
12182 "Shared library native lib extraction not supported");
12185 maybeThrowExceptionForMultiArchCopy(
12186 "Error unpackaging 32 bit native libs for multiarch app.", abi32);
12188 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
12190 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
12191 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
12192 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
12193 useIsaSpecificSubdirs);
12195 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
12196 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
12198 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12201 maybeThrowExceptionForMultiArchCopy(
12202 "Error unpackaging 64 bit native libs for multiarch app.", abi64);
12205 // Shared library native libs should be in the APK zip aligned
12206 if (extractLibs && pkg.isLibrary()) {
12207 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
12208 "Shared library native lib extraction not supported");
12210 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
12214 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
12216 if (pkg.use32bitAbi) {
12217 pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
12218 pkg.applicationInfo.primaryCpuAbi = abi;
12220 pkg.applicationInfo.secondaryCpuAbi = abi;
12223 pkg.applicationInfo.primaryCpuAbi = abi;
12227 String[] abiList = (cpuAbiOverride != null) ?
12228 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
12230 // Enable gross and lame hacks for apps that are built with old
12231 // SDK tools. We must scan their APKs for renderscript bitcode and
12232 // not launch them if it's present. Don't bother checking on devices
12233 // that don't have 64 bit support.
12234 boolean needsRenderScriptOverride = false;
12235 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
12236 NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
12237 abiList = Build.SUPPORTED_32_BIT_ABIS;
12238 needsRenderScriptOverride = true;
12243 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
12244 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
12245 nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
12247 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
12248 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
12250 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12252 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
12253 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
12254 "Error unpackaging native libs for app, errorCode=" + copyRet);
12257 if (copyRet >= 0) {
12258 // Shared libraries that have native libs must be multi-architecture
12259 if (pkg.isLibrary()) {
12260 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
12261 "Shared library with native libs must be multiarch");
12263 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
12264 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
12265 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
12266 } else if (needsRenderScriptOverride) {
12267 pkg.applicationInfo.primaryCpuAbi = abiList[0];
12270 } catch (IOException ioe) {
12271 Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
12273 IoUtils.closeQuietly(handle);
12276 // Now that we've calculated the ABIs and determined if it's an internal app,
12277 // we will go ahead and populate the nativeLibraryPath.
12278 setNativeLibraryPaths(pkg, appLib32InstallDir);
12282 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
12283 * i.e, so that all packages can be run inside a single process if required.
12285 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
12286 * this function will either try and make the ABI for all packages in {@code packagesForUser}
12287 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
12288 * the ABI selected for {@code packagesForUser}. This variant is used when installing or
12289 * updating a package that belongs to a shared user.
12291 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
12292 * adds unnecessary complexity.
12294 private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
12295 PackageParser.Package scannedPackage) {
12296 String requiredInstructionSet = null;
12297 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
12298 requiredInstructionSet = VMRuntime.getInstructionSet(
12299 scannedPackage.applicationInfo.primaryCpuAbi);
12302 PackageSetting requirer = null;
12303 for (PackageSetting ps : packagesForUser) {
12304 // If packagesForUser contains scannedPackage, we skip it. This will happen
12305 // when scannedPackage is an update of an existing package. Without this check,
12306 // we will never be able to change the ABI of any package belonging to a shared
12307 // user, even if it's compatible with other packages.
12308 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
12309 if (ps.primaryCpuAbiString == null) {
12313 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
12314 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
12315 // We have a mismatch between instruction sets (say arm vs arm64) warn about
12316 // this but there's not much we can do.
12317 String errorMessage = "Instruction set mismatch, "
12318 + ((requirer == null) ? "[caller]" : requirer)
12319 + " requires " + requiredInstructionSet + " whereas " + ps
12320 + " requires " + instructionSet;
12321 Slog.w(TAG, errorMessage);
12324 if (requiredInstructionSet == null) {
12325 requiredInstructionSet = instructionSet;
12331 if (requiredInstructionSet != null) {
12332 String adjustedAbi;
12333 if (requirer != null) {
12334 // requirer != null implies that either scannedPackage was null or that scannedPackage
12335 // did not require an ABI, in which case we have to adjust scannedPackage to match
12336 // the ABI of the set (which is the same as requirer's ABI)
12337 adjustedAbi = requirer.primaryCpuAbiString;
12338 if (scannedPackage != null) {
12339 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
12342 // requirer == null implies that we're updating all ABIs in the set to
12343 // match scannedPackage.
12344 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi;
12347 for (PackageSetting ps : packagesForUser) {
12348 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
12349 if (ps.primaryCpuAbiString != null) {
12353 ps.primaryCpuAbiString = adjustedAbi;
12354 if (ps.pkg != null && ps.pkg.applicationInfo != null &&
12355 !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
12356 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
12357 if (DEBUG_ABI_SELECTION) {
12358 Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
12360 + (requirer != null ? requirer.pkg : "null")
12361 + ", scannedPackage="
12362 + (scannedPackage != null ? scannedPackage : "null")
12366 mInstaller.rmdex(ps.codePathString,
12367 getDexCodeInstructionSet(getPreferredInstructionSet()));
12368 } catch (InstallerException ignored) {
12376 private void setUpCustomResolverActivity(PackageParser.Package pkg) {
12377 synchronized (mPackages) {
12378 mResolverReplaced = true;
12379 // Set up information for custom user intent resolution activity.
12380 mResolveActivity.applicationInfo = pkg.applicationInfo;
12381 mResolveActivity.name = mCustomResolverComponentName.getClassName();
12382 mResolveActivity.packageName = pkg.applicationInfo.packageName;
12383 mResolveActivity.processName = pkg.applicationInfo.packageName;
12384 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
12385 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
12386 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
12387 mResolveActivity.theme = 0;
12388 mResolveActivity.exported = true;
12389 mResolveActivity.enabled = true;
12390 mResolveInfo.activityInfo = mResolveActivity;
12391 mResolveInfo.priority = 0;
12392 mResolveInfo.preferredOrder = 0;
12393 mResolveInfo.match = 0;
12394 mResolveComponentName = mCustomResolverComponentName;
12395 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
12396 mResolveComponentName);
12400 private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
12401 if (installerActivity == null) {
12402 if (DEBUG_EPHEMERAL) {
12403 Slog.d(TAG, "Clear ephemeral installer activity");
12405 mInstantAppInstallerActivity = null;
12409 if (DEBUG_EPHEMERAL) {
12410 Slog.d(TAG, "Set ephemeral installer activity: "
12411 + installerActivity.getComponentName());
12413 // Set up information for ephemeral installer activity
12414 mInstantAppInstallerActivity = installerActivity;
12415 mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
12416 | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
12417 mInstantAppInstallerActivity.exported = true;
12418 mInstantAppInstallerActivity.enabled = true;
12419 mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
12420 mInstantAppInstallerInfo.priority = 0;
12421 mInstantAppInstallerInfo.preferredOrder = 1;
12422 mInstantAppInstallerInfo.isDefault = true;
12423 mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
12424 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
12427 private static String calculateBundledApkRoot(final String codePathString) {
12428 final File codePath = new File(codePathString);
12429 final File codeRoot;
12430 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
12431 codeRoot = Environment.getRootDirectory();
12432 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
12433 codeRoot = Environment.getOemDirectory();
12434 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
12435 codeRoot = Environment.getVendorDirectory();
12437 // Unrecognized code path; take its top real segment as the apk root:
12438 // e.g. /something/app/blah.apk => /something
12440 File f = codePath.getCanonicalFile();
12441 File parent = f.getParentFile(); // non-null because codePath is a file
12443 while ((tmp = parent.getParentFile()) != null) {
12448 Slog.w(TAG, "Unrecognized code path "
12449 + codePath + " - using " + codeRoot);
12450 } catch (IOException e) {
12451 // Can't canonicalize the code path -- shenanigans?
12452 Slog.w(TAG, "Can't canonicalize code path " + codePath);
12453 return Environment.getRootDirectory().getPath();
12456 return codeRoot.getPath();
12460 * Derive and set the location of native libraries for the given package,
12461 * which varies depending on where and how the package was installed.
12463 private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
12464 final ApplicationInfo info = pkg.applicationInfo;
12465 final String codePath = pkg.codePath;
12466 final File codeFile = new File(codePath);
12467 final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
12468 final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
12470 info.nativeLibraryRootDir = null;
12471 info.nativeLibraryRootRequiresIsa = false;
12472 info.nativeLibraryDir = null;
12473 info.secondaryNativeLibraryDir = null;
12475 if (isApkFile(codeFile)) {
12476 // Monolithic install
12478 // If "/system/lib64/apkname" exists, assume that is the per-package
12479 // native library directory to use; otherwise use "/system/lib/apkname".
12480 final String apkRoot = calculateBundledApkRoot(info.sourceDir);
12481 final boolean is64Bit = VMRuntime.is64BitInstructionSet(
12482 getPrimaryInstructionSet(info));
12484 // This is a bundled system app so choose the path based on the ABI.
12485 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
12486 // is just the default path.
12487 final String apkName = deriveCodePathName(codePath);
12488 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
12489 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
12490 apkName).getAbsolutePath();
12492 if (info.secondaryCpuAbi != null) {
12493 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
12494 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
12495 secondaryLibDir, apkName).getAbsolutePath();
12497 } else if (asecApp) {
12498 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
12499 .getAbsolutePath();
12501 final String apkName = deriveCodePathName(codePath);
12502 info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
12503 .getAbsolutePath();
12506 info.nativeLibraryRootRequiresIsa = false;
12507 info.nativeLibraryDir = info.nativeLibraryRootDir;
12510 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
12511 info.nativeLibraryRootRequiresIsa = true;
12513 info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
12514 getPrimaryInstructionSet(info)).getAbsolutePath();
12516 if (info.secondaryCpuAbi != null) {
12517 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
12518 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
12524 * Calculate the abis and roots for a bundled app. These can uniquely
12525 * be determined from the contents of the system partition, i.e whether
12526 * it contains 64 or 32 bit shared libraries etc. We do not validate any
12527 * of this information, and instead assume that the system was built
12530 private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
12531 PackageSetting pkgSetting) {
12532 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
12534 // If "/system/lib64/apkname" exists, assume that is the per-package
12535 // native library directory to use; otherwise use "/system/lib/apkname".
12536 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
12537 setBundledAppAbi(pkg, apkRoot, apkName);
12538 // pkgSetting might be null during rescan following uninstall of updates
12539 // to a bundled app, so accommodate that possibility. The settings in
12540 // that case will be established later from the parsed package.
12542 // If the settings aren't null, sync them up with what we've just derived.
12543 // note that apkRoot isn't stored in the package settings.
12544 if (pkgSetting != null) {
12545 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
12546 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
12551 * Deduces the ABI of a bundled app and sets the relevant fields on the
12552 * parsed pkg object.
12554 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
12555 * under which system libraries are installed.
12556 * @param apkName the name of the installed package.
12558 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
12559 final File codeFile = new File(pkg.codePath);
12561 final boolean has64BitLibs;
12562 final boolean has32BitLibs;
12563 if (isApkFile(codeFile)) {
12564 // Monolithic install
12565 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
12566 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
12569 final File rootDir = new File(codeFile, LIB_DIR_NAME);
12570 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
12571 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
12572 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
12573 has64BitLibs = (new File(rootDir, isa)).exists();
12575 has64BitLibs = false;
12577 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
12578 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
12579 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
12580 has32BitLibs = (new File(rootDir, isa)).exists();
12582 has32BitLibs = false;
12586 if (has64BitLibs && !has32BitLibs) {
12587 // The package has 64 bit libs, but not 32 bit libs. Its primary
12588 // ABI should be 64 bit. We can safely assume here that the bundled
12589 // native libraries correspond to the most preferred ABI in the list.
12591 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12592 pkg.applicationInfo.secondaryCpuAbi = null;
12593 } else if (has32BitLibs && !has64BitLibs) {
12594 // The package has 32 bit libs but not 64 bit libs. Its primary
12595 // ABI should be 32 bit.
12597 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12598 pkg.applicationInfo.secondaryCpuAbi = null;
12599 } else if (has32BitLibs && has64BitLibs) {
12600 // The application has both 64 and 32 bit bundled libraries. We check
12601 // here that the app declares multiArch support, and warn if it doesn't.
12603 // We will be lenient here and record both ABIs. The primary will be the
12604 // ABI that's higher on the list, i.e, a device that's configured to prefer
12605 // 64 bit apps will see a 64 bit primary ABI,
12607 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
12608 Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
12611 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
12612 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12613 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12615 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12616 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12619 pkg.applicationInfo.primaryCpuAbi = null;
12620 pkg.applicationInfo.secondaryCpuAbi = null;
12624 private void killApplication(String pkgName, int appId, String reason) {
12625 killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
12628 private void killApplication(String pkgName, int appId, int userId, String reason) {
12629 // Request the ActivityManager to kill the process(only for existing packages)
12630 // so that we do not end up in a confused state while the user is still using the older
12631 // version of the application while the new one gets installed.
12632 final long token = Binder.clearCallingIdentity();
12634 IActivityManager am = ActivityManager.getService();
12637 am.killApplication(pkgName, appId, userId, reason);
12638 } catch (RemoteException e) {
12642 Binder.restoreCallingIdentity(token);
12646 private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
12647 // Remove the parent package setting
12648 PackageSetting ps = (PackageSetting) pkg.mExtras;
12650 removePackageLI(ps, chatty);
12652 // Remove the child package setting
12653 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12654 for (int i = 0; i < childCount; i++) {
12655 PackageParser.Package childPkg = pkg.childPackages.get(i);
12656 ps = (PackageSetting) childPkg.mExtras;
12658 removePackageLI(ps, chatty);
12663 void removePackageLI(PackageSetting ps, boolean chatty) {
12664 if (DEBUG_INSTALL) {
12666 Log.d(TAG, "Removing package " + ps.name);
12670 synchronized (mPackages) {
12671 mPackages.remove(ps.name);
12672 final PackageParser.Package pkg = ps.pkg;
12674 cleanPackageDataStructuresLILPw(pkg, chatty);
12679 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
12680 if (DEBUG_INSTALL) {
12682 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
12686 synchronized (mPackages) {
12687 // Remove the parent package
12688 mPackages.remove(pkg.applicationInfo.packageName);
12689 cleanPackageDataStructuresLILPw(pkg, chatty);
12691 // Remove the child packages
12692 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12693 for (int i = 0; i < childCount; i++) {
12694 PackageParser.Package childPkg = pkg.childPackages.get(i);
12695 mPackages.remove(childPkg.applicationInfo.packageName);
12696 cleanPackageDataStructuresLILPw(childPkg, chatty);
12701 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
12702 int N = pkg.providers.size();
12703 StringBuilder r = null;
12705 for (i=0; i<N; i++) {
12706 PackageParser.Provider p = pkg.providers.get(i);
12707 mProviders.removeProvider(p);
12708 if (p.info.authority == null) {
12710 /* There was another ContentProvider with this authority when
12711 * this app was installed so this authority is null,
12712 * Ignore it as we don't have to unregister the provider.
12716 String names[] = p.info.authority.split(";");
12717 for (int j = 0; j < names.length; j++) {
12718 if (mProvidersByAuthority.get(names[j]) == p) {
12719 mProvidersByAuthority.remove(names[j]);
12720 if (DEBUG_REMOVE) {
12722 Log.d(TAG, "Unregistered content provider: " + names[j]
12723 + ", className = " + p.info.name + ", isSyncable = "
12724 + p.info.isSyncable);
12728 if (DEBUG_REMOVE && chatty) {
12730 r = new StringBuilder(256);
12734 r.append(p.info.name);
12738 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r);
12741 N = pkg.services.size();
12743 for (i=0; i<N; i++) {
12744 PackageParser.Service s = pkg.services.get(i);
12745 mServices.removeService(s);
12748 r = new StringBuilder(256);
12752 r.append(s.info.name);
12756 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r);
12759 N = pkg.receivers.size();
12761 for (i=0; i<N; i++) {
12762 PackageParser.Activity a = pkg.receivers.get(i);
12763 mReceivers.removeActivity(a, "receiver");
12764 if (DEBUG_REMOVE && chatty) {
12766 r = new StringBuilder(256);
12770 r.append(a.info.name);
12774 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r);
12777 N = pkg.activities.size();
12779 for (i=0; i<N; i++) {
12780 PackageParser.Activity a = pkg.activities.get(i);
12781 mActivities.removeActivity(a, "activity");
12782 if (DEBUG_REMOVE && chatty) {
12784 r = new StringBuilder(256);
12788 r.append(a.info.name);
12792 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r);
12795 N = pkg.permissions.size();
12797 for (i=0; i<N; i++) {
12798 PackageParser.Permission p = pkg.permissions.get(i);
12799 BasePermission bp = mSettings.mPermissions.get(p.info.name);
12801 bp = mSettings.mPermissionTrees.get(p.info.name);
12803 if (bp != null && bp.perm == p) {
12805 if (DEBUG_REMOVE && chatty) {
12807 r = new StringBuilder(256);
12811 r.append(p.info.name);
12814 if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
12815 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name);
12816 if (appOpPkgs != null) {
12817 appOpPkgs.remove(pkg.packageName);
12822 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
12825 N = pkg.requestedPermissions.size();
12827 for (i=0; i<N; i++) {
12828 String perm = pkg.requestedPermissions.get(i);
12829 BasePermission bp = mSettings.mPermissions.get(perm);
12830 if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
12831 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm);
12832 if (appOpPkgs != null) {
12833 appOpPkgs.remove(pkg.packageName);
12834 if (appOpPkgs.isEmpty()) {
12835 mAppOpPermissionPackages.remove(perm);
12841 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
12844 N = pkg.instrumentation.size();
12846 for (i=0; i<N; i++) {
12847 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
12848 mInstrumentation.remove(a.getComponentName());
12849 if (DEBUG_REMOVE && chatty) {
12851 r = new StringBuilder(256);
12855 r.append(a.info.name);
12859 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r);
12863 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12864 // Only system apps can hold shared libraries.
12865 if (pkg.libraryNames != null) {
12866 for (i = 0; i < pkg.libraryNames.size(); i++) {
12867 String name = pkg.libraryNames.get(i);
12868 if (removeSharedLibraryLPw(name, 0)) {
12869 if (DEBUG_REMOVE && chatty) {
12871 r = new StringBuilder(256);
12884 // Any package can hold static shared libraries.
12885 if (pkg.staticSharedLibName != null) {
12886 if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
12887 if (DEBUG_REMOVE && chatty) {
12889 r = new StringBuilder(256);
12893 r.append(pkg.staticSharedLibName);
12899 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r);
12903 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
12904 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
12905 if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
12912 static final int UPDATE_PERMISSIONS_ALL = 1<<0;
12913 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
12914 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
12916 private void updatePermissionsLPw(PackageParser.Package pkg, int flags) {
12917 // Update the parent permissions
12918 updatePermissionsLPw(pkg.packageName, pkg, flags);
12919 // Update the child permissions
12920 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12921 for (int i = 0; i < childCount; i++) {
12922 PackageParser.Package childPkg = pkg.childPackages.get(i);
12923 updatePermissionsLPw(childPkg.packageName, childPkg, flags);
12927 private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
12929 final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
12930 updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
12933 private void updatePermissionsLPw(String changingPkg,
12934 PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
12935 // Make sure there are no dangling permission trees.
12936 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
12937 while (it.hasNext()) {
12938 final BasePermission bp = it.next();
12939 if (bp.packageSetting == null) {
12940 // We may not yet have parsed the package, so just see if
12941 // we still know about its settings.
12942 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
12944 if (bp.packageSetting == null) {
12945 Slog.w(TAG, "Removing dangling permission tree: " + bp.name
12946 + " from package " + bp.sourcePackage);
12948 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
12949 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
12950 Slog.i(TAG, "Removing old permission tree: " + bp.name
12951 + " from package " + bp.sourcePackage);
12952 flags |= UPDATE_PERMISSIONS_ALL;
12958 // Make sure all dynamic permissions have been assigned to a package,
12959 // and make sure there are no dangling permissions.
12960 it = mSettings.mPermissions.values().iterator();
12961 while (it.hasNext()) {
12962 final BasePermission bp = it.next();
12963 if (bp.type == BasePermission.TYPE_DYNAMIC) {
12964 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
12965 + bp.name + " pkg=" + bp.sourcePackage
12966 + " info=" + bp.pendingInfo);
12967 if (bp.packageSetting == null && bp.pendingInfo != null) {
12968 final BasePermission tree = findPermissionTreeLP(bp.name);
12969 if (tree != null && tree.perm != null) {
12970 bp.packageSetting = tree.packageSetting;
12971 bp.perm = new PackageParser.Permission(tree.perm.owner,
12972 new PermissionInfo(bp.pendingInfo));
12973 bp.perm.info.packageName = tree.perm.info.packageName;
12974 bp.perm.info.name = bp.name;
12979 if (bp.packageSetting == null) {
12980 // We may not yet have parsed the package, so just see if
12981 // we still know about its settings.
12982 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
12984 if (bp.packageSetting == null) {
12985 Slog.w(TAG, "Removing dangling permission: " + bp.name
12986 + " from package " + bp.sourcePackage);
12988 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
12989 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
12990 Slog.i(TAG, "Removing old permission: " + bp.name
12991 + " from package " + bp.sourcePackage);
12992 flags |= UPDATE_PERMISSIONS_ALL;
12998 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
12999 // Now update the permissions for all packages, in particular
13000 // replace the granted permissions of the system packages.
13001 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
13002 for (PackageParser.Package pkg : mPackages.values()) {
13003 if (pkg != pkgInfo) {
13004 // Only replace for packages on requested volume
13005 final String volumeUuid = getVolumeUuidForPackage(pkg);
13006 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
13007 && Objects.equals(replaceVolumeUuid, volumeUuid);
13008 grantPermissionsLPw(pkg, replace, changingPkg);
13013 if (pkgInfo != null) {
13014 // Only replace for packages on requested volume
13015 final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
13016 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
13017 && Objects.equals(replaceVolumeUuid, volumeUuid);
13018 grantPermissionsLPw(pkgInfo, replace, changingPkg);
13020 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
13023 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
13024 String packageOfInterest) {
13025 // IMPORTANT: There are two types of permissions: install and runtime.
13026 // Install time permissions are granted when the app is installed to
13027 // all device users and users added in the future. Runtime permissions
13028 // are granted at runtime explicitly to specific users. Normal and signature
13029 // protected permissions are install time permissions. Dangerous permissions
13030 // are install permissions if the app's target SDK is Lollipop MR1 or older,
13031 // otherwise they are runtime permissions. This function does not manage
13032 // runtime permissions except for the case an app targeting Lollipop MR1
13033 // being upgraded to target a newer SDK, in which case dangerous permissions
13034 // are transformed from install time to runtime ones.
13036 final PackageSetting ps = (PackageSetting) pkg.mExtras;
13041 PermissionsState permissionsState = ps.getPermissionsState();
13042 PermissionsState origPermissions = permissionsState;
13044 final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
13046 boolean runtimePermissionsRevoked = false;
13047 int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
13049 boolean changedInstallPermission = false;
13052 ps.installPermissionsFixed = false;
13053 if (!ps.isSharedUser()) {
13054 origPermissions = new PermissionsState(permissionsState);
13055 permissionsState.reset();
13057 // We need to know only about runtime permission changes since the
13058 // calling code always writes the install permissions state but
13059 // the runtime ones are written only if changed. The only cases of
13060 // changed runtime permissions here are promotion of an install to
13061 // runtime and revocation of a runtime from a shared user.
13062 changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
13063 ps.sharedUser, UserManagerService.getInstance().getUserIds());
13064 if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
13065 runtimePermissionsRevoked = true;
13070 permissionsState.setGlobalGids(mGlobalGids);
13072 final int N = pkg.requestedPermissions.size();
13073 for (int i=0; i<N; i++) {
13074 final String name = pkg.requestedPermissions.get(i);
13075 final BasePermission bp = mSettings.mPermissions.get(name);
13076 final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
13077 >= Build.VERSION_CODES.M;
13079 if (DEBUG_INSTALL) {
13080 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
13083 if (bp == null || bp.packageSetting == null) {
13084 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
13085 if (DEBUG_PERMISSIONS) {
13086 Slog.i(TAG, "Unknown permission " + name
13087 + " in package " + pkg.packageName);
13094 // Limit ephemeral apps to ephemeral allowed permissions.
13095 if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
13096 if (DEBUG_PERMISSIONS) {
13097 Log.i(TAG, "Denying non-ephemeral permission " + bp.name + " for package "
13098 + pkg.packageName);
13103 if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
13104 if (DEBUG_PERMISSIONS) {
13105 Log.i(TAG, "Denying runtime-only permission " + bp.name + " for package "
13106 + pkg.packageName);
13111 final String perm = bp.name;
13112 boolean allowedSig = false;
13113 int grant = GRANT_DENIED;
13115 // Keep track of app op permissions.
13116 if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
13117 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
13118 if (pkgs == null) {
13119 pkgs = new ArraySet<>();
13120 mAppOpPermissionPackages.put(bp.name, pkgs);
13122 pkgs.add(pkg.packageName);
13125 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
13127 case PermissionInfo.PROTECTION_NORMAL: {
13128 // For all apps normal permissions are install time ones.
13129 grant = GRANT_INSTALL;
13132 case PermissionInfo.PROTECTION_DANGEROUS: {
13133 // If a permission review is required for legacy apps we represent
13134 // their permissions as always granted runtime ones since we need
13135 // to keep the review required permission flag per user while an
13136 // install permission's state is shared across all users.
13137 if (!appSupportsRuntimePermissions && !mPermissionReviewRequired) {
13138 // For legacy apps dangerous permissions are install time ones.
13139 grant = GRANT_INSTALL;
13140 } else if (origPermissions.hasInstallPermission(bp.name)) {
13141 // For legacy apps that became modern, install becomes runtime.
13142 grant = GRANT_UPGRADE;
13143 } else if (mPromoteSystemApps
13145 && mExistingSystemPackages.contains(ps.name)) {
13146 // For legacy system apps, install becomes runtime.
13147 // We cannot check hasInstallPermission() for system apps since those
13148 // permissions were granted implicitly and not persisted pre-M.
13149 grant = GRANT_UPGRADE;
13151 // For modern apps keep runtime permissions unchanged.
13152 grant = GRANT_RUNTIME;
13156 case PermissionInfo.PROTECTION_SIGNATURE: {
13157 // For all apps signature permissions are install time ones.
13158 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
13160 grant = GRANT_INSTALL;
13165 if (DEBUG_PERMISSIONS) {
13166 Slog.i(TAG, "Granting permission " + perm + " to package " + pkg.packageName);
13169 if (grant != GRANT_DENIED) {
13170 if (!isSystemApp(ps) && ps.installPermissionsFixed) {
13171 // If this is an existing, non-system package, then
13172 // we can't add any new permissions to it.
13173 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
13174 // Except... if this is a permission that was added
13175 // to the platform (note: need to only do this when
13176 // updating the platform).
13177 if (!isNewPlatformPermissionForPackage(perm, pkg)) {
13178 grant = GRANT_DENIED;
13184 case GRANT_INSTALL: {
13185 // Revoke this as runtime permission to handle the case of
13186 // a runtime permission being downgraded to an install one.
13187 // Also in permission review mode we keep dangerous permissions
13189 for (int userId : UserManagerService.getInstance().getUserIds()) {
13190 if (origPermissions.getRuntimePermissionState(
13191 bp.name, userId) != null) {
13192 // Revoke the runtime permission and clear the flags.
13193 origPermissions.revokeRuntimePermission(bp, userId);
13194 origPermissions.updatePermissionFlags(bp, userId,
13195 PackageManager.MASK_PERMISSION_FLAGS, 0);
13196 // If we revoked a permission permission, we have to write.
13197 changedRuntimePermissionUserIds = ArrayUtils.appendInt(
13198 changedRuntimePermissionUserIds, userId);
13201 // Grant an install permission.
13202 if (permissionsState.grantInstallPermission(bp) !=
13203 PermissionsState.PERMISSION_OPERATION_FAILURE) {
13204 changedInstallPermission = true;
13208 case GRANT_RUNTIME: {
13209 // Grant previously granted runtime permissions.
13210 for (int userId : UserManagerService.getInstance().getUserIds()) {
13211 PermissionState permissionState = origPermissions
13212 .getRuntimePermissionState(bp.name, userId);
13213 int flags = permissionState != null
13214 ? permissionState.getFlags() : 0;
13215 if (origPermissions.hasRuntimePermission(bp.name, userId)) {
13216 // Don't propagate the permission in a permission review mode if
13217 // the former was revoked, i.e. marked to not propagate on upgrade.
13218 // Note that in a permission review mode install permissions are
13219 // represented as constantly granted runtime ones since we need to
13220 // keep a per user state associated with the permission. Also the
13221 // revoke on upgrade flag is no longer applicable and is reset.
13222 final boolean revokeOnUpgrade = (flags & PackageManager
13223 .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
13224 if (revokeOnUpgrade) {
13225 flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
13226 // Since we changed the flags, we have to write.
13227 changedRuntimePermissionUserIds = ArrayUtils.appendInt(
13228 changedRuntimePermissionUserIds, userId);
13230 if (!mPermissionReviewRequired || !revokeOnUpgrade) {
13231 if (permissionsState.grantRuntimePermission(bp, userId) ==
13232 PermissionsState.PERMISSION_OPERATION_FAILURE) {
13233 // If we cannot put the permission as it was,
13234 // we have to write.
13235 changedRuntimePermissionUserIds = ArrayUtils.appendInt(
13236 changedRuntimePermissionUserIds, userId);
13240 // If the app supports runtime permissions no need for a review.
13241 if (mPermissionReviewRequired
13242 && appSupportsRuntimePermissions
13243 && (flags & PackageManager
13244 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
13245 flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
13246 // Since we changed the flags, we have to write.
13247 changedRuntimePermissionUserIds = ArrayUtils.appendInt(
13248 changedRuntimePermissionUserIds, userId);
13250 } else if (mPermissionReviewRequired
13251 && !appSupportsRuntimePermissions) {
13252 // For legacy apps that need a permission review, every new
13253 // runtime permission is granted but it is pending a review.
13254 // We also need to review only platform defined runtime
13255 // permissions as these are the only ones the platform knows
13256 // how to disable the API to simulate revocation as legacy
13257 // apps don't expect to run with revoked permissions.
13258 if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) {
13259 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
13260 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
13261 // We changed the flags, hence have to write.
13262 changedRuntimePermissionUserIds = ArrayUtils.appendInt(
13263 changedRuntimePermissionUserIds, userId);
13266 if (permissionsState.grantRuntimePermission(bp, userId)
13267 != PermissionsState.PERMISSION_OPERATION_FAILURE) {
13268 // We changed the permission, hence have to write.
13269 changedRuntimePermissionUserIds = ArrayUtils.appendInt(
13270 changedRuntimePermissionUserIds, userId);
13273 // Propagate the permission flags.
13274 permissionsState.updatePermissionFlags(bp, userId, flags, flags);
13278 case GRANT_UPGRADE: {
13279 // Grant runtime permissions for a previously held install permission.
13280 PermissionState permissionState = origPermissions
13281 .getInstallPermissionState(bp.name);
13282 final int flags = permissionState != null ? permissionState.getFlags() : 0;
13284 if (origPermissions.revokeInstallPermission(bp)
13285 != PermissionsState.PERMISSION_OPERATION_FAILURE) {
13286 // We will be transferring the permission flags, so clear them.
13287 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
13288 PackageManager.MASK_PERMISSION_FLAGS, 0);
13289 changedInstallPermission = true;
13292 // If the permission is not to be promoted to runtime we ignore it and
13293 // also its other flags as they are not applicable to install permissions.
13294 if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
13295 for (int userId : currentUserIds) {
13296 if (permissionsState.grantRuntimePermission(bp, userId) !=
13297 PermissionsState.PERMISSION_OPERATION_FAILURE) {
13298 // Transfer the permission flags.
13299 permissionsState.updatePermissionFlags(bp, userId,
13301 // If we granted the permission, we have to write.
13302 changedRuntimePermissionUserIds = ArrayUtils.appendInt(
13303 changedRuntimePermissionUserIds, userId);
13310 if (packageOfInterest == null
13311 || packageOfInterest.equals(pkg.packageName)) {
13312 if (DEBUG_PERMISSIONS) {
13313 Slog.i(TAG, "Not granting permission " + perm
13314 + " to package " + pkg.packageName
13315 + " because it was previously installed without");
13321 if (permissionsState.revokeInstallPermission(bp) !=
13322 PermissionsState.PERMISSION_OPERATION_FAILURE) {
13323 // Also drop the permission flags.
13324 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
13325 PackageManager.MASK_PERMISSION_FLAGS, 0);
13326 changedInstallPermission = true;
13327 Slog.i(TAG, "Un-granting permission " + perm
13328 + " from package " + pkg.packageName
13329 + " (protectionLevel=" + bp.protectionLevel
13330 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
13332 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
13333 // Don't print warning for app op permissions, since it is fine for them
13334 // not to be granted, there is a UI for the user to decide.
13335 if (DEBUG_PERMISSIONS
13336 && (packageOfInterest == null
13337 || packageOfInterest.equals(pkg.packageName))) {
13338 Slog.i(TAG, "Not granting permission " + perm
13339 + " to package " + pkg.packageName
13340 + " (protectionLevel=" + bp.protectionLevel
13341 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
13348 if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
13349 !isSystemApp(ps) || isUpdatedSystemApp(ps)){
13350 // This is the first that we have heard about this package, so the
13351 // permissions we have now selected are fixed until explicitly
13353 ps.installPermissionsFixed = true;
13356 // Persist the runtime permissions state for users with changes. If permissions
13357 // were revoked because no app in the shared user declares them we have to
13358 // write synchronously to avoid losing runtime permissions state.
13359 for (int userId : changedRuntimePermissionUserIds) {
13360 mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
13364 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
13365 boolean allowed = false;
13366 final int NP = PackageParser.NEW_PERMISSIONS.length;
13367 for (int ip=0; ip<NP; ip++) {
13368 final PackageParser.NewPermissionInfo npi
13369 = PackageParser.NEW_PERMISSIONS[ip];
13370 if (npi.name.equals(perm)
13371 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
13373 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
13374 + pkg.packageName);
13381 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
13382 BasePermission bp, PermissionsState origPermissions) {
13383 boolean privilegedPermission = (bp.protectionLevel
13384 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0;
13385 boolean privappPermissionsDisable =
13386 RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
13387 boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage);
13388 boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
13389 if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivilegedApp()
13390 && !platformPackage && platformPermission) {
13391 final ArraySet<String> allowedPermissions = SystemConfig.getInstance()
13392 .getPrivAppPermissions(pkg.packageName);
13393 final boolean whitelisted =
13394 allowedPermissions != null && allowedPermissions.contains(perm);
13395 if (!whitelisted) {
13396 Slog.w(TAG, "Privileged permission " + perm + " for package "
13397 + pkg.packageName + " - not in privapp-permissions whitelist");
13398 // Only report violations for apps on system image
13399 if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
13400 // it's only a reportable violation if the permission isn't explicitly denied
13401 final ArraySet<String> deniedPermissions = SystemConfig.getInstance()
13402 .getPrivAppDenyPermissions(pkg.packageName);
13403 final boolean permissionViolation =
13404 deniedPermissions == null || !deniedPermissions.contains(perm);
13405 if (permissionViolation) {
13406 if (mPrivappPermissionsViolations == null) {
13407 mPrivappPermissionsViolations = new ArraySet<>();
13409 mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
13414 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
13419 boolean allowed = (compareSignatures(
13420 bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
13421 == PackageManager.SIGNATURE_MATCH)
13422 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
13423 == PackageManager.SIGNATURE_MATCH);
13424 if (!allowed && privilegedPermission) {
13425 if (isSystemApp(pkg)) {
13426 // For updated system applications, a system permission
13427 // is granted only if it had been defined by the original application.
13428 if (pkg.isUpdatedSystemApp()) {
13429 final PackageSetting sysPs = mSettings
13430 .getDisabledSystemPkgLPr(pkg.packageName);
13431 if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) {
13432 // If the original was granted this permission, we take
13433 // that grant decision as read and propagate it to the
13435 if (sysPs.isPrivileged()) {
13439 // The system apk may have been updated with an older
13440 // version of the one on the data partition, but which
13441 // granted a new system permission that it didn't have
13442 // before. In this case we do want to allow the app to
13443 // now get the new permission if the ancestral apk is
13444 // privileged to get it.
13445 if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) {
13446 for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) {
13447 if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) {
13453 // Also if a privileged parent package on the system image or any of
13454 // its children requested a privileged permission, the updated child
13455 // packages can also get the permission.
13456 if (pkg.parentPackage != null) {
13457 final PackageSetting disabledSysParentPs = mSettings
13458 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
13459 if (disabledSysParentPs != null && disabledSysParentPs.pkg != null
13460 && disabledSysParentPs.isPrivileged()) {
13461 if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) {
13463 } else if (disabledSysParentPs.pkg.childPackages != null) {
13464 final int count = disabledSysParentPs.pkg.childPackages.size();
13465 for (int i = 0; i < count; i++) {
13466 PackageParser.Package disabledSysChildPkg =
13467 disabledSysParentPs.pkg.childPackages.get(i);
13468 if (isPackageRequestingPermission(disabledSysChildPkg,
13479 allowed = isPrivilegedApp(pkg);
13484 if (!allowed && (bp.protectionLevel
13485 & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
13486 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
13487 // If this was a previously normal/dangerous permission that got moved
13488 // to a system permission as part of the runtime permission redesign, then
13489 // we still want to blindly grant it to old apps.
13492 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
13493 && pkg.packageName.equals(mRequiredInstallerPackage)) {
13494 // If this permission is to be granted to the system installer and
13495 // this app is an installer, then it gets the permission.
13498 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
13499 && pkg.packageName.equals(mRequiredVerifierPackage)) {
13500 // If this permission is to be granted to the system verifier and
13501 // this app is a verifier, then it gets the permission.
13504 if (!allowed && (bp.protectionLevel
13505 & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
13506 && isSystemApp(pkg)) {
13507 // Any pre-installed system app is allowed to get this permission.
13510 if (!allowed && (bp.protectionLevel
13511 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
13512 // For development permissions, a development permission
13513 // is granted only if it was already granted.
13514 allowed = origPermissions.hasInstallPermission(perm);
13516 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0
13517 && pkg.packageName.equals(mSetupWizardPackage)) {
13518 // If this permission is to be granted to the system setup wizard and
13519 // this app is a setup wizard, then it gets the permission.
13526 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
13527 final int permCount = pkg.requestedPermissions.size();
13528 for (int j = 0; j < permCount; j++) {
13529 String requestedPermission = pkg.requestedPermissions.get(j);
13530 if (permission.equals(requestedPermission)) {
13537 final class ActivityIntentResolver
13538 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
13539 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
13540 boolean defaultOnly, int userId) {
13541 if (!sUserManager.exists(userId)) return null;
13542 mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
13543 return super.queryIntent(intent, resolvedType, defaultOnly, userId);
13546 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
13548 if (!sUserManager.exists(userId)) return null;
13550 return super.queryIntent(intent, resolvedType,
13551 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
13555 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
13556 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
13557 if (!sUserManager.exists(userId)) return null;
13558 if (packageActivities == null) {
13562 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
13563 final int N = packageActivities.size();
13564 ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
13565 new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
13567 ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
13568 for (int i = 0; i < N; ++i) {
13569 intentFilters = packageActivities.get(i).intents;
13570 if (intentFilters != null && intentFilters.size() > 0) {
13571 PackageParser.ActivityIntentInfo[] array =
13572 new PackageParser.ActivityIntentInfo[intentFilters.size()];
13573 intentFilters.toArray(array);
13574 listCut.add(array);
13577 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
13581 * Finds a privileged activity that matches the specified activity names.
13583 private PackageParser.Activity findMatchingActivity(
13584 List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
13585 for (PackageParser.Activity sysActivity : activityList) {
13586 if (sysActivity.info.name.equals(activityInfo.name)) {
13587 return sysActivity;
13589 if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
13590 return sysActivity;
13592 if (sysActivity.info.targetActivity != null) {
13593 if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
13594 return sysActivity;
13596 if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
13597 return sysActivity;
13604 public class IterGenerator<E> {
13605 public Iterator<E> generate(ActivityIntentInfo info) {
13610 public class ActionIterGenerator extends IterGenerator<String> {
13612 public Iterator<String> generate(ActivityIntentInfo info) {
13613 return info.actionsIterator();
13617 public class CategoriesIterGenerator extends IterGenerator<String> {
13619 public Iterator<String> generate(ActivityIntentInfo info) {
13620 return info.categoriesIterator();
13624 public class SchemesIterGenerator extends IterGenerator<String> {
13626 public Iterator<String> generate(ActivityIntentInfo info) {
13627 return info.schemesIterator();
13631 public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
13633 public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
13634 return info.authoritiesIterator();
13639 * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
13640 * MODIFIED. Do not pass in a list that should not be changed.
13642 private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
13643 IterGenerator<T> generator, Iterator<T> searchIterator) {
13644 // loop through the set of actions; every one must be found in the intent filter
13645 while (searchIterator.hasNext()) {
13646 // we must have at least one filter in the list to consider a match
13647 if (intentList.size() == 0) {
13651 final T searchAction = searchIterator.next();
13653 // loop through the set of intent filters
13654 final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
13655 while (intentIter.hasNext()) {
13656 final ActivityIntentInfo intentInfo = intentIter.next();
13657 boolean selectionFound = false;
13659 // loop through the intent filter's selection criteria; at least one
13660 // of them must match the searched criteria
13661 final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
13662 while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
13663 final T intentSelection = intentSelectionIter.next();
13664 if (intentSelection != null && intentSelection.equals(searchAction)) {
13665 selectionFound = true;
13670 // the selection criteria wasn't found in this filter's set; this filter
13671 // is not a potential match
13672 if (!selectionFound) {
13673 intentIter.remove();
13679 private boolean isProtectedAction(ActivityIntentInfo filter) {
13680 final Iterator<String> actionsIter = filter.actionsIterator();
13681 while (actionsIter != null && actionsIter.hasNext()) {
13682 final String filterAction = actionsIter.next();
13683 if (PROTECTED_ACTIONS.contains(filterAction)) {
13691 * Adjusts the priority of the given intent filter according to policy.
13694 * <li>The priority for non privileged applications is capped to '0'</li>
13695 * <li>The priority for protected actions on privileged applications is capped to '0'</li>
13696 * <li>The priority for unbundled updates to privileged applications is capped to the
13697 * priority defined on the system partition</li>
13700 * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
13701 * allowed to obtain any priority on any action.
13703 private void adjustPriority(
13704 List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
13705 // nothing to do; priority is fine as-is
13706 if (intent.getPriority() <= 0) {
13710 final ActivityInfo activityInfo = intent.activity.info;
13711 final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
13713 final boolean privilegedApp =
13714 ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
13715 if (!privilegedApp) {
13716 // non-privileged applications can never define a priority >0
13717 if (DEBUG_FILTERS) {
13718 Slog.i(TAG, "Non-privileged app; cap priority to 0;"
13719 + " package: " + applicationInfo.packageName
13720 + " activity: " + intent.activity.className
13721 + " origPrio: " + intent.getPriority());
13723 intent.setPriority(0);
13727 if (systemActivities == null) {
13728 // the system package is not disabled; we're parsing the system partition
13729 if (isProtectedAction(intent)) {
13730 if (mDeferProtectedFilters) {
13731 // We can't deal with these just yet. No component should ever obtain a
13732 // >0 priority for a protected actions, with ONE exception -- the setup
13733 // wizard. The setup wizard, however, cannot be known until we're able to
13734 // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
13735 // until all intent filters have been processed. Chicken, meet egg.
13736 // Let the filter temporarily have a high priority and rectify the
13737 // priorities after all system packages have been scanned.
13738 mProtectedFilters.add(intent);
13739 if (DEBUG_FILTERS) {
13740 Slog.i(TAG, "Protected action; save for later;"
13741 + " package: " + applicationInfo.packageName
13742 + " activity: " + intent.activity.className
13743 + " origPrio: " + intent.getPriority());
13747 if (DEBUG_FILTERS && mSetupWizardPackage == null) {
13748 Slog.i(TAG, "No setup wizard;"
13749 + " All protected intents capped to priority 0");
13751 if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
13752 if (DEBUG_FILTERS) {
13753 Slog.i(TAG, "Found setup wizard;"
13754 + " allow priority " + intent.getPriority() + ";"
13755 + " package: " + intent.activity.info.packageName
13756 + " activity: " + intent.activity.className
13757 + " priority: " + intent.getPriority());
13759 // setup wizard gets whatever it wants
13762 if (DEBUG_FILTERS) {
13763 Slog.i(TAG, "Protected action; cap priority to 0;"
13764 + " package: " + intent.activity.info.packageName
13765 + " activity: " + intent.activity.className
13766 + " origPrio: " + intent.getPriority());
13768 intent.setPriority(0);
13772 // privileged apps on the system image get whatever priority they request
13776 // privileged app unbundled update ... try to find the same activity
13777 final PackageParser.Activity foundActivity =
13778 findMatchingActivity(systemActivities, activityInfo);
13779 if (foundActivity == null) {
13780 // this is a new activity; it cannot obtain >0 priority
13781 if (DEBUG_FILTERS) {
13782 Slog.i(TAG, "New activity; cap priority to 0;"
13783 + " package: " + applicationInfo.packageName
13784 + " activity: " + intent.activity.className
13785 + " origPrio: " + intent.getPriority());
13787 intent.setPriority(0);
13791 // found activity, now check for filter equivalence
13793 // a shallow copy is enough; we modify the list, not its contents
13794 final List<ActivityIntentInfo> intentListCopy =
13795 new ArrayList<>(foundActivity.intents);
13796 final List<ActivityIntentInfo> foundFilters = findFilters(intent);
13798 // find matching action subsets
13799 final Iterator<String> actionsIterator = intent.actionsIterator();
13800 if (actionsIterator != null) {
13801 getIntentListSubset(
13802 intentListCopy, new ActionIterGenerator(), actionsIterator);
13803 if (intentListCopy.size() == 0) {
13804 // no more intents to match; we're not equivalent
13805 if (DEBUG_FILTERS) {
13806 Slog.i(TAG, "Mismatched action; cap priority to 0;"
13807 + " package: " + applicationInfo.packageName
13808 + " activity: " + intent.activity.className
13809 + " origPrio: " + intent.getPriority());
13811 intent.setPriority(0);
13816 // find matching category subsets
13817 final Iterator<String> categoriesIterator = intent.categoriesIterator();
13818 if (categoriesIterator != null) {
13819 getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
13820 categoriesIterator);
13821 if (intentListCopy.size() == 0) {
13822 // no more intents to match; we're not equivalent
13823 if (DEBUG_FILTERS) {
13824 Slog.i(TAG, "Mismatched category; cap priority to 0;"
13825 + " package: " + applicationInfo.packageName
13826 + " activity: " + intent.activity.className
13827 + " origPrio: " + intent.getPriority());
13829 intent.setPriority(0);
13834 // find matching schemes subsets
13835 final Iterator<String> schemesIterator = intent.schemesIterator();
13836 if (schemesIterator != null) {
13837 getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
13839 if (intentListCopy.size() == 0) {
13840 // no more intents to match; we're not equivalent
13841 if (DEBUG_FILTERS) {
13842 Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
13843 + " package: " + applicationInfo.packageName
13844 + " activity: " + intent.activity.className
13845 + " origPrio: " + intent.getPriority());
13847 intent.setPriority(0);
13852 // find matching authorities subsets
13853 final Iterator<IntentFilter.AuthorityEntry>
13854 authoritiesIterator = intent.authoritiesIterator();
13855 if (authoritiesIterator != null) {
13856 getIntentListSubset(intentListCopy,
13857 new AuthoritiesIterGenerator(),
13858 authoritiesIterator);
13859 if (intentListCopy.size() == 0) {
13860 // no more intents to match; we're not equivalent
13861 if (DEBUG_FILTERS) {
13862 Slog.i(TAG, "Mismatched authority; cap priority to 0;"
13863 + " package: " + applicationInfo.packageName
13864 + " activity: " + intent.activity.className
13865 + " origPrio: " + intent.getPriority());
13867 intent.setPriority(0);
13872 // we found matching filter(s); app gets the max priority of all intents
13873 int cappedPriority = 0;
13874 for (int i = intentListCopy.size() - 1; i >= 0; --i) {
13875 cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
13877 if (intent.getPriority() > cappedPriority) {
13878 if (DEBUG_FILTERS) {
13879 Slog.i(TAG, "Found matching filter(s);"
13880 + " cap priority to " + cappedPriority + ";"
13881 + " package: " + applicationInfo.packageName
13882 + " activity: " + intent.activity.className
13883 + " origPrio: " + intent.getPriority());
13885 intent.setPriority(cappedPriority);
13888 // all this for nothing; the requested priority was <= what was on the system
13891 public final void addActivity(PackageParser.Activity a, String type) {
13892 mActivities.put(a.getComponentName(), a);
13893 if (DEBUG_SHOW_INFO)
13895 TAG, " " + type + " " +
13896 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
13897 if (DEBUG_SHOW_INFO)
13898 Log.v(TAG, " Class=" + a.info.name);
13899 final int NI = a.intents.size();
13900 for (int j=0; j<NI; j++) {
13901 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
13902 if ("activity".equals(type)) {
13903 final PackageSetting ps =
13904 mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
13905 final List<PackageParser.Activity> systemActivities =
13906 ps != null && ps.pkg != null ? ps.pkg.activities : null;
13907 adjustPriority(systemActivities, intent);
13909 if (DEBUG_SHOW_INFO) {
13910 Log.v(TAG, " IntentFilter:");
13911 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
13913 if (!intent.debugCheck()) {
13914 Log.w(TAG, "==> For Activity " + a.info.name);
13920 public final void removeActivity(PackageParser.Activity a, String type) {
13921 mActivities.remove(a.getComponentName());
13922 if (DEBUG_SHOW_INFO) {
13923 Log.v(TAG, " " + type + " "
13924 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
13925 : a.info.name) + ":");
13926 Log.v(TAG, " Class=" + a.info.name);
13928 final int NI = a.intents.size();
13929 for (int j=0; j<NI; j++) {
13930 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
13931 if (DEBUG_SHOW_INFO) {
13932 Log.v(TAG, " IntentFilter:");
13933 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
13935 removeFilter(intent);
13940 protected boolean allowFilterResult(
13941 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
13942 ActivityInfo filterAi = filter.activity.info;
13943 for (int i=dest.size()-1; i>=0; i--) {
13944 ActivityInfo destAi = dest.get(i).activityInfo;
13945 if (destAi.name == filterAi.name
13946 && destAi.packageName == filterAi.packageName) {
13954 protected ActivityIntentInfo[] newArray(int size) {
13955 return new ActivityIntentInfo[size];
13959 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
13960 if (!sUserManager.exists(userId)) return true;
13961 PackageParser.Package p = filter.activity.owner;
13963 PackageSetting ps = (PackageSetting)p.mExtras;
13965 // System apps are never considered stopped for purposes of
13966 // filtering, because there may be no way for the user to
13967 // actually re-launch them.
13968 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
13969 && ps.getStopped(userId);
13976 protected boolean isPackageForFilter(String packageName,
13977 PackageParser.ActivityIntentInfo info) {
13978 return packageName.equals(info.activity.owner.packageName);
13982 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
13983 int match, int userId) {
13984 if (!sUserManager.exists(userId)) return null;
13985 if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
13988 final PackageParser.Activity activity = info.activity;
13989 PackageSetting ps = (PackageSetting) activity.owner.mExtras;
13993 final PackageUserState userState = ps.readUserState(userId);
13995 PackageParser.generateActivityInfo(activity, mFlags, userState, userId);
13999 final boolean matchExplicitlyVisibleOnly =
14000 (mFlags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
14001 final boolean matchVisibleToInstantApp =
14002 (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
14003 final boolean componentVisible =
14004 matchVisibleToInstantApp
14005 && info.isVisibleToInstantApp()
14006 && (!matchExplicitlyVisibleOnly || info.isExplicitlyVisibleToInstantApp());
14007 final boolean matchInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
14008 // throw out filters that aren't visible to ephemeral apps
14009 if (matchVisibleToInstantApp && !(componentVisible || userState.instantApp)) {
14012 // throw out instant app filters if we're not explicitly requesting them
14013 if (!matchInstantApp && userState.instantApp) {
14016 // throw out instant app filters if updates are available; will trigger
14017 // instant app resolution
14018 if (userState.instantApp && ps.isUpdateAvailable()) {
14021 final ResolveInfo res = new ResolveInfo();
14022 res.activityInfo = ai;
14023 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
14026 if (info != null) {
14027 res.handleAllWebDataURI = info.handleAllWebDataURI();
14029 res.priority = info.getPriority();
14030 res.preferredOrder = activity.owner.mPreferredOrder;
14031 //System.out.println("Result: " + res.activityInfo.className +
14032 // " = " + res.priority);
14034 res.isDefault = info.hasDefault;
14035 res.labelRes = info.labelRes;
14036 res.nonLocalizedLabel = info.nonLocalizedLabel;
14037 if (userNeedsBadging(userId)) {
14038 res.noResourceId = true;
14040 res.icon = info.icon;
14042 res.iconResourceId = info.icon;
14043 res.system = res.activityInfo.applicationInfo.isSystemApp();
14044 res.isInstantAppAvailable = userState.instantApp;
14049 protected void sortResults(List<ResolveInfo> results) {
14050 Collections.sort(results, mResolvePrioritySorter);
14054 protected void dumpFilter(PrintWriter out, String prefix,
14055 PackageParser.ActivityIntentInfo filter) {
14056 out.print(prefix); out.print(
14057 Integer.toHexString(System.identityHashCode(filter.activity)));
14059 filter.activity.printComponentShortName(out);
14060 out.print(" filter ");
14061 out.println(Integer.toHexString(System.identityHashCode(filter)));
14065 protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
14066 return filter.activity;
14069 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
14070 PackageParser.Activity activity = (PackageParser.Activity)label;
14071 out.print(prefix); out.print(
14072 Integer.toHexString(System.identityHashCode(activity)));
14074 activity.printComponentShortName(out);
14076 out.print(" ("); out.print(count); out.print(" filters)");
14081 // Keys are String (activity class name), values are Activity.
14082 private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
14083 = new ArrayMap<ComponentName, PackageParser.Activity>();
14084 private int mFlags;
14087 private final class ServiceIntentResolver
14088 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
14089 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
14090 boolean defaultOnly, int userId) {
14091 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
14092 return super.queryIntent(intent, resolvedType, defaultOnly, userId);
14095 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
14097 if (!sUserManager.exists(userId)) return null;
14099 return super.queryIntent(intent, resolvedType,
14100 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
14104 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
14105 int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
14106 if (!sUserManager.exists(userId)) return null;
14107 if (packageServices == null) {
14111 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
14112 final int N = packageServices.size();
14113 ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
14114 new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
14116 ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
14117 for (int i = 0; i < N; ++i) {
14118 intentFilters = packageServices.get(i).intents;
14119 if (intentFilters != null && intentFilters.size() > 0) {
14120 PackageParser.ServiceIntentInfo[] array =
14121 new PackageParser.ServiceIntentInfo[intentFilters.size()];
14122 intentFilters.toArray(array);
14123 listCut.add(array);
14126 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
14129 public final void addService(PackageParser.Service s) {
14130 mServices.put(s.getComponentName(), s);
14131 if (DEBUG_SHOW_INFO) {
14133 + (s.info.nonLocalizedLabel != null
14134 ? s.info.nonLocalizedLabel : s.info.name) + ":");
14135 Log.v(TAG, " Class=" + s.info.name);
14137 final int NI = s.intents.size();
14139 for (j=0; j<NI; j++) {
14140 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
14141 if (DEBUG_SHOW_INFO) {
14142 Log.v(TAG, " IntentFilter:");
14143 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
14145 if (!intent.debugCheck()) {
14146 Log.w(TAG, "==> For Service " + s.info.name);
14152 public final void removeService(PackageParser.Service s) {
14153 mServices.remove(s.getComponentName());
14154 if (DEBUG_SHOW_INFO) {
14155 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null
14156 ? s.info.nonLocalizedLabel : s.info.name) + ":");
14157 Log.v(TAG, " Class=" + s.info.name);
14159 final int NI = s.intents.size();
14161 for (j=0; j<NI; j++) {
14162 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
14163 if (DEBUG_SHOW_INFO) {
14164 Log.v(TAG, " IntentFilter:");
14165 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
14167 removeFilter(intent);
14172 protected boolean allowFilterResult(
14173 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
14174 ServiceInfo filterSi = filter.service.info;
14175 for (int i=dest.size()-1; i>=0; i--) {
14176 ServiceInfo destAi = dest.get(i).serviceInfo;
14177 if (destAi.name == filterSi.name
14178 && destAi.packageName == filterSi.packageName) {
14186 protected PackageParser.ServiceIntentInfo[] newArray(int size) {
14187 return new PackageParser.ServiceIntentInfo[size];
14191 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
14192 if (!sUserManager.exists(userId)) return true;
14193 PackageParser.Package p = filter.service.owner;
14195 PackageSetting ps = (PackageSetting)p.mExtras;
14197 // System apps are never considered stopped for purposes of
14198 // filtering, because there may be no way for the user to
14199 // actually re-launch them.
14200 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
14201 && ps.getStopped(userId);
14208 protected boolean isPackageForFilter(String packageName,
14209 PackageParser.ServiceIntentInfo info) {
14210 return packageName.equals(info.service.owner.packageName);
14214 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
14215 int match, int userId) {
14216 if (!sUserManager.exists(userId)) return null;
14217 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
14218 if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
14221 final PackageParser.Service service = info.service;
14222 PackageSetting ps = (PackageSetting) service.owner.mExtras;
14226 final PackageUserState userState = ps.readUserState(userId);
14227 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
14228 userState, userId);
14232 final boolean matchVisibleToInstantApp =
14233 (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
14234 final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
14235 // throw out filters that aren't visible to ephemeral apps
14236 if (matchVisibleToInstantApp
14237 && !(info.isVisibleToInstantApp() || userState.instantApp)) {
14240 // throw out ephemeral filters if we're not explicitly requesting them
14241 if (!isInstantApp && userState.instantApp) {
14244 // throw out instant app filters if updates are available; will trigger
14245 // instant app resolution
14246 if (userState.instantApp && ps.isUpdateAvailable()) {
14249 final ResolveInfo res = new ResolveInfo();
14250 res.serviceInfo = si;
14251 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
14252 res.filter = filter;
14254 res.priority = info.getPriority();
14255 res.preferredOrder = service.owner.mPreferredOrder;
14257 res.isDefault = info.hasDefault;
14258 res.labelRes = info.labelRes;
14259 res.nonLocalizedLabel = info.nonLocalizedLabel;
14260 res.icon = info.icon;
14261 res.system = res.serviceInfo.applicationInfo.isSystemApp();
14266 protected void sortResults(List<ResolveInfo> results) {
14267 Collections.sort(results, mResolvePrioritySorter);
14271 protected void dumpFilter(PrintWriter out, String prefix,
14272 PackageParser.ServiceIntentInfo filter) {
14273 out.print(prefix); out.print(
14274 Integer.toHexString(System.identityHashCode(filter.service)));
14276 filter.service.printComponentShortName(out);
14277 out.print(" filter ");
14278 out.println(Integer.toHexString(System.identityHashCode(filter)));
14282 protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
14283 return filter.service;
14286 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
14287 PackageParser.Service service = (PackageParser.Service)label;
14288 out.print(prefix); out.print(
14289 Integer.toHexString(System.identityHashCode(service)));
14291 service.printComponentShortName(out);
14293 out.print(" ("); out.print(count); out.print(" filters)");
14298 // List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
14299 // final Iterator<ResolveInfo> i = resolveInfoList.iterator();
14300 // final List<ResolveInfo> retList = Lists.newArrayList();
14301 // while (i.hasNext()) {
14302 // final ResolveInfo resolveInfo = (ResolveInfo) i;
14303 // if (isEnabledLP(resolveInfo.serviceInfo)) {
14304 // retList.add(resolveInfo);
14310 // Keys are String (activity class name), values are Activity.
14311 private final ArrayMap<ComponentName, PackageParser.Service> mServices
14312 = new ArrayMap<ComponentName, PackageParser.Service>();
14313 private int mFlags;
14316 private final class ProviderIntentResolver
14317 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
14318 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
14319 boolean defaultOnly, int userId) {
14320 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
14321 return super.queryIntent(intent, resolvedType, defaultOnly, userId);
14324 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
14326 if (!sUserManager.exists(userId))
14329 return super.queryIntent(intent, resolvedType,
14330 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
14334 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
14335 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
14336 if (!sUserManager.exists(userId))
14338 if (packageProviders == null) {
14342 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
14343 final int N = packageProviders.size();
14344 ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
14345 new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
14347 ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
14348 for (int i = 0; i < N; ++i) {
14349 intentFilters = packageProviders.get(i).intents;
14350 if (intentFilters != null && intentFilters.size() > 0) {
14351 PackageParser.ProviderIntentInfo[] array =
14352 new PackageParser.ProviderIntentInfo[intentFilters.size()];
14353 intentFilters.toArray(array);
14354 listCut.add(array);
14357 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
14360 public final void addProvider(PackageParser.Provider p) {
14361 if (mProviders.containsKey(p.getComponentName())) {
14362 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
14366 mProviders.put(p.getComponentName(), p);
14367 if (DEBUG_SHOW_INFO) {
14369 + (p.info.nonLocalizedLabel != null
14370 ? p.info.nonLocalizedLabel : p.info.name) + ":");
14371 Log.v(TAG, " Class=" + p.info.name);
14373 final int NI = p.intents.size();
14375 for (j = 0; j < NI; j++) {
14376 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
14377 if (DEBUG_SHOW_INFO) {
14378 Log.v(TAG, " IntentFilter:");
14379 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
14381 if (!intent.debugCheck()) {
14382 Log.w(TAG, "==> For Provider " + p.info.name);
14388 public final void removeProvider(PackageParser.Provider p) {
14389 mProviders.remove(p.getComponentName());
14390 if (DEBUG_SHOW_INFO) {
14391 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null
14392 ? p.info.nonLocalizedLabel : p.info.name) + ":");
14393 Log.v(TAG, " Class=" + p.info.name);
14395 final int NI = p.intents.size();
14397 for (j = 0; j < NI; j++) {
14398 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
14399 if (DEBUG_SHOW_INFO) {
14400 Log.v(TAG, " IntentFilter:");
14401 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
14403 removeFilter(intent);
14408 protected boolean allowFilterResult(
14409 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
14410 ProviderInfo filterPi = filter.provider.info;
14411 for (int i = dest.size() - 1; i >= 0; i--) {
14412 ProviderInfo destPi = dest.get(i).providerInfo;
14413 if (destPi.name == filterPi.name
14414 && destPi.packageName == filterPi.packageName) {
14422 protected PackageParser.ProviderIntentInfo[] newArray(int size) {
14423 return new PackageParser.ProviderIntentInfo[size];
14427 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
14428 if (!sUserManager.exists(userId))
14430 PackageParser.Package p = filter.provider.owner;
14432 PackageSetting ps = (PackageSetting) p.mExtras;
14434 // System apps are never considered stopped for purposes of
14435 // filtering, because there may be no way for the user to
14436 // actually re-launch them.
14437 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
14438 && ps.getStopped(userId);
14445 protected boolean isPackageForFilter(String packageName,
14446 PackageParser.ProviderIntentInfo info) {
14447 return packageName.equals(info.provider.owner.packageName);
14451 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
14452 int match, int userId) {
14453 if (!sUserManager.exists(userId))
14455 final PackageParser.ProviderIntentInfo info = filter;
14456 if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
14459 final PackageParser.Provider provider = info.provider;
14460 PackageSetting ps = (PackageSetting) provider.owner.mExtras;
14464 final PackageUserState userState = ps.readUserState(userId);
14465 final boolean matchVisibleToInstantApp =
14466 (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
14467 final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
14468 // throw out filters that aren't visible to instant applications
14469 if (matchVisibleToInstantApp
14470 && !(info.isVisibleToInstantApp() || userState.instantApp)) {
14473 // throw out instant application filters if we're not explicitly requesting them
14474 if (!isInstantApp && userState.instantApp) {
14477 // throw out instant application filters if updates are available; will trigger
14478 // instant application resolution
14479 if (userState.instantApp && ps.isUpdateAvailable()) {
14482 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
14483 userState, userId);
14487 final ResolveInfo res = new ResolveInfo();
14488 res.providerInfo = pi;
14489 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
14490 res.filter = filter;
14492 res.priority = info.getPriority();
14493 res.preferredOrder = provider.owner.mPreferredOrder;
14495 res.isDefault = info.hasDefault;
14496 res.labelRes = info.labelRes;
14497 res.nonLocalizedLabel = info.nonLocalizedLabel;
14498 res.icon = info.icon;
14499 res.system = res.providerInfo.applicationInfo.isSystemApp();
14504 protected void sortResults(List<ResolveInfo> results) {
14505 Collections.sort(results, mResolvePrioritySorter);
14509 protected void dumpFilter(PrintWriter out, String prefix,
14510 PackageParser.ProviderIntentInfo filter) {
14513 Integer.toHexString(System.identityHashCode(filter.provider)));
14515 filter.provider.printComponentShortName(out);
14516 out.print(" filter ");
14517 out.println(Integer.toHexString(System.identityHashCode(filter)));
14521 protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
14522 return filter.provider;
14525 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
14526 PackageParser.Provider provider = (PackageParser.Provider)label;
14527 out.print(prefix); out.print(
14528 Integer.toHexString(System.identityHashCode(provider)));
14530 provider.printComponentShortName(out);
14532 out.print(" ("); out.print(count); out.print(" filters)");
14537 private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
14538 = new ArrayMap<ComponentName, PackageParser.Provider>();
14539 private int mFlags;
14542 static final class EphemeralIntentResolver
14543 extends IntentResolver<AuxiliaryResolveInfo, AuxiliaryResolveInfo> {
14545 * The result that has the highest defined order. Ordering applies on a
14546 * per-package basis. Mapping is from package name to Pair of order and
14547 * EphemeralResolveInfo.
14549 * NOTE: This is implemented as a field variable for convenience and efficiency.
14550 * By having a field variable, we're able to track filter ordering as soon as
14551 * a non-zero order is defined. Otherwise, multiple loops across the result set
14552 * would be needed to apply ordering. If the intent resolver becomes re-entrant,
14553 * this needs to be contained entirely within {@link #filterResults}.
14555 final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
14558 protected AuxiliaryResolveInfo[] newArray(int size) {
14559 return new AuxiliaryResolveInfo[size];
14563 protected boolean isPackageForFilter(String packageName, AuxiliaryResolveInfo responseObj) {
14568 protected AuxiliaryResolveInfo newResult(AuxiliaryResolveInfo responseObj, int match,
14570 if (!sUserManager.exists(userId)) {
14573 final String packageName = responseObj.resolveInfo.getPackageName();
14574 final Integer order = responseObj.getOrder();
14575 final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
14576 mOrderResult.get(packageName);
14577 // ordering is enabled and this item's order isn't high enough
14578 if (lastOrderResult != null && lastOrderResult.first >= order) {
14581 final InstantAppResolveInfo res = responseObj.resolveInfo;
14583 // non-zero order, enable ordering
14584 mOrderResult.put(packageName, new Pair<>(order, res));
14586 return responseObj;
14590 protected void filterResults(List<AuxiliaryResolveInfo> results) {
14591 // only do work if ordering is enabled [most of the time it won't be]
14592 if (mOrderResult.size() == 0) {
14595 int resultSize = results.size();
14596 for (int i = 0; i < resultSize; i++) {
14597 final InstantAppResolveInfo info = results.get(i).resolveInfo;
14598 final String packageName = info.getPackageName();
14599 final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName);
14600 if (savedInfo == null) {
14601 // package doesn't having ordering
14604 if (savedInfo.second == info) {
14605 // circled back to the highest ordered item; remove from order list
14606 mOrderResult.remove(packageName);
14607 if (mOrderResult.size() == 0) {
14608 // no more ordered items
14613 // item has a worse order, remove it from the result list
14621 private static final Comparator<ResolveInfo> mResolvePrioritySorter =
14622 new Comparator<ResolveInfo>() {
14623 public int compare(ResolveInfo r1, ResolveInfo r2) {
14624 int v1 = r1.priority;
14625 int v2 = r2.priority;
14626 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
14628 return (v1 > v2) ? -1 : 1;
14630 v1 = r1.preferredOrder;
14631 v2 = r2.preferredOrder;
14633 return (v1 > v2) ? -1 : 1;
14635 if (r1.isDefault != r2.isDefault) {
14636 return r1.isDefault ? -1 : 1;
14640 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
14642 return (v1 > v2) ? -1 : 1;
14644 if (r1.system != r2.system) {
14645 return r1.system ? -1 : 1;
14647 if (r1.activityInfo != null) {
14648 return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
14650 if (r1.serviceInfo != null) {
14651 return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
14653 if (r1.providerInfo != null) {
14654 return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
14660 private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
14661 new Comparator<ProviderInfo>() {
14662 public int compare(ProviderInfo p1, ProviderInfo p2) {
14663 final int v1 = p1.initOrder;
14664 final int v2 = p2.initOrder;
14665 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
14669 public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
14670 final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
14671 final int[] userIds) {
14672 mHandler.post(new Runnable() {
14674 public void run() {
14676 final IActivityManager am = ActivityManager.getService();
14677 if (am == null) return;
14678 final int[] resolvedUserIds;
14679 if (userIds == null) {
14680 resolvedUserIds = am.getRunningUserIds();
14682 resolvedUserIds = userIds;
14684 for (int id : resolvedUserIds) {
14685 final Intent intent = new Intent(action,
14686 pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
14687 if (extras != null) {
14688 intent.putExtras(extras);
14690 if (targetPkg != null) {
14691 intent.setPackage(targetPkg);
14693 // Modify the UID when posting to other users
14694 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
14695 if (uid > 0 && UserHandle.getUserId(uid) != id) {
14696 uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
14697 intent.putExtra(Intent.EXTRA_UID, uid);
14699 intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
14700 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
14701 if (DEBUG_BROADCASTS) {
14702 RuntimeException here = new RuntimeException("here");
14703 here.fillInStackTrace();
14704 Slog.d(TAG, "Sending to user " + id + ": "
14705 + intent.toShortString(false, true, false, false)
14706 + " " + intent.getExtras(), here);
14708 am.broadcastIntent(null, intent, null, finishedReceiver,
14709 0, null, null, null, android.app.AppOpsManager.OP_NONE,
14710 null, finishedReceiver != null, false, id);
14712 } catch (RemoteException ex) {
14719 * Check if the external storage media is available. This is true if there
14720 * is a mounted external storage medium or if the external storage is
14723 private boolean isExternalMediaAvailable() {
14724 return mMediaMounted || Environment.isExternalStorageEmulated();
14728 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
14729 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14733 synchronized (mPackages) {
14734 if (!isExternalMediaAvailable()) {
14735 // If the external storage is no longer mounted at this point,
14736 // the caller may not have been able to delete all of this
14737 // packages files and can not delete any more. Bail.
14740 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
14741 if (lastPackage != null) {
14742 pkgs.remove(lastPackage);
14744 if (pkgs.size() > 0) {
14745 return pkgs.get(0);
14751 void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
14752 final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
14753 userId, andCode ? 1 : 0, packageName);
14754 if (mSystemReady) {
14755 msg.sendToTarget();
14757 if (mPostSystemReadyMessages == null) {
14758 mPostSystemReadyMessages = new ArrayList<>();
14760 mPostSystemReadyMessages.add(msg);
14764 void startCleaningPackages() {
14766 if (!isExternalMediaAvailable()) {
14769 synchronized (mPackages) {
14770 if (mSettings.mPackagesToBeCleaned.isEmpty()) {
14774 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
14775 intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
14776 IActivityManager am = ActivityManager.getService();
14779 synchronized (mPackages) {
14780 if (!mDefaultContainerWhitelisted) {
14781 mDefaultContainerWhitelisted = true;
14782 PackageSetting ps = mSettings.mPackages.get(DEFAULT_CONTAINER_PACKAGE);
14783 dcsUid = UserHandle.getUid(UserHandle.USER_SYSTEM, ps.appId);
14788 am.backgroundWhitelistUid(dcsUid);
14790 am.startService(null, intent, null, false, mContext.getOpPackageName(),
14791 UserHandle.USER_SYSTEM);
14792 } catch (RemoteException e) {
14798 public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
14799 int installFlags, String installerPackageName, int userId) {
14800 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
14802 final int callingUid = Binder.getCallingUid();
14803 enforceCrossUserPermission(callingUid, userId,
14804 true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");
14806 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
14808 if (observer != null) {
14809 observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
14811 } catch (RemoteException re) {
14816 if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
14817 installFlags |= PackageManager.INSTALL_FROM_ADB;
14820 // Caller holds INSTALL_PACKAGES permission, so we're less strict
14821 // about installerPackageName.
14823 installFlags &= ~PackageManager.INSTALL_FROM_ADB;
14824 installFlags &= ~PackageManager.INSTALL_ALL_USERS;
14828 if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
14829 user = UserHandle.ALL;
14831 user = new UserHandle(userId);
14834 // Only system components can circumvent runtime permissions when installing.
14835 if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
14836 && mContext.checkCallingOrSelfPermission(Manifest.permission
14837 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
14838 throw new SecurityException("You need the "
14839 + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
14840 + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
14843 if ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0
14844 || (installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
14845 throw new IllegalArgumentException(
14846 "New installs into ASEC containers no longer supported");
14849 final File originFile = new File(originPath);
14850 final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
14852 final Message msg = mHandler.obtainMessage(INIT_COPY);
14853 final VerificationInfo verificationInfo = new VerificationInfo(
14854 null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);
14855 final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,
14856 installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,
14857 null /*packageAbiOverride*/, null /*grantedPermissions*/,
14858 null /*certificates*/, PackageManager.INSTALL_REASON_UNKNOWN);
14859 params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
14862 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
14863 System.identityHashCode(msg.obj));
14864 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
14865 System.identityHashCode(msg.obj));
14867 mHandler.sendMessage(msg);
14872 * Ensure that the install reason matches what we know about the package installer (e.g. whether
14873 * it is acting on behalf on an enterprise or the user).
14875 * Note that the ordering of the conditionals in this method is important. The checks we perform
14876 * are as follows, in this order:
14878 * 1) If the install is being performed by a system app, we can trust the app to have set the
14879 * install reason correctly. Thus, we pass through the install reason unchanged, no matter
14881 * 2) If the install is being performed by a device or profile owner app, the install reason
14882 * should be enterprise policy. However, we cannot be sure that the device or profile owner
14883 * set the install reason correctly. If the app targets an older SDK version where install
14884 * reasons did not exist yet, or if the app author simply forgot, the install reason may be
14885 * unset or wrong. Thus, we force the install reason to be enterprise policy.
14886 * 3) In all other cases, the install is being performed by a regular app that is neither part
14887 * of the system nor a device or profile owner. We have no reason to believe that this app is
14888 * acting on behalf of the enterprise admin. Thus, we check whether the install reason was
14889 * set to enterprise policy and if so, change it to unknown instead.
14891 private int fixUpInstallReason(String installerPackageName, int installerUid,
14892 int installReason) {
14893 if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
14894 == PERMISSION_GRANTED) {
14895 // If the install is being performed by a system app, we trust that app to have set the
14896 // install reason correctly.
14897 return installReason;
14900 final IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
14901 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
14903 ComponentName owner = null;
14905 owner = dpm.getDeviceOwnerComponent(true /* callingUserOnly */);
14906 if (owner == null) {
14907 owner = dpm.getProfileOwner(UserHandle.getUserId(installerUid));
14909 } catch (RemoteException e) {
14911 if (owner != null && owner.getPackageName().equals(installerPackageName)) {
14912 // If the install is being performed by a device or profile owner, the install
14913 // reason should be enterprise policy.
14914 return PackageManager.INSTALL_REASON_POLICY;
14918 if (installReason == PackageManager.INSTALL_REASON_POLICY) {
14919 // If the install is being performed by a regular app (i.e. neither system app nor
14920 // device or profile owner), we have no reason to believe that the app is acting on
14921 // behalf of an enterprise. If the app set the install reason to enterprise policy,
14922 // change it to unknown instead.
14923 return PackageManager.INSTALL_REASON_UNKNOWN;
14926 // If the install is being performed by a regular app and the install reason was set to any
14927 // value but enterprise policy, leave the install reason unchanged.
14928 return installReason;
14931 void installStage(String packageName, File stagedDir, String stagedCid,
14932 IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
14933 String installerPackageName, int installerUid, UserHandle user,
14934 Certificate[][] certificates) {
14935 if (DEBUG_EPHEMERAL) {
14936 if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
14937 Slog.d(TAG, "Ephemeral install of " + packageName);
14940 final VerificationInfo verificationInfo = new VerificationInfo(
14941 sessionParams.originatingUri, sessionParams.referrerUri,
14942 sessionParams.originatingUid, installerUid);
14944 final OriginInfo origin;
14945 if (stagedDir != null) {
14946 origin = OriginInfo.fromStagedFile(stagedDir);
14948 origin = OriginInfo.fromStagedContainer(stagedCid);
14951 final Message msg = mHandler.obtainMessage(INIT_COPY);
14952 final int installReason = fixUpInstallReason(installerPackageName, installerUid,
14953 sessionParams.installReason);
14954 final InstallParams params = new InstallParams(origin, null, observer,
14955 sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
14956 verificationInfo, user, sessionParams.abiOverride,
14957 sessionParams.grantedRuntimePermissions, certificates, installReason);
14958 params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
14961 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
14962 System.identityHashCode(msg.obj));
14963 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
14964 System.identityHashCode(msg.obj));
14966 mHandler.sendMessage(msg);
14969 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
14971 final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
14972 sendPackageAddedForNewUsers(packageName, isSystem /*sendBootCompleted*/,
14973 false /*startReceiver*/, pkgSetting.appId, userId);
14975 // Send a session commit broadcast
14976 final PackageInstaller.SessionInfo info = new PackageInstaller.SessionInfo();
14977 info.installReason = pkgSetting.getInstallReason(userId);
14978 info.appPackageName = packageName;
14979 sendSessionCommitBroadcast(info, userId);
14982 public void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
14983 boolean includeStopped, int appId, int... userIds) {
14984 if (ArrayUtils.isEmpty(userIds)) {
14987 Bundle extras = new Bundle(1);
14988 // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
14989 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userIds[0], appId));
14991 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
14992 packageName, extras, 0, null, null, userIds);
14993 if (sendBootCompleted) {
14994 mHandler.post(() -> {
14995 for (int userId : userIds) {
14996 sendBootCompletedBroadcastToSystemApp(
14997 packageName, includeStopped, userId);
15005 * The just-installed/enabled app is bundled on the system, so presumed to be able to run
15006 * automatically without needing an explicit launch.
15007 * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
15009 private void sendBootCompletedBroadcastToSystemApp(String packageName, boolean includeStopped,
15011 // If user is not running, the app didn't miss any broadcast
15012 if (!mUserManagerInternal.isUserRunning(userId)) {
15015 final IActivityManager am = ActivityManager.getService();
15017 // Deliver LOCKED_BOOT_COMPLETED first
15018 Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
15019 .setPackage(packageName);
15020 if (includeStopped) {
15021 lockedBcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
15023 final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
15024 am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
15025 android.app.AppOpsManager.OP_NONE, null, false, false, userId);
15027 // Deliver BOOT_COMPLETED only if user is unlocked
15028 if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
15029 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
15030 if (includeStopped) {
15031 bcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
15033 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
15034 android.app.AppOpsManager.OP_NONE, null, false, false, userId);
15036 } catch (RemoteException e) {
15037 throw e.rethrowFromSystemServer();
15042 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
15044 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
15045 PackageSetting pkgSetting;
15046 final int callingUid = Binder.getCallingUid();
15047 enforceCrossUserPermission(callingUid, userId,
15048 true /* requireFullPermission */, true /* checkShell */,
15049 "setApplicationHiddenSetting for user " + userId);
15051 if (hidden && isPackageDeviceAdmin(packageName, userId)) {
15052 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
15056 long callingId = Binder.clearCallingIdentity();
15058 boolean sendAdded = false;
15059 boolean sendRemoved = false;
15061 synchronized (mPackages) {
15062 pkgSetting = mSettings.mPackages.get(packageName);
15063 if (pkgSetting == null) {
15066 if (filterAppAccessLPr(pkgSetting, callingUid, userId)) {
15069 // Do not allow "android" is being disabled
15070 if ("android".equals(packageName)) {
15071 Slog.w(TAG, "Cannot hide package: android");
15074 // Cannot hide static shared libs as they are considered
15075 // a part of the using app (emulating static linking). Also
15076 // static libs are installed always on internal storage.
15077 PackageParser.Package pkg = mPackages.get(packageName);
15078 if (pkg != null && pkg.staticSharedLibName != null) {
15079 Slog.w(TAG, "Cannot hide package: " + packageName
15080 + " providing static shared library: "
15081 + pkg.staticSharedLibName);
15084 // Only allow protected packages to hide themselves.
15085 if (hidden && !UserHandle.isSameApp(callingUid, pkgSetting.appId)
15086 && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
15087 Slog.w(TAG, "Not hiding protected package: " + packageName);
15091 if (pkgSetting.getHidden(userId) != hidden) {
15092 pkgSetting.setHidden(hidden, userId);
15093 mSettings.writePackageRestrictionsLPr(userId);
15095 sendRemoved = true;
15102 sendPackageAddedForUser(packageName, pkgSetting, userId);
15106 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
15108 sendApplicationHiddenForUser(packageName, pkgSetting, userId);
15112 Binder.restoreCallingIdentity(callingId);
15117 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
15119 final PackageRemovedInfo info = new PackageRemovedInfo(this);
15120 info.removedPackage = packageName;
15121 info.installerPackageName = pkgSetting.installerPackageName;
15122 info.removedUsers = new int[] {userId};
15123 info.broadcastUsers = new int[] {userId};
15124 info.uid = UserHandle.getUid(userId, pkgSetting.appId);
15125 info.sendPackageRemovedBroadcasts(true /*killApp*/);
15128 private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
15129 if (pkgList.length > 0) {
15130 Bundle extras = new Bundle(1);
15131 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
15133 sendPackageBroadcast(
15134 suspended ? Intent.ACTION_PACKAGES_SUSPENDED
15135 : Intent.ACTION_PACKAGES_UNSUSPENDED,
15136 null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
15137 new int[] {userId});
15142 * Returns true if application is not found or there was an error. Otherwise it returns
15143 * the hidden state of the package for the given user.
15146 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
15147 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
15148 final int callingUid = Binder.getCallingUid();
15149 enforceCrossUserPermission(callingUid, userId,
15150 true /* requireFullPermission */, false /* checkShell */,
15151 "getApplicationHidden for user " + userId);
15153 long callingId = Binder.clearCallingIdentity();
15156 synchronized (mPackages) {
15157 ps = mSettings.mPackages.get(packageName);
15161 if (filterAppAccessLPr(ps, callingUid, userId)) {
15164 return ps.getHidden(userId);
15167 Binder.restoreCallingIdentity(callingId);
15175 public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
15176 int installReason) {
15177 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
15179 PackageSetting pkgSetting;
15180 final int callingUid = Binder.getCallingUid();
15181 enforceCrossUserPermission(callingUid, userId,
15182 true /* requireFullPermission */, true /* checkShell */,
15183 "installExistingPackage for user " + userId);
15184 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
15185 return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
15188 long callingId = Binder.clearCallingIdentity();
15190 boolean installed = false;
15191 final boolean instantApp =
15192 (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15193 final boolean fullApp =
15194 (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
15197 synchronized (mPackages) {
15198 pkgSetting = mSettings.mPackages.get(packageName);
15199 if (pkgSetting == null) {
15200 return PackageManager.INSTALL_FAILED_INVALID_URI;
15202 if (!canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
15203 // only allow the existing package to be used if it's installed as a full
15204 // application for at least one user
15205 boolean installAllowed = false;
15206 for (int checkUserId : sUserManager.getUserIds()) {
15207 installAllowed = !pkgSetting.getInstantApp(checkUserId);
15208 if (installAllowed) {
15212 if (!installAllowed) {
15213 return PackageManager.INSTALL_FAILED_INVALID_URI;
15216 if (!pkgSetting.getInstalled(userId)) {
15217 pkgSetting.setInstalled(true, userId);
15218 pkgSetting.setHidden(false, userId);
15219 pkgSetting.setInstallReason(installReason, userId);
15220 mSettings.writePackageRestrictionsLPr(userId);
15221 mSettings.writeKernelMappingLPr(pkgSetting);
15223 } else if (fullApp && pkgSetting.getInstantApp(userId)) {
15224 // upgrade app from instant to full; we don't allow app downgrade
15227 setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
15231 if (pkgSetting.pkg != null) {
15232 synchronized (mInstallLock) {
15233 // We don't need to freeze for a brand new install
15234 prepareAppDataAfterInstallLIF(pkgSetting.pkg);
15237 sendPackageAddedForUser(packageName, pkgSetting, userId);
15238 synchronized (mPackages) {
15239 updateSequenceNumberLP(pkgSetting, new int[]{ userId });
15243 Binder.restoreCallingIdentity(callingId);
15246 return PackageManager.INSTALL_SUCCEEDED;
15249 void setInstantAppForUser(PackageSetting pkgSetting, int userId,
15250 boolean instantApp, boolean fullApp) {
15251 // no state specified; do nothing
15252 if (!instantApp && !fullApp) {
15255 if (userId != UserHandle.USER_ALL) {
15256 if (instantApp && !pkgSetting.getInstantApp(userId)) {
15257 pkgSetting.setInstantApp(true /*instantApp*/, userId);
15258 } else if (fullApp && pkgSetting.getInstantApp(userId)) {
15259 pkgSetting.setInstantApp(false /*instantApp*/, userId);
15262 for (int currentUserId : sUserManager.getUserIds()) {
15263 if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
15264 pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
15265 } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
15266 pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
15272 boolean isUserRestricted(int userId, String restrictionKey) {
15273 Bundle restrictions = sUserManager.getUserRestrictions(userId);
15274 if (restrictions.getBoolean(restrictionKey, false)) {
15275 Log.w(TAG, "User is restricted: " + restrictionKey);
15282 public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
15284 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
15285 final int callingUid = Binder.getCallingUid();
15286 enforceCrossUserPermission(callingUid, userId,
15287 true /* requireFullPermission */, true /* checkShell */,
15288 "setPackagesSuspended for user " + userId);
15290 if (ArrayUtils.isEmpty(packageNames)) {
15291 return packageNames;
15294 // List of package names for whom the suspended state has changed.
15295 List<String> changedPackages = new ArrayList<>(packageNames.length);
15296 // List of package names for whom the suspended state is not set as requested in this
15298 List<String> unactionedPackages = new ArrayList<>(packageNames.length);
15299 long callingId = Binder.clearCallingIdentity();
15301 for (int i = 0; i < packageNames.length; i++) {
15302 String packageName = packageNames[i];
15303 boolean changed = false;
15305 synchronized (mPackages) {
15306 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
15307 if (pkgSetting == null
15308 || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
15309 Slog.w(TAG, "Could not find package setting for package \"" + packageName
15310 + "\". Skipping suspending/un-suspending.");
15311 unactionedPackages.add(packageName);
15314 appId = pkgSetting.appId;
15315 if (pkgSetting.getSuspended(userId) != suspended) {
15316 if (!canSuspendPackageForUserLocked(packageName, userId)) {
15317 unactionedPackages.add(packageName);
15320 pkgSetting.setSuspended(suspended, userId);
15321 mSettings.writePackageRestrictionsLPr(userId);
15323 changedPackages.add(packageName);
15327 if (changed && suspended) {
15328 killApplication(packageName, UserHandle.getUid(userId, appId),
15329 "suspending package");
15333 Binder.restoreCallingIdentity(callingId);
15336 if (!changedPackages.isEmpty()) {
15337 sendPackagesSuspendedForUser(changedPackages.toArray(
15338 new String[changedPackages.size()]), userId, suspended);
15341 return unactionedPackages.toArray(new String[unactionedPackages.size()]);
15345 public boolean isPackageSuspendedForUser(String packageName, int userId) {
15346 final int callingUid = Binder.getCallingUid();
15347 enforceCrossUserPermission(callingUid, userId,
15348 true /* requireFullPermission */, false /* checkShell */,
15349 "isPackageSuspendedForUser for user " + userId);
15350 synchronized (mPackages) {
15351 final PackageSetting ps = mSettings.mPackages.get(packageName);
15352 if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
15353 throw new IllegalArgumentException("Unknown target package: " + packageName);
15355 return ps.getSuspended(userId);
15359 private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
15360 if (isPackageDeviceAdmin(packageName, userId)) {
15361 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15362 + "\": has an active device admin");
15366 String activeLauncherPackageName = getActiveLauncherPackageName(userId);
15367 if (packageName.equals(activeLauncherPackageName)) {
15368 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15369 + "\": contains the active launcher");
15373 if (packageName.equals(mRequiredInstallerPackage)) {
15374 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15375 + "\": required for package installation");
15379 if (packageName.equals(mRequiredUninstallerPackage)) {
15380 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15381 + "\": required for package uninstallation");
15385 if (packageName.equals(mRequiredVerifierPackage)) {
15386 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15387 + "\": required for package verification");
15391 if (packageName.equals(getDefaultDialerPackageName(userId))) {
15392 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15393 + "\": is the default dialer");
15397 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
15398 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15399 + "\": protected package");
15403 // Cannot suspend static shared libs as they are considered
15404 // a part of the using app (emulating static linking). Also
15405 // static libs are installed always on internal storage.
15406 PackageParser.Package pkg = mPackages.get(packageName);
15407 if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
15408 Slog.w(TAG, "Cannot suspend package: " + packageName
15409 + " providing static shared library: "
15410 + pkg.staticSharedLibName);
15417 private String getActiveLauncherPackageName(int userId) {
15418 Intent intent = new Intent(Intent.ACTION_MAIN);
15419 intent.addCategory(Intent.CATEGORY_HOME);
15420 ResolveInfo resolveInfo = resolveIntent(
15422 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
15423 PackageManager.MATCH_DEFAULT_ONLY,
15426 return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
15429 private String getDefaultDialerPackageName(int userId) {
15430 synchronized (mPackages) {
15431 return mSettings.getDefaultDialerPackageNameLPw(userId);
15436 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
15437 mContext.enforceCallingOrSelfPermission(
15438 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
15439 "Only package verification agents can verify applications");
15441 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
15442 final PackageVerificationResponse response = new PackageVerificationResponse(
15443 verificationCode, Binder.getCallingUid());
15445 msg.obj = response;
15446 mHandler.sendMessage(msg);
15450 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
15451 long millisecondsToDelay) {
15452 mContext.enforceCallingOrSelfPermission(
15453 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
15454 "Only package verification agents can extend verification timeouts");
15456 final PackageVerificationState state = mPendingVerification.get(id);
15457 final PackageVerificationResponse response = new PackageVerificationResponse(
15458 verificationCodeAtTimeout, Binder.getCallingUid());
15460 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
15461 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
15463 if (millisecondsToDelay < 0) {
15464 millisecondsToDelay = 0;
15466 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
15467 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
15468 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
15471 if ((state != null) && !state.timeoutExtended()) {
15472 state.extendTimeout();
15474 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
15476 msg.obj = response;
15477 mHandler.sendMessageDelayed(msg, millisecondsToDelay);
15481 private void broadcastPackageVerified(int verificationId, Uri packageUri,
15482 int verificationCode, UserHandle user) {
15483 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
15484 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
15485 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
15486 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
15487 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
15489 mContext.sendBroadcastAsUser(intent, user,
15490 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
15493 private ComponentName matchComponentForVerifier(String packageName,
15494 List<ResolveInfo> receivers) {
15495 ActivityInfo targetReceiver = null;
15497 final int NR = receivers.size();
15498 for (int i = 0; i < NR; i++) {
15499 final ResolveInfo info = receivers.get(i);
15500 if (info.activityInfo == null) {
15504 if (packageName.equals(info.activityInfo.packageName)) {
15505 targetReceiver = info.activityInfo;
15510 if (targetReceiver == null) {
15514 return new ComponentName(targetReceiver.packageName, targetReceiver.name);
15517 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
15518 List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
15519 if (pkgInfo.verifiers.length == 0) {
15523 final int N = pkgInfo.verifiers.length;
15524 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
15525 for (int i = 0; i < N; i++) {
15526 final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
15528 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
15530 if (comp == null) {
15534 final int verifierUid = getUidForVerifier(verifierInfo);
15535 if (verifierUid == -1) {
15539 if (DEBUG_VERIFY) {
15540 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
15541 + " with the correct signature");
15543 sufficientVerifiers.add(comp);
15544 verificationState.addSufficientVerifier(verifierUid);
15547 return sufficientVerifiers;
15550 private int getUidForVerifier(VerifierInfo verifierInfo) {
15551 synchronized (mPackages) {
15552 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
15555 } else if (pkg.mSignatures.length != 1) {
15556 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
15557 + " has more than one signature; ignoring");
15562 * If the public key of the package's signature does not match
15563 * our expected public key, then this is a different package and
15567 final byte[] expectedPublicKey;
15569 final Signature verifierSig = pkg.mSignatures[0];
15570 final PublicKey publicKey = verifierSig.getPublicKey();
15571 expectedPublicKey = publicKey.getEncoded();
15572 } catch (CertificateException e) {
15576 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
15578 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
15579 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
15580 + " does not have the expected public key; ignoring");
15584 return pkg.applicationInfo.uid;
15589 public void finishPackageInstall(int token, boolean didLaunch) {
15590 enforceSystemOrRoot("Only the system is allowed to finish installs");
15592 if (DEBUG_INSTALL) {
15593 Slog.v(TAG, "BM finishing package install for " + token);
15595 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
15597 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
15598 mHandler.sendMessage(msg);
15602 * Get the verification agent timeout. Used for both the APK verifier and the
15603 * intent filter verifier.
15605 * @return verification timeout in milliseconds
15607 private long getVerificationTimeout() {
15608 return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
15609 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
15610 DEFAULT_VERIFICATION_TIMEOUT);
15614 * Get the default verification agent response code.
15616 * @return default verification response code
15618 private int getDefaultVerificationResponse(UserHandle user) {
15619 if (sUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS, user.getIdentifier())) {
15620 return PackageManager.VERIFICATION_REJECT;
15622 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
15623 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
15624 DEFAULT_VERIFICATION_RESPONSE);
15628 * Check whether or not package verification has been enabled.
15630 * @return true if verification should be performed
15632 private boolean isVerificationEnabled(int userId, int installFlags, int installerUid) {
15633 if (!DEFAULT_VERIFY_ENABLE) {
15637 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
15639 // Check if installing from ADB
15640 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
15641 // Do not run verification in a test harness environment
15642 if (ActivityManager.isRunningInTestHarness()) {
15645 if (ensureVerifyAppsEnabled) {
15648 // Check if the developer does not want package verification for ADB installs
15649 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
15650 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
15654 // only when not installed from ADB, skip verification for instant apps when
15655 // the installer and verifier are the same.
15656 if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
15657 if (mInstantAppInstallerActivity != null
15658 && mInstantAppInstallerActivity.packageName.equals(
15659 mRequiredVerifierPackage)) {
15661 mContext.getSystemService(AppOpsManager.class)
15662 .checkPackage(installerUid, mRequiredVerifierPackage);
15663 if (DEBUG_VERIFY) {
15664 Slog.i(TAG, "disable verification for instant app");
15667 } catch (SecurityException ignore) { }
15672 if (ensureVerifyAppsEnabled) {
15676 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
15677 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
15681 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
15682 throws RemoteException {
15683 mContext.enforceCallingOrSelfPermission(
15684 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
15685 "Only intentfilter verification agents can verify applications");
15687 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
15688 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
15689 Binder.getCallingUid(), verificationCode, failedDomains);
15691 msg.obj = response;
15692 mHandler.sendMessage(msg);
15696 public int getIntentVerificationStatus(String packageName, int userId) {
15697 final int callingUid = Binder.getCallingUid();
15698 if (UserHandle.getUserId(callingUid) != userId) {
15699 mContext.enforceCallingOrSelfPermission(
15700 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
15701 "getIntentVerificationStatus" + userId);
15703 if (getInstantAppPackageName(callingUid) != null) {
15704 return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
15706 synchronized (mPackages) {
15707 final PackageSetting ps = mSettings.mPackages.get(packageName);
15709 || filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
15710 return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
15712 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
15717 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
15718 mContext.enforceCallingOrSelfPermission(
15719 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
15721 boolean result = false;
15722 synchronized (mPackages) {
15723 final PackageSetting ps = mSettings.mPackages.get(packageName);
15724 if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
15727 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
15730 scheduleWritePackageRestrictionsLocked(userId);
15736 public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
15737 String packageName) {
15738 final int callingUid = Binder.getCallingUid();
15739 if (getInstantAppPackageName(callingUid) != null) {
15740 return ParceledListSlice.emptyList();
15742 synchronized (mPackages) {
15743 final PackageSetting ps = mSettings.mPackages.get(packageName);
15744 if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
15745 return ParceledListSlice.emptyList();
15747 return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
15752 public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
15753 if (TextUtils.isEmpty(packageName)) {
15754 return ParceledListSlice.emptyList();
15756 final int callingUid = Binder.getCallingUid();
15757 final int callingUserId = UserHandle.getUserId(callingUid);
15758 synchronized (mPackages) {
15759 PackageParser.Package pkg = mPackages.get(packageName);
15760 if (pkg == null || pkg.activities == null) {
15761 return ParceledListSlice.emptyList();
15763 if (pkg.mExtras == null) {
15764 return ParceledListSlice.emptyList();
15766 final PackageSetting ps = (PackageSetting) pkg.mExtras;
15767 if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
15768 return ParceledListSlice.emptyList();
15770 final int count = pkg.activities.size();
15771 ArrayList<IntentFilter> result = new ArrayList<>();
15772 for (int n=0; n<count; n++) {
15773 PackageParser.Activity activity = pkg.activities.get(n);
15774 if (activity.intents != null && activity.intents.size() > 0) {
15775 result.addAll(activity.intents);
15778 return new ParceledListSlice<>(result);
15783 public boolean setDefaultBrowserPackageName(String packageName, int userId) {
15784 mContext.enforceCallingOrSelfPermission(
15785 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
15786 if (UserHandle.getCallingUserId() != userId) {
15787 mContext.enforceCallingOrSelfPermission(
15788 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
15791 synchronized (mPackages) {
15792 boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
15793 if (packageName != null) {
15794 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
15795 packageName, userId);
15802 public String getDefaultBrowserPackageName(int userId) {
15803 if (UserHandle.getCallingUserId() != userId) {
15804 mContext.enforceCallingOrSelfPermission(
15805 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
15807 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
15810 synchronized (mPackages) {
15811 return mSettings.getDefaultBrowserPackageNameLPw(userId);
15816 * Get the "allow unknown sources" setting.
15818 * @return the current "allow unknown sources" setting
15820 private int getUnknownSourcesSettings() {
15821 return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
15822 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
15827 public void setInstallerPackageName(String targetPackage, String installerPackageName) {
15828 final int callingUid = Binder.getCallingUid();
15829 if (getInstantAppPackageName(callingUid) != null) {
15833 synchronized (mPackages) {
15834 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
15835 if (targetPackageSetting == null
15836 || filterAppAccessLPr(
15837 targetPackageSetting, callingUid, UserHandle.getUserId(callingUid))) {
15838 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
15841 PackageSetting installerPackageSetting;
15842 if (installerPackageName != null) {
15843 installerPackageSetting = mSettings.mPackages.get(installerPackageName);
15844 if (installerPackageSetting == null) {
15845 throw new IllegalArgumentException("Unknown installer package: "
15846 + installerPackageName);
15849 installerPackageSetting = null;
15852 Signature[] callerSignature;
15853 Object obj = mSettings.getUserIdLPr(callingUid);
15855 if (obj instanceof SharedUserSetting) {
15856 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
15857 } else if (obj instanceof PackageSetting) {
15858 callerSignature = ((PackageSetting)obj).signatures.mSignatures;
15860 throw new SecurityException("Bad object " + obj + " for uid " + callingUid);
15863 throw new SecurityException("Unknown calling UID: " + callingUid);
15866 // Verify: can't set installerPackageName to a package that is
15867 // not signed with the same cert as the caller.
15868 if (installerPackageSetting != null) {
15869 if (compareSignatures(callerSignature,
15870 installerPackageSetting.signatures.mSignatures)
15871 != PackageManager.SIGNATURE_MATCH) {
15872 throw new SecurityException(
15873 "Caller does not have same cert as new installer package "
15874 + installerPackageName);
15878 // Verify: if target already has an installer package, it must
15879 // be signed with the same cert as the caller.
15880 if (targetPackageSetting.installerPackageName != null) {
15881 PackageSetting setting = mSettings.mPackages.get(
15882 targetPackageSetting.installerPackageName);
15883 // If the currently set package isn't valid, then it's always
15884 // okay to change it.
15885 if (setting != null) {
15886 if (compareSignatures(callerSignature,
15887 setting.signatures.mSignatures)
15888 != PackageManager.SIGNATURE_MATCH) {
15889 throw new SecurityException(
15890 "Caller does not have same cert as old installer package "
15891 + targetPackageSetting.installerPackageName);
15897 targetPackageSetting.installerPackageName = installerPackageName;
15898 if (installerPackageName != null) {
15899 mSettings.mInstallerPackages.add(installerPackageName);
15901 scheduleWriteSettingsLocked();
15906 public void setApplicationCategoryHint(String packageName, int categoryHint,
15907 String callerPackageName) {
15908 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
15909 throw new SecurityException("Instant applications don't have access to this method");
15911 mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
15912 callerPackageName);
15913 synchronized (mPackages) {
15914 PackageSetting ps = mSettings.mPackages.get(packageName);
15916 throw new IllegalArgumentException("Unknown target package " + packageName);
15918 if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
15919 throw new IllegalArgumentException("Unknown target package " + packageName);
15921 if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
15922 throw new IllegalArgumentException("Calling package " + callerPackageName
15923 + " is not installer for " + packageName);
15926 if (ps.categoryHint != categoryHint) {
15927 ps.categoryHint = categoryHint;
15928 scheduleWriteSettingsLocked();
15933 private void processPendingInstall(final InstallArgs args, final int currentStatus) {
15934 // Queue up an async operation since the package installation may take a little while.
15935 mHandler.post(new Runnable() {
15936 public void run() {
15937 mHandler.removeCallbacks(this);
15938 // Result object to be returned
15939 PackageInstalledInfo res = new PackageInstalledInfo();
15940 res.setReturnCode(currentStatus);
15943 res.removedInfo = null;
15944 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
15945 args.doPreInstall(res.returnCode);
15946 synchronized (mInstallLock) {
15947 installPackageTracedLI(args, res);
15949 args.doPostInstall(res.returnCode, res.uid);
15952 // A restore should be performed at this point if (a) the install
15953 // succeeded, (b) the operation is not an update, and (c) the new
15954 // package has not opted out of backup participation.
15955 final boolean update = res.removedInfo != null
15956 && res.removedInfo.removedPackage != null;
15957 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
15958 boolean doRestore = !update
15959 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
15961 // Set up the post-install work request bookkeeping. This will be used
15962 // and cleaned up by the post-install event handling regardless of whether
15963 // there's a restore pass performed. Token values are >= 1.
15965 if (mNextInstallToken < 0) mNextInstallToken = 1;
15966 token = mNextInstallToken++;
15968 PostInstallData data = new PostInstallData(args, res);
15969 mRunningInstalls.put(token, data);
15970 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
15972 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
15973 // Pass responsibility to the Backup Manager. It will perform a
15974 // restore if appropriate, then pass responsibility back to the
15975 // Package Manager to run the post-install observer callbacks
15977 IBackupManager bm = IBackupManager.Stub.asInterface(
15978 ServiceManager.getService(Context.BACKUP_SERVICE));
15980 if (DEBUG_INSTALL) Log.v(TAG, "token " + token
15981 + " to BM for possible restore");
15982 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
15984 // TODO: http://b/22388012
15985 if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
15986 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
15990 } catch (RemoteException e) {
15991 // can't happen; the backup manager is local
15992 } catch (Exception e) {
15993 Slog.e(TAG, "Exception trying to enqueue restore", e);
15997 Slog.e(TAG, "Backup Manager not found!");
16003 // No restore possible, or the Backup Manager was mysteriously not
16004 // available -- just fire the post-install work request directly.
16005 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
16007 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
16009 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
16010 mHandler.sendMessage(msg);
16017 * Callback from PackageSettings whenever an app is first transitioned out of the
16018 * 'stopped' state. Normally we just issue the broadcast, but we can't do that if
16019 * the app was "launched" for a restoreAtInstall operation. Therefore we check
16020 * here whether the app is the target of an ongoing install, and only send the
16021 * broadcast immediately if it is not in that state. If it *is* undergoing a restore,
16022 * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
16025 void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) {
16026 // Serialize this with the rest of the install-process message chain. In the
16027 // restore-at-install case, this Runnable will necessarily run before the
16028 // POST_INSTALL message is processed, so the contents of mRunningInstalls
16029 // are coherent. In the non-restore case, the app has already completed install
16030 // and been launched through some other means, so it is not in a problematic
16031 // state for observers to see the FIRST_LAUNCH signal.
16032 mHandler.post(new Runnable() {
16034 public void run() {
16035 for (int i = 0; i < mRunningInstalls.size(); i++) {
16036 final PostInstallData data = mRunningInstalls.valueAt(i);
16037 if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16040 if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) {
16041 // right package; but is it for the right user?
16042 for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
16043 if (userId == data.res.newUsers[uIndex]) {
16044 if (DEBUG_BACKUP) {
16045 Slog.i(TAG, "Package " + pkgName
16046 + " being restored so deferring FIRST_LAUNCH");
16053 // didn't find it, so not being restored
16054 if (DEBUG_BACKUP) {
16055 Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH");
16057 sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId});
16062 private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) {
16063 sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
16064 installerPkg, null, userIds);
16067 private abstract class HandlerParams {
16068 private static final int MAX_RETRIES = 4;
16071 * Number of times startCopy() has been attempted and had a non-fatal
16074 private int mRetries = 0;
16076 /** User handle for the user requesting the information or installation. */
16077 private final UserHandle mUser;
16078 String traceMethod;
16081 HandlerParams(UserHandle user) {
16085 UserHandle getUser() {
16089 HandlerParams setTraceMethod(String traceMethod) {
16090 this.traceMethod = traceMethod;
16094 HandlerParams setTraceCookie(int traceCookie) {
16095 this.traceCookie = traceCookie;
16099 final boolean startCopy() {
16102 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
16104 if (++mRetries > MAX_RETRIES) {
16105 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
16106 mHandler.sendEmptyMessage(MCS_GIVE_UP);
16107 handleServiceError();
16113 } catch (RemoteException e) {
16114 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
16115 mHandler.sendEmptyMessage(MCS_RECONNECT);
16118 handleReturnCode();
16122 final void serviceError() {
16123 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
16124 handleServiceError();
16125 handleReturnCode();
16128 abstract void handleStartCopy() throws RemoteException;
16129 abstract void handleServiceError();
16130 abstract void handleReturnCode();
16133 private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
16134 for (File path : paths) {
16136 mcs.clearDirectory(path.getAbsolutePath());
16137 } catch (RemoteException e) {
16142 static class OriginInfo {
16144 * Location where install is coming from, before it has been
16145 * copied/renamed into place. This could be a single monolithic APK
16146 * file, or a cluster directory. This location may be untrusted.
16152 * Flag indicating that {@link #file} or {@link #cid} has already been
16153 * staged, meaning downstream users don't need to defensively copy the
16156 final boolean staged;
16159 * Flag indicating that {@link #file} or {@link #cid} is an already
16160 * installed app that is being moved.
16162 final boolean existing;
16164 final String resolvedPath;
16165 final File resolvedFile;
16167 static OriginInfo fromNothing() {
16168 return new OriginInfo(null, null, false, false);
16171 static OriginInfo fromUntrustedFile(File file) {
16172 return new OriginInfo(file, null, false, false);
16175 static OriginInfo fromExistingFile(File file) {
16176 return new OriginInfo(file, null, false, true);
16179 static OriginInfo fromStagedFile(File file) {
16180 return new OriginInfo(file, null, true, false);
16183 static OriginInfo fromStagedContainer(String cid) {
16184 return new OriginInfo(null, cid, true, false);
16187 private OriginInfo(File file, String cid, boolean staged, boolean existing) {
16190 this.staged = staged;
16191 this.existing = existing;
16194 resolvedPath = PackageHelper.getSdDir(cid);
16195 resolvedFile = new File(resolvedPath);
16196 } else if (file != null) {
16197 resolvedPath = file.getAbsolutePath();
16198 resolvedFile = file;
16200 resolvedPath = null;
16201 resolvedFile = null;
16206 static class MoveInfo {
16208 final String fromUuid;
16209 final String toUuid;
16210 final String packageName;
16211 final String dataAppName;
16213 final String seinfo;
16214 final int targetSdkVersion;
16216 public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
16217 String dataAppName, int appId, String seinfo, int targetSdkVersion) {
16218 this.moveId = moveId;
16219 this.fromUuid = fromUuid;
16220 this.toUuid = toUuid;
16221 this.packageName = packageName;
16222 this.dataAppName = dataAppName;
16223 this.appId = appId;
16224 this.seinfo = seinfo;
16225 this.targetSdkVersion = targetSdkVersion;
16229 static class VerificationInfo {
16230 /** A constant used to indicate that a uid value is not present. */
16231 public static final int NO_UID = -1;
16233 /** URI referencing where the package was downloaded from. */
16234 final Uri originatingUri;
16236 /** HTTP referrer URI associated with the originatingURI. */
16237 final Uri referrer;
16239 /** UID of the application that the install request originated from. */
16240 final int originatingUid;
16242 /** UID of application requesting the install */
16243 final int installerUid;
16245 VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
16246 this.originatingUri = originatingUri;
16247 this.referrer = referrer;
16248 this.originatingUid = originatingUid;
16249 this.installerUid = installerUid;
16253 class InstallParams extends HandlerParams {
16254 final OriginInfo origin;
16255 final MoveInfo move;
16256 final IPackageInstallObserver2 observer;
16258 final String installerPackageName;
16259 final String volumeUuid;
16260 private InstallArgs mArgs;
16262 final String packageAbiOverride;
16263 final String[] grantedRuntimePermissions;
16264 final VerificationInfo verificationInfo;
16265 final Certificate[][] certificates;
16266 final int installReason;
16268 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
16269 int installFlags, String installerPackageName, String volumeUuid,
16270 VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
16271 String[] grantedPermissions, Certificate[][] certificates, int installReason) {
16273 this.origin = origin;
16275 this.observer = observer;
16276 this.installFlags = installFlags;
16277 this.installerPackageName = installerPackageName;
16278 this.volumeUuid = volumeUuid;
16279 this.verificationInfo = verificationInfo;
16280 this.packageAbiOverride = packageAbiOverride;
16281 this.grantedRuntimePermissions = grantedPermissions;
16282 this.certificates = certificates;
16283 this.installReason = installReason;
16287 public String toString() {
16288 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
16289 + " file=" + origin.file + " cid=" + origin.cid + "}";
16292 private int installLocationPolicy(PackageInfoLite pkgLite) {
16293 String packageName = pkgLite.packageName;
16294 int installLocation = pkgLite.installLocation;
16295 boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
16297 synchronized (mPackages) {
16298 // Currently installed package which the new package is attempting to replace or
16299 // null if no such package is installed.
16300 PackageParser.Package installedPkg = mPackages.get(packageName);
16301 // Package which currently owns the data which the new package will own if installed.
16302 // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
16303 // will be null whereas dataOwnerPkg will contain information about the package
16304 // which was uninstalled while keeping its data.
16305 PackageParser.Package dataOwnerPkg = installedPkg;
16306 if (dataOwnerPkg == null) {
16307 PackageSetting ps = mSettings.mPackages.get(packageName);
16309 dataOwnerPkg = ps.pkg;
16313 if (dataOwnerPkg != null) {
16314 // If installed, the package will get access to data left on the device by its
16315 // predecessor. As a security measure, this is permited only if this is not a
16316 // version downgrade or if the predecessor package is marked as debuggable and
16317 // a downgrade is explicitly requested.
16319 // On debuggable platform builds, downgrades are permitted even for
16320 // non-debuggable packages to make testing easier. Debuggable platform builds do
16321 // not offer security guarantees and thus it's OK to disable some security
16322 // mechanisms to make debugging/testing easier on those builds. However, even on
16323 // debuggable builds downgrades of packages are permitted only if requested via
16324 // installFlags. This is because we aim to keep the behavior of debuggable
16325 // platform builds as close as possible to the behavior of non-debuggable
16326 // platform builds.
16327 final boolean downgradeRequested =
16328 (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
16329 final boolean packageDebuggable =
16330 (dataOwnerPkg.applicationInfo.flags
16331 & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
16332 final boolean downgradePermitted =
16333 (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
16334 if (!downgradePermitted) {
16336 checkDowngrade(dataOwnerPkg, pkgLite);
16337 } catch (PackageManagerException e) {
16338 Slog.w(TAG, "Downgrade detected: " + e.getMessage());
16339 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
16344 if (installedPkg != null) {
16345 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
16346 // Check for updated system application.
16347 if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
16349 Slog.w(TAG, "Cannot install update to system app on sdcard");
16350 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
16352 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
16355 // Install flag overrides everything.
16356 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
16358 // If current upgrade specifies particular preference
16359 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
16360 // Application explicitly specified internal.
16361 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
16362 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
16363 // App explictly prefers external. Let policy decide
16365 // Prefer previous location
16366 if (isExternal(installedPkg)) {
16367 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
16369 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
16373 // Invalid install. Return error code
16374 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
16378 // All the special cases have been taken care of.
16379 // Return result based on recommended install location.
16381 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
16383 return pkgLite.recommendedInstallLocation;
16387 * Invoke remote method to get package information and install
16388 * location values. Override install location based on default
16389 * policy if needed and then create install arguments based
16390 * on the install location.
16392 public void handleStartCopy() throws RemoteException {
16393 int ret = PackageManager.INSTALL_SUCCEEDED;
16395 // If we're already staged, we've firmly committed to an install location
16396 if (origin.staged) {
16397 if (origin.file != null) {
16398 installFlags |= PackageManager.INSTALL_INTERNAL;
16399 installFlags &= ~PackageManager.INSTALL_EXTERNAL;
16400 } else if (origin.cid != null) {
16401 installFlags |= PackageManager.INSTALL_EXTERNAL;
16402 installFlags &= ~PackageManager.INSTALL_INTERNAL;
16404 throw new IllegalStateException("Invalid stage location");
16408 final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
16409 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
16410 final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
16411 PackageInfoLite pkgLite = null;
16413 if (onInt && onSd) {
16414 // Check if both bits are set.
16415 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
16416 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
16417 } else if (onSd && ephemeral) {
16418 Slog.w(TAG, "Conflicting flags specified for installing ephemeral on external");
16419 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
16421 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
16422 packageAbiOverride);
16424 if (DEBUG_EPHEMERAL && ephemeral) {
16425 Slog.v(TAG, "pkgLite for install: " + pkgLite);
16429 * If we have too little free space, try to free cache
16430 * before giving up.
16432 if (!origin.staged && pkgLite.recommendedInstallLocation
16433 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
16434 // TODO: focus freeing disk space on the target device
16435 final StorageManager storage = StorageManager.from(mContext);
16436 final long lowThreshold = storage.getStorageLowBytes(
16437 Environment.getDataDirectory());
16439 final long sizeBytes = mContainerService.calculateInstalledSize(
16440 origin.resolvedPath, isForwardLocked(), packageAbiOverride);
16443 mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);
16444 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
16445 installFlags, packageAbiOverride);
16446 } catch (InstallerException e) {
16447 Slog.w(TAG, "Failed to free cache", e);
16451 * The cache free must have deleted the file we
16452 * downloaded to install.
16454 * TODO: fix the "freeCache" call to not delete
16455 * the file we care about.
16457 if (pkgLite.recommendedInstallLocation
16458 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
16459 pkgLite.recommendedInstallLocation
16460 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
16465 if (ret == PackageManager.INSTALL_SUCCEEDED) {
16466 int loc = pkgLite.recommendedInstallLocation;
16467 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
16468 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
16469 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
16470 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
16471 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
16472 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
16473 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
16474 ret = PackageManager.INSTALL_FAILED_INVALID_APK;
16475 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
16476 ret = PackageManager.INSTALL_FAILED_INVALID_URI;
16477 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
16478 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
16480 // Override with defaults if needed.
16481 loc = installLocationPolicy(pkgLite);
16482 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
16483 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
16484 } else if (!onSd && !onInt) {
16485 // Override install location with flags
16486 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
16487 // Set the flag to install on external media.
16488 installFlags |= PackageManager.INSTALL_EXTERNAL;
16489 installFlags &= ~PackageManager.INSTALL_INTERNAL;
16490 } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
16491 if (DEBUG_EPHEMERAL) {
16492 Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
16494 installFlags |= PackageManager.INSTALL_INSTANT_APP;
16495 installFlags &= ~(PackageManager.INSTALL_EXTERNAL
16496 |PackageManager.INSTALL_INTERNAL);
16498 // Make sure the flag for installing on external
16500 installFlags |= PackageManager.INSTALL_INTERNAL;
16501 installFlags &= ~PackageManager.INSTALL_EXTERNAL;
16507 final InstallArgs args = createInstallArgs(this);
16510 if (ret == PackageManager.INSTALL_SUCCEEDED) {
16511 // TODO: http://b/22976637
16512 // Apps installed for "all" users use the device owner to verify the app
16513 UserHandle verifierUser = getUser();
16514 if (verifierUser == UserHandle.ALL) {
16515 verifierUser = UserHandle.SYSTEM;
16519 * Determine if we have any installed package verifiers. If we
16520 * do, then we'll defer to them to verify the packages.
16522 final int requiredUid = mRequiredVerifierPackage == null ? -1
16523 : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
16524 verifierUser.getIdentifier());
16525 final int installerUid =
16526 verificationInfo == null ? -1 : verificationInfo.installerUid;
16527 if (!origin.existing && requiredUid != -1
16528 && isVerificationEnabled(
16529 verifierUser.getIdentifier(), installFlags, installerUid)) {
16530 final Intent verification = new Intent(
16531 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
16532 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16533 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
16534 PACKAGE_MIME_TYPE);
16535 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
16537 // Query all live verifiers based on current user state
16538 final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
16539 PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier(),
16540 false /*allowDynamicSplits*/);
16542 if (DEBUG_VERIFY) {
16543 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
16544 + verification.toString() + " with " + pkgLite.verifiers.length
16545 + " optional verifiers");
16548 final int verificationId = mPendingVerificationToken++;
16550 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
16552 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
16553 installerPackageName);
16555 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
16558 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
16559 pkgLite.packageName);
16561 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
16562 pkgLite.versionCode);
16564 if (verificationInfo != null) {
16565 if (verificationInfo.originatingUri != null) {
16566 verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
16567 verificationInfo.originatingUri);
16569 if (verificationInfo.referrer != null) {
16570 verification.putExtra(Intent.EXTRA_REFERRER,
16571 verificationInfo.referrer);
16573 if (verificationInfo.originatingUid >= 0) {
16574 verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
16575 verificationInfo.originatingUid);
16577 if (verificationInfo.installerUid >= 0) {
16578 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
16579 verificationInfo.installerUid);
16583 final PackageVerificationState verificationState = new PackageVerificationState(
16584 requiredUid, args);
16586 mPendingVerification.append(verificationId, verificationState);
16588 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
16589 receivers, verificationState);
16591 DeviceIdleController.LocalService idleController = getDeviceIdleController();
16592 final long idleDuration = getVerificationTimeout();
16595 * If any sufficient verifiers were listed in the package
16596 * manifest, attempt to ask them.
16598 if (sufficientVerifiers != null) {
16599 final int N = sufficientVerifiers.size();
16601 Slog.i(TAG, "Additional verifiers required, but none installed.");
16602 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
16604 for (int i = 0; i < N; i++) {
16605 final ComponentName verifierComponent = sufficientVerifiers.get(i);
16606 idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
16607 verifierComponent.getPackageName(), idleDuration,
16608 verifierUser.getIdentifier(), false, "package verifier");
16610 final Intent sufficientIntent = new Intent(verification);
16611 sufficientIntent.setComponent(verifierComponent);
16612 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
16617 final ComponentName requiredVerifierComponent = matchComponentForVerifier(
16618 mRequiredVerifierPackage, receivers);
16619 if (ret == PackageManager.INSTALL_SUCCEEDED
16620 && mRequiredVerifierPackage != null) {
16621 Trace.asyncTraceBegin(
16622 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
16624 * Send the intent to the required verification agent,
16625 * but only start the verification timeout after the
16626 * target BroadcastReceivers have run.
16628 verification.setComponent(requiredVerifierComponent);
16629 idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
16630 mRequiredVerifierPackage, idleDuration,
16631 verifierUser.getIdentifier(), false, "package verifier");
16632 mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
16633 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
16634 new BroadcastReceiver() {
16636 public void onReceive(Context context, Intent intent) {
16637 final Message msg = mHandler
16638 .obtainMessage(CHECK_PENDING_VERIFICATION);
16639 msg.arg1 = verificationId;
16640 mHandler.sendMessageDelayed(msg, getVerificationTimeout());
16642 }, null, 0, null, null);
16645 * We don't want the copy to proceed until verification
16646 * succeeds, so null out this field.
16652 * No package verification is enabled, so immediately start
16653 * the remote call to initiate copy using temporary file.
16655 ret = args.copyApk(mContainerService, true);
16663 void handleReturnCode() {
16664 // If mArgs is null, then MCS couldn't be reached. When it
16665 // reconnects, it will try again to install. At that point, this
16667 if (mArgs != null) {
16668 processPendingInstall(mArgs, mRet);
16673 void handleServiceError() {
16674 mArgs = createInstallArgs(this);
16675 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
16678 public boolean isForwardLocked() {
16679 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
16684 * Used during creation of InstallArgs
16686 * @param installFlags package installation flags
16687 * @return true if should be installed on external storage
16689 private static boolean installOnExternalAsec(int installFlags) {
16690 if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
16693 if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
16700 * Used during creation of InstallArgs
16702 * @param installFlags package installation flags
16703 * @return true if should be installed as forward locked
16705 private static boolean installForwardLocked(int installFlags) {
16706 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
16709 private InstallArgs createInstallArgs(InstallParams params) {
16710 if (params.move != null) {
16711 return new MoveInstallArgs(params);
16712 } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
16713 return new AsecInstallArgs(params);
16715 return new FileInstallArgs(params);
16720 * Create args that describe an existing installed package. Typically used
16721 * when cleaning up old installs, or used as a move source.
16723 private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
16724 String resourcePath, String[] instructionSets) {
16725 final boolean isInAsec;
16726 if (installOnExternalAsec(installFlags)) {
16727 /* Apps on SD card are always in ASEC containers. */
16729 } else if (installForwardLocked(installFlags)
16730 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
16732 * Forward-locked apps are only in ASEC containers if they're the
16741 return new AsecInstallArgs(codePath, instructionSets,
16742 installOnExternalAsec(installFlags), installForwardLocked(installFlags));
16744 return new FileInstallArgs(codePath, resourcePath, instructionSets);
16748 static abstract class InstallArgs {
16749 /** @see InstallParams#origin */
16750 final OriginInfo origin;
16751 /** @see InstallParams#move */
16752 final MoveInfo move;
16754 final IPackageInstallObserver2 observer;
16755 // Always refers to PackageManager flags only
16756 final int installFlags;
16757 final String installerPackageName;
16758 final String volumeUuid;
16759 final UserHandle user;
16760 final String abiOverride;
16761 final String[] installGrantPermissions;
16762 /** If non-null, drop an async trace when the install completes */
16763 final String traceMethod;
16764 final int traceCookie;
16765 final Certificate[][] certificates;
16766 final int installReason;
16768 // The list of instruction sets supported by this app. This is currently
16769 // only used during the rmdex() phase to clean up resources. We can get rid of this
16770 // if we move dex files under the common app path.
16771 /* nullable */ String[] instructionSets;
16773 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
16774 int installFlags, String installerPackageName, String volumeUuid,
16775 UserHandle user, String[] instructionSets,
16776 String abiOverride, String[] installGrantPermissions,
16777 String traceMethod, int traceCookie, Certificate[][] certificates,
16778 int installReason) {
16779 this.origin = origin;
16781 this.installFlags = installFlags;
16782 this.observer = observer;
16783 this.installerPackageName = installerPackageName;
16784 this.volumeUuid = volumeUuid;
16786 this.instructionSets = instructionSets;
16787 this.abiOverride = abiOverride;
16788 this.installGrantPermissions = installGrantPermissions;
16789 this.traceMethod = traceMethod;
16790 this.traceCookie = traceCookie;
16791 this.certificates = certificates;
16792 this.installReason = installReason;
16795 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
16796 abstract int doPreInstall(int status);
16799 * Rename package into final resting place. All paths on the given
16800 * scanned package should be updated to reflect the rename.
16802 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
16803 abstract int doPostInstall(int status, int uid);
16805 /** @see PackageSettingBase#codePathString */
16806 abstract String getCodePath();
16807 /** @see PackageSettingBase#resourcePathString */
16808 abstract String getResourcePath();
16810 // Need installer lock especially for dex file removal.
16811 abstract void cleanUpResourcesLI();
16812 abstract boolean doPostDeleteLI(boolean delete);
16815 * Called before the source arguments are copied. This is used mostly
16816 * for MoveParams when it needs to read the source file to put it in the
16820 return PackageManager.INSTALL_SUCCEEDED;
16824 * Called after the source arguments are copied. This is used mostly for
16825 * MoveParams when it needs to read the source file to put it in the
16828 int doPostCopy(int uid) {
16829 return PackageManager.INSTALL_SUCCEEDED;
16832 protected boolean isFwdLocked() {
16833 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
16836 protected boolean isExternalAsec() {
16837 return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
16840 protected boolean isEphemeral() {
16841 return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
16844 UserHandle getUser() {
16849 void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
16850 if (!allCodePaths.isEmpty()) {
16851 if (instructionSets == null) {
16852 throw new IllegalStateException("instructionSet == null");
16854 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
16855 for (String codePath : allCodePaths) {
16856 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
16858 mInstaller.rmdex(codePath, dexCodeInstructionSet);
16859 } catch (InstallerException ignored) {
16867 * Logic to handle installation of non-ASEC applications, including copying
16868 * and renaming logic.
16870 class FileInstallArgs extends InstallArgs {
16871 private File codeFile;
16872 private File resourceFile;
16874 // Example topology:
16875 // /data/app/com.example/base.apk
16876 // /data/app/com.example/split_foo.apk
16877 // /data/app/com.example/lib/arm/libfoo.so
16878 // /data/app/com.example/lib/arm64/libfoo.so
16879 // /data/app/com.example/dalvik/arm/base.apk@classes.dex
16882 FileInstallArgs(InstallParams params) {
16883 super(params.origin, params.move, params.observer, params.installFlags,
16884 params.installerPackageName, params.volumeUuid,
16885 params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
16886 params.grantedRuntimePermissions,
16887 params.traceMethod, params.traceCookie, params.certificates,
16888 params.installReason);
16889 if (isFwdLocked()) {
16890 throw new IllegalArgumentException("Forward locking only supported in ASEC");
16894 /** Existing install */
16895 FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
16896 super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
16897 null, null, null, 0, null /*certificates*/,
16898 PackageManager.INSTALL_REASON_UNKNOWN);
16899 this.codeFile = (codePath != null) ? new File(codePath) : null;
16900 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
16903 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
16904 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
16906 return doCopyApk(imcs, temp);
16908 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16912 private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
16913 if (origin.staged) {
16914 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
16915 codeFile = origin.file;
16916 resourceFile = origin.file;
16917 return PackageManager.INSTALL_SUCCEEDED;
16921 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
16922 final File tempDir =
16923 mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
16924 codeFile = tempDir;
16925 resourceFile = tempDir;
16926 } catch (IOException e) {
16927 Slog.w(TAG, "Failed to create copy file: " + e);
16928 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
16931 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
16933 public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
16934 if (!FileUtils.isValidExtFilename(name)) {
16935 throw new IllegalArgumentException("Invalid filename: " + name);
16938 final File file = new File(codeFile, name);
16939 final FileDescriptor fd = Os.open(file.getAbsolutePath(),
16940 O_RDWR | O_CREAT, 0644);
16941 Os.chmod(file.getAbsolutePath(), 0644);
16942 return new ParcelFileDescriptor(fd);
16943 } catch (ErrnoException e) {
16944 throw new RemoteException("Failed to open: " + e.getMessage());
16949 int ret = PackageManager.INSTALL_SUCCEEDED;
16950 ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
16951 if (ret != PackageManager.INSTALL_SUCCEEDED) {
16952 Slog.e(TAG, "Failed to copy package");
16956 final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
16957 NativeLibraryHelper.Handle handle = null;
16959 handle = NativeLibraryHelper.Handle.create(codeFile);
16960 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
16962 } catch (IOException e) {
16963 Slog.e(TAG, "Copying native libraries failed", e);
16964 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
16966 IoUtils.closeQuietly(handle);
16972 int doPreInstall(int status) {
16973 if (status != PackageManager.INSTALL_SUCCEEDED) {
16979 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
16980 if (status != PackageManager.INSTALL_SUCCEEDED) {
16985 final File targetDir = codeFile.getParentFile();
16986 final File beforeCodeFile = codeFile;
16987 final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
16989 if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
16991 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
16992 } catch (ErrnoException e) {
16993 Slog.w(TAG, "Failed to rename", e);
16997 if (!SELinux.restoreconRecursive(afterCodeFile)) {
16998 Slog.w(TAG, "Failed to restorecon");
17001 // Reflect the rename internally
17002 codeFile = afterCodeFile;
17003 resourceFile = afterCodeFile;
17005 // Reflect the rename in scanned details
17006 pkg.setCodePath(afterCodeFile.getAbsolutePath());
17007 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
17008 afterCodeFile, pkg.baseCodePath));
17009 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
17010 afterCodeFile, pkg.splitCodePaths));
17012 // Reflect the rename in app info
17013 pkg.setApplicationVolumeUuid(pkg.volumeUuid);
17014 pkg.setApplicationInfoCodePath(pkg.codePath);
17015 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
17016 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
17017 pkg.setApplicationInfoResourcePath(pkg.codePath);
17018 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
17019 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
17024 int doPostInstall(int status, int uid) {
17025 if (status != PackageManager.INSTALL_SUCCEEDED) {
17032 String getCodePath() {
17033 return (codeFile != null) ? codeFile.getAbsolutePath() : null;
17037 String getResourcePath() {
17038 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
17041 private boolean cleanUp() {
17042 if (codeFile == null || !codeFile.exists()) {
17046 removeCodePathLI(codeFile);
17048 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
17049 resourceFile.delete();
17055 void cleanUpResourcesLI() {
17056 // Try enumerating all code paths before deleting
17057 List<String> allCodePaths = Collections.EMPTY_LIST;
17058 if (codeFile != null && codeFile.exists()) {
17060 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
17061 allCodePaths = pkg.getAllCodePaths();
17062 } catch (PackageParserException e) {
17063 // Ignored; we tried our best
17068 removeDexFiles(allCodePaths, instructionSets);
17071 boolean doPostDeleteLI(boolean delete) {
17072 // XXX err, shouldn't we respect the delete flag?
17073 cleanUpResourcesLI();
17078 private boolean isAsecExternal(String cid) {
17079 final String asecPath = PackageHelper.getSdFilesystem(cid);
17080 return !asecPath.startsWith(mAsecInternalPath);
17083 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
17084 PackageManagerException {
17086 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
17087 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
17088 throw new PackageManagerException(copyRet, message);
17094 * Extract the StorageManagerService "container ID" from the full code path of an
17097 static String cidFromCodePath(String fullCodePath) {
17098 int eidx = fullCodePath.lastIndexOf("/");
17099 String subStr1 = fullCodePath.substring(0, eidx);
17100 int sidx = subStr1.lastIndexOf("/");
17101 return subStr1.substring(sidx+1, eidx);
17105 * Logic to handle installation of ASEC applications, including copying and
17108 class AsecInstallArgs extends InstallArgs {
17109 static final String RES_FILE_NAME = "pkg.apk";
17110 static final String PUBLIC_RES_FILE_NAME = "res.zip";
17113 String packagePath;
17114 String resourcePath;
17117 AsecInstallArgs(InstallParams params) {
17118 super(params.origin, params.move, params.observer, params.installFlags,
17119 params.installerPackageName, params.volumeUuid,
17120 params.getUser(), null /* instruction sets */, params.packageAbiOverride,
17121 params.grantedRuntimePermissions,
17122 params.traceMethod, params.traceCookie, params.certificates,
17123 params.installReason);
17126 /** Existing install */
17127 AsecInstallArgs(String fullCodePath, String[] instructionSets,
17128 boolean isExternal, boolean isForwardLocked) {
17129 super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
17130 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
17131 instructionSets, null, null, null, 0, null /*certificates*/,
17132 PackageManager.INSTALL_REASON_UNKNOWN);
17133 // Hackily pretend we're still looking at a full code path
17134 if (!fullCodePath.endsWith(RES_FILE_NAME)) {
17135 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
17138 // Extract cid from fullCodePath
17139 int eidx = fullCodePath.lastIndexOf("/");
17140 String subStr1 = fullCodePath.substring(0, eidx);
17141 int sidx = subStr1.lastIndexOf("/");
17142 cid = subStr1.substring(sidx+1, eidx);
17143 setMountPath(subStr1);
17146 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
17147 super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
17148 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
17149 instructionSets, null, null, null, 0, null /*certificates*/,
17150 PackageManager.INSTALL_REASON_UNKNOWN);
17152 setMountPath(PackageHelper.getSdDir(cid));
17155 void createCopyFile() {
17156 cid = mInstallerService.allocateExternalStageCidLegacy();
17159 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
17160 if (origin.staged && origin.cid != null) {
17161 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy");
17163 setMountPath(PackageHelper.getSdDir(cid));
17164 return PackageManager.INSTALL_SUCCEEDED;
17171 * Pre-emptively destroy the container since it's destroyed if
17172 * copying fails due to it existing anyway.
17174 PackageHelper.destroySdDir(cid);
17177 final String newMountPath = imcs.copyPackageToContainer(
17178 origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
17179 isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
17181 if (newMountPath != null) {
17182 setMountPath(newMountPath);
17183 return PackageManager.INSTALL_SUCCEEDED;
17185 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
17190 String getCodePath() {
17191 return packagePath;
17195 String getResourcePath() {
17196 return resourcePath;
17199 int doPreInstall(int status) {
17200 if (status != PackageManager.INSTALL_SUCCEEDED) {
17201 // Destroy container
17202 PackageHelper.destroySdDir(cid);
17204 boolean mounted = PackageHelper.isContainerMounted(cid);
17206 String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
17207 Process.SYSTEM_UID);
17208 if (newMountPath != null) {
17209 setMountPath(newMountPath);
17211 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
17218 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
17219 String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
17220 String newMountPath = null;
17221 if (PackageHelper.isContainerMounted(cid)) {
17222 // Unmount the container
17223 if (!PackageHelper.unMountSdDir(cid)) {
17224 Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
17228 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
17229 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
17230 " which might be stale. Will try to clean up.");
17231 // Clean up the stale container and proceed to recreate.
17232 if (!PackageHelper.destroySdDir(newCacheId)) {
17233 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
17236 // Successfully cleaned up stale container. Try to rename again.
17237 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
17238 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
17239 + " inspite of cleaning it up.");
17243 if (!PackageHelper.isContainerMounted(newCacheId)) {
17244 Slog.w(TAG, "Mounting container " + newCacheId);
17245 newMountPath = PackageHelper.mountSdDir(newCacheId,
17246 getEncryptKey(), Process.SYSTEM_UID);
17248 newMountPath = PackageHelper.getSdDir(newCacheId);
17250 if (newMountPath == null) {
17251 Slog.w(TAG, "Failed to get cache path for " + newCacheId);
17254 Log.i(TAG, "Succesfully renamed " + cid +
17255 " to " + newCacheId +
17256 " at new path: " + newMountPath);
17259 final File beforeCodeFile = new File(packagePath);
17260 setMountPath(newMountPath);
17261 final File afterCodeFile = new File(packagePath);
17263 // Reflect the rename in scanned details
17264 pkg.setCodePath(afterCodeFile.getAbsolutePath());
17265 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
17266 afterCodeFile, pkg.baseCodePath));
17267 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
17268 afterCodeFile, pkg.splitCodePaths));
17270 // Reflect the rename in app info
17271 pkg.setApplicationVolumeUuid(pkg.volumeUuid);
17272 pkg.setApplicationInfoCodePath(pkg.codePath);
17273 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
17274 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
17275 pkg.setApplicationInfoResourcePath(pkg.codePath);
17276 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
17277 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
17282 private void setMountPath(String mountPath) {
17283 final File mountFile = new File(mountPath);
17285 final File monolithicFile = new File(mountFile, RES_FILE_NAME);
17286 if (monolithicFile.exists()) {
17287 packagePath = monolithicFile.getAbsolutePath();
17288 if (isFwdLocked()) {
17289 resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
17291 resourcePath = packagePath;
17294 packagePath = mountFile.getAbsolutePath();
17295 resourcePath = packagePath;
17299 int doPostInstall(int status, int uid) {
17300 if (status != PackageManager.INSTALL_SUCCEEDED) {
17303 final int groupOwner;
17304 final String protectedFile;
17305 if (isFwdLocked()) {
17306 groupOwner = UserHandle.getSharedAppGid(uid);
17307 protectedFile = RES_FILE_NAME;
17310 protectedFile = null;
17313 if (uid < Process.FIRST_APPLICATION_UID
17314 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
17315 Slog.e(TAG, "Failed to finalize " + cid);
17316 PackageHelper.destroySdDir(cid);
17317 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
17320 boolean mounted = PackageHelper.isContainerMounted(cid);
17322 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
17328 private void cleanUp() {
17329 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
17331 // Destroy secure container
17332 PackageHelper.destroySdDir(cid);
17335 private List<String> getAllCodePaths() {
17336 final File codeFile = new File(getCodePath());
17337 if (codeFile != null && codeFile.exists()) {
17339 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
17340 return pkg.getAllCodePaths();
17341 } catch (PackageParserException e) {
17342 // Ignored; we tried our best
17345 return Collections.EMPTY_LIST;
17348 void cleanUpResourcesLI() {
17349 // Enumerate all code paths before deleting
17350 cleanUpResourcesLI(getAllCodePaths());
17353 private void cleanUpResourcesLI(List<String> allCodePaths) {
17355 removeDexFiles(allCodePaths, instructionSets);
17358 String getPackageName() {
17359 return getAsecPackageName(cid);
17362 boolean doPostDeleteLI(boolean delete) {
17363 if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
17364 final List<String> allCodePaths = getAllCodePaths();
17365 boolean mounted = PackageHelper.isContainerMounted(cid);
17368 if (PackageHelper.unMountSdDir(cid)) {
17372 if (!mounted && delete) {
17373 cleanUpResourcesLI(allCodePaths);
17380 if (isFwdLocked()) {
17381 if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE,
17382 MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) {
17383 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
17387 return PackageManager.INSTALL_SUCCEEDED;
17391 int doPostCopy(int uid) {
17392 if (isFwdLocked()) {
17393 if (uid < Process.FIRST_APPLICATION_UID
17394 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
17396 Slog.e(TAG, "Failed to finalize " + cid);
17397 PackageHelper.destroySdDir(cid);
17398 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
17402 return PackageManager.INSTALL_SUCCEEDED;
17407 * Logic to handle movement of existing installed applications.
17409 class MoveInstallArgs extends InstallArgs {
17410 private File codeFile;
17411 private File resourceFile;
17414 MoveInstallArgs(InstallParams params) {
17415 super(params.origin, params.move, params.observer, params.installFlags,
17416 params.installerPackageName, params.volumeUuid,
17417 params.getUser(), null /* instruction sets */, params.packageAbiOverride,
17418 params.grantedRuntimePermissions,
17419 params.traceMethod, params.traceCookie, params.certificates,
17420 params.installReason);
17423 int copyApk(IMediaContainerService imcs, boolean temp) {
17424 if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
17425 + move.fromUuid + " to " + move.toUuid);
17426 synchronized (mInstaller) {
17428 mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
17429 move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
17430 } catch (InstallerException e) {
17431 Slog.w(TAG, "Failed to move app", e);
17432 return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
17436 codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
17437 resourceFile = codeFile;
17438 if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
17440 return PackageManager.INSTALL_SUCCEEDED;
17443 int doPreInstall(int status) {
17444 if (status != PackageManager.INSTALL_SUCCEEDED) {
17445 cleanUp(move.toUuid);
17450 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
17451 if (status != PackageManager.INSTALL_SUCCEEDED) {
17452 cleanUp(move.toUuid);
17456 // Reflect the move in app info
17457 pkg.setApplicationVolumeUuid(pkg.volumeUuid);
17458 pkg.setApplicationInfoCodePath(pkg.codePath);
17459 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
17460 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
17461 pkg.setApplicationInfoResourcePath(pkg.codePath);
17462 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
17463 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
17468 int doPostInstall(int status, int uid) {
17469 if (status == PackageManager.INSTALL_SUCCEEDED) {
17470 cleanUp(move.fromUuid);
17472 cleanUp(move.toUuid);
17478 String getCodePath() {
17479 return (codeFile != null) ? codeFile.getAbsolutePath() : null;
17483 String getResourcePath() {
17484 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
17487 private boolean cleanUp(String volumeUuid) {
17488 final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
17490 Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
17491 final int[] userIds = sUserManager.getUserIds();
17492 synchronized (mInstallLock) {
17493 // Clean up both app data and code
17494 // All package moves are frozen until finished
17495 for (int userId : userIds) {
17497 mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
17498 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
17499 } catch (InstallerException e) {
17500 Slog.w(TAG, String.valueOf(e));
17503 removeCodePathLI(codeFile);
17508 void cleanUpResourcesLI() {
17509 throw new UnsupportedOperationException();
17512 boolean doPostDeleteLI(boolean delete) {
17513 throw new UnsupportedOperationException();
17517 static String getAsecPackageName(String packageCid) {
17518 int idx = packageCid.lastIndexOf("-");
17522 return packageCid.substring(0, idx);
17525 // Utility method used to create code paths based on package name and available index.
17526 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
17527 String idxStr = "";
17529 // Fall back to default value of idx=1 if prefix is not
17530 // part of oldCodePath
17531 if (oldCodePath != null) {
17532 String subStr = oldCodePath;
17533 // Drop the suffix right away
17534 if (suffix != null && subStr.endsWith(suffix)) {
17535 subStr = subStr.substring(0, subStr.length() - suffix.length());
17537 // If oldCodePath already contains prefix find out the
17538 // ending index to either increment or decrement.
17539 int sidx = subStr.lastIndexOf(prefix);
17541 subStr = subStr.substring(sidx + prefix.length());
17542 if (subStr != null) {
17543 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
17544 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
17547 idx = Integer.parseInt(subStr);
17553 } catch(NumberFormatException e) {
17558 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
17559 return prefix + idxStr;
17562 private File getNextCodePath(File targetDir, String packageName) {
17564 SecureRandom random = new SecureRandom();
17565 byte[] bytes = new byte[16];
17567 random.nextBytes(bytes);
17568 String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
17569 result = new File(targetDir, packageName + "-" + suffix);
17570 } while (result.exists());
17574 // Utility method that returns the relative package path with respect
17575 // to the installation directory. Like say for /data/data/com.test-1.apk
17576 // string com.test-1 is returned.
17577 static String deriveCodePathName(String codePath) {
17578 if (codePath == null) {
17581 final File codeFile = new File(codePath);
17582 final String name = codeFile.getName();
17583 if (codeFile.isDirectory()) {
17585 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
17586 final int lastDot = name.lastIndexOf('.');
17587 return name.substring(0, lastDot);
17589 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
17594 static class PackageInstalledInfo {
17597 // The set of users that originally had this package installed.
17599 // The set of users that now have this package installed.
17601 PackageParser.Package pkg;
17604 String installerPackageName;
17605 PackageRemovedInfo removedInfo;
17606 ArrayMap<String, PackageInstalledInfo> addedChildPackages;
17608 public void setError(int code, String msg) {
17609 setReturnCode(code);
17610 setReturnMessage(msg);
17614 public void setError(String msg, PackageParserException e) {
17615 setReturnCode(e.error);
17616 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
17617 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
17618 for (int i = 0; i < childCount; i++) {
17619 addedChildPackages.valueAt(i).setError(msg, e);
17621 Slog.w(TAG, msg, e);
17624 public void setError(String msg, PackageManagerException e) {
17625 returnCode = e.error;
17626 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
17627 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
17628 for (int i = 0; i < childCount; i++) {
17629 addedChildPackages.valueAt(i).setError(msg, e);
17631 Slog.w(TAG, msg, e);
17634 public void setReturnCode(int returnCode) {
17635 this.returnCode = returnCode;
17636 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
17637 for (int i = 0; i < childCount; i++) {
17638 addedChildPackages.valueAt(i).returnCode = returnCode;
17642 private void setReturnMessage(String returnMsg) {
17643 this.returnMsg = returnMsg;
17644 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
17645 for (int i = 0; i < childCount; i++) {
17646 addedChildPackages.valueAt(i).returnMsg = returnMsg;
17650 // In some error cases we want to convey more info back to the observer
17651 String origPackage;
17652 String origPermission;
17656 * Install a non-existing package.
17658 private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
17659 int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
17660 PackageInstalledInfo res, int installReason) {
17661 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
17663 // Remember this for later, in case we need to rollback this install
17664 String pkgName = pkg.packageName;
17666 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
17668 synchronized(mPackages) {
17669 final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName);
17670 if (renamedPackage != null) {
17671 // A package with the same name is already installed, though
17672 // it has been renamed to an older name. The package we
17673 // are trying to install should be installed as an update to
17674 // the existing one, but that has not been requested, so bail.
17675 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
17676 + " without first uninstalling package running as "
17680 if (mPackages.containsKey(pkgName)) {
17681 // Don't allow installation over an existing package with the same name.
17682 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
17683 + " without first uninstalling.");
17689 PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
17690 System.currentTimeMillis(), user);
17692 updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
17694 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
17695 prepareAppDataAfterInstallLIF(newPackage);
17698 // Remove package from internal structures, but keep around any
17699 // data that might have already existed
17700 deletePackageLIF(pkgName, UserHandle.ALL, false, null,
17701 PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
17703 } catch (PackageManagerException e) {
17704 res.setError("Package couldn't be installed in " + pkg.codePath, e);
17707 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17710 private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
17711 // Can't rotate keys during boot or if sharedUser.
17712 if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
17713 || !oldPs.keySetData.isUsingUpgradeKeySets()) {
17716 // app is using upgradeKeySets; make sure all are valid
17717 KeySetManagerService ksms = mSettings.mKeySetManagerService;
17718 long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
17719 for (int i = 0; i < upgradeKeySets.length; i++) {
17720 if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
17721 Slog.wtf(TAG, "Package "
17722 + (oldPs.name != null ? oldPs.name : "<null>")
17723 + " contains upgrade-key-set reference to unknown key-set: "
17724 + upgradeKeySets[i]
17725 + " reverting to signatures check.");
17732 private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
17733 // Upgrade keysets are being used. Determine if new package has a superset of the
17735 long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
17736 KeySetManagerService ksms = mSettings.mKeySetManagerService;
17737 for (int i = 0; i < upgradeKeySets.length; i++) {
17738 Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
17739 if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
17746 private static void updateDigest(MessageDigest digest, File file) throws IOException {
17747 try (DigestInputStream digestStream =
17748 new DigestInputStream(new FileInputStream(file), digest)) {
17749 while (digestStream.read() != -1) {} // nothing to do; just plow through the file
17753 private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags,
17754 UserHandle user, String installerPackageName, PackageInstalledInfo res,
17755 int installReason) {
17756 final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
17758 final PackageParser.Package oldPackage;
17759 final PackageSetting ps;
17760 final String pkgName = pkg.packageName;
17761 final int[] allUsers;
17762 final int[] installedUsers;
17764 synchronized(mPackages) {
17765 oldPackage = mPackages.get(pkgName);
17766 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
17768 // don't allow upgrade to target a release SDK from a pre-release SDK
17769 final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
17770 == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
17771 final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
17772 == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
17773 if (oldTargetsPreRelease
17774 && !newTargetsPreRelease
17775 && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
17776 Slog.w(TAG, "Can't install package targeting released sdk");
17777 res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
17781 ps = mSettings.mPackages.get(pkgName);
17783 // verify signatures are valid
17784 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
17785 if (!checkUpgradeKeySetLP(ps, pkg)) {
17786 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
17787 "New package not signed by keys specified by upgrade-keysets: "
17792 // default to original signature matching
17793 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
17794 != PackageManager.SIGNATURE_MATCH) {
17795 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
17796 "New package has a different signature: " + pkgName);
17801 // don't allow a system upgrade unless the upgrade hash matches
17802 if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) {
17803 byte[] digestBytes = null;
17805 final MessageDigest digest = MessageDigest.getInstance("SHA-512");
17806 updateDigest(digest, new File(pkg.baseCodePath));
17807 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
17808 for (String path : pkg.splitCodePaths) {
17809 updateDigest(digest, new File(path));
17812 digestBytes = digest.digest();
17813 } catch (NoSuchAlgorithmException | IOException e) {
17814 res.setError(INSTALL_FAILED_INVALID_APK,
17815 "Could not compute hash: " + pkgName);
17818 if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
17819 res.setError(INSTALL_FAILED_INVALID_APK,
17820 "New package fails restrict-update check: " + pkgName);
17823 // retain upgrade restriction
17824 pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
17827 // Check for shared user id changes
17828 String invalidPackageName =
17829 getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
17830 if (invalidPackageName != null) {
17831 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
17832 "Package " + invalidPackageName + " tried to change user "
17833 + oldPackage.mSharedUserId);
17837 // In case of rollback, remember per-user/profile install state
17838 allUsers = sUserManager.getUserIds();
17839 installedUsers = ps.queryInstalledUsers(allUsers, true);
17841 // don't allow an upgrade from full to ephemeral
17842 if (isInstantApp) {
17843 if (user == null || user.getIdentifier() == UserHandle.USER_ALL) {
17844 for (int currentUser : allUsers) {
17845 if (!ps.getInstantApp(currentUser)) {
17846 // can't downgrade from full to instant
17847 Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
17848 + " for user: " + currentUser);
17849 res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
17853 } else if (!ps.getInstantApp(user.getIdentifier())) {
17854 // can't downgrade from full to instant
17855 Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
17856 + " for user: " + user.getIdentifier());
17857 res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
17863 // Update what is removed
17864 res.removedInfo = new PackageRemovedInfo(this);
17865 res.removedInfo.uid = oldPackage.applicationInfo.uid;
17866 res.removedInfo.removedPackage = oldPackage.packageName;
17867 res.removedInfo.installerPackageName = ps.installerPackageName;
17868 res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
17869 res.removedInfo.isUpdate = true;
17870 res.removedInfo.origUsers = installedUsers;
17871 res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
17872 for (int i = 0; i < installedUsers.length; i++) {
17873 final int userId = installedUsers[i];
17874 res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
17877 final int childCount = (oldPackage.childPackages != null)
17878 ? oldPackage.childPackages.size() : 0;
17879 for (int i = 0; i < childCount; i++) {
17880 boolean childPackageUpdated = false;
17881 PackageParser.Package childPkg = oldPackage.childPackages.get(i);
17882 final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17883 if (res.addedChildPackages != null) {
17884 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
17885 if (childRes != null) {
17886 childRes.removedInfo.uid = childPkg.applicationInfo.uid;
17887 childRes.removedInfo.removedPackage = childPkg.packageName;
17888 if (childPs != null) {
17889 childRes.removedInfo.installerPackageName = childPs.installerPackageName;
17891 childRes.removedInfo.isUpdate = true;
17892 childRes.removedInfo.installReasons = res.removedInfo.installReasons;
17893 childPackageUpdated = true;
17896 if (!childPackageUpdated) {
17897 PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
17898 childRemovedRes.removedPackage = childPkg.packageName;
17899 if (childPs != null) {
17900 childRemovedRes.installerPackageName = childPs.installerPackageName;
17902 childRemovedRes.isUpdate = false;
17903 childRemovedRes.dataRemoved = true;
17904 synchronized (mPackages) {
17905 if (childPs != null) {
17906 childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
17909 if (res.removedInfo.removedChildPackages == null) {
17910 res.removedInfo.removedChildPackages = new ArrayMap<>();
17912 res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
17916 boolean sysPkg = (isSystemApp(oldPackage));
17918 // Set the system/privileged flags as needed
17919 final boolean privileged =
17920 (oldPackage.applicationInfo.privateFlags
17921 & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
17922 final int systemPolicyFlags = policyFlags
17923 | PackageParser.PARSE_IS_SYSTEM
17924 | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0);
17926 replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags,
17927 user, allUsers, installerPackageName, res, installReason);
17929 replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags,
17930 user, allUsers, installerPackageName, res, installReason);
17935 public List<String> getPreviousCodePaths(String packageName) {
17936 final int callingUid = Binder.getCallingUid();
17937 final List<String> result = new ArrayList<>();
17938 if (getInstantAppPackageName(callingUid) != null) {
17941 final PackageSetting ps = mSettings.mPackages.get(packageName);
17943 && ps.oldCodePaths != null
17944 && !filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
17945 result.addAll(ps.oldCodePaths);
17950 private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
17951 PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
17952 int[] allUsers, String installerPackageName, PackageInstalledInfo res,
17953 int installReason) {
17954 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
17957 String pkgName = deletedPackage.packageName;
17958 boolean deletedPkg = true;
17959 boolean addedPkg = false;
17960 boolean updatedSettings = false;
17961 final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
17962 final int deleteFlags = PackageManager.DELETE_KEEP_DATA
17963 | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
17965 final long origUpdateTime = (pkg.mExtras != null)
17966 ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
17968 // First delete the existing package while retaining the data directory
17969 if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
17970 res.removedInfo, true, pkg)) {
17971 // If the existing package wasn't successfully deleted
17972 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
17973 deletedPkg = false;
17975 // Successfully deleted the old package; proceed with replace.
17977 // If deleted package lived in a container, give users a chance to
17978 // relinquish resources before killing.
17979 if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
17980 if (DEBUG_INSTALL) {
17981 Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
17983 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
17984 final ArrayList<String> pkgList = new ArrayList<String>(1);
17985 pkgList.add(deletedPackage.applicationInfo.packageName);
17986 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
17989 clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
17990 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
17991 clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
17994 final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags,
17995 scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
17996 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
17999 // Update the in-memory copy of the previous code paths.
18000 PackageSetting ps = mSettings.mPackages.get(pkgName);
18002 if (ps.oldCodePaths == null) {
18003 ps.oldCodePaths = new ArraySet<>();
18005 Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
18006 if (deletedPackage.splitCodePaths != null) {
18007 Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
18010 ps.oldCodePaths = null;
18012 if (ps.childPackageNames != null) {
18013 for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
18014 final String childPkgName = ps.childPackageNames.get(i);
18015 final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
18016 childPs.oldCodePaths = ps.oldCodePaths;
18019 // set instant app status, but, only if it's explicitly specified
18020 final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
18021 final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
18022 setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp);
18023 prepareAppDataAfterInstallLIF(newPackage);
18025 mDexManager.notifyPackageUpdated(newPackage.packageName,
18026 newPackage.baseCodePath, newPackage.splitCodePaths);
18027 } catch (PackageManagerException e) {
18028 res.setError("Package couldn't be installed in " + pkg.codePath, e);
18032 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
18033 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
18035 // Revert all internal state mutations and added folders for the failed install
18037 deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
18038 res.removedInfo, true, null);
18041 // Restore the old package
18043 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
18044 File restoreFile = new File(deletedPackage.codePath);
18045 // Parse old package
18046 boolean oldExternal = isExternal(deletedPackage);
18047 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY |
18048 (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
18049 (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
18050 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
18052 scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
18054 } catch (PackageManagerException e) {
18055 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
18060 synchronized (mPackages) {
18061 // Ensure the installer package name up to date
18062 setInstallerPackageNameLPw(deletedPackage, installerPackageName);
18064 // Update permissions for restored package
18065 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
18067 mSettings.writeLPr();
18070 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
18073 synchronized (mPackages) {
18074 PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);
18076 res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
18077 if (res.removedInfo.removedChildPackages != null) {
18078 final int childCount = res.removedInfo.removedChildPackages.size();
18079 // Iterate in reverse as we may modify the collection
18080 for (int i = childCount - 1; i >= 0; i--) {
18081 String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
18082 if (res.addedChildPackages.containsKey(childPackageName)) {
18083 res.removedInfo.removedChildPackages.removeAt(i);
18085 PackageRemovedInfo childInfo = res.removedInfo
18086 .removedChildPackages.valueAt(i);
18087 childInfo.removedForAllUsers = mPackages.get(
18088 childInfo.removedPackage) == null;
18097 private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
18098 PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
18099 int[] allUsers, String installerPackageName, PackageInstalledInfo res,
18100 int installReason) {
18101 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
18102 + ", old=" + deletedPackage);
18104 final boolean disabledSystem;
18106 // Remove existing system package
18107 removePackageLI(deletedPackage, true);
18109 synchronized (mPackages) {
18110 disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
18112 if (!disabledSystem) {
18113 // We didn't need to disable the .apk as a current system package,
18114 // which means we are replacing another update that is already
18115 // installed. We need to make sure to delete the older one's .apk.
18116 res.removedInfo.args = createInstallArgsForExisting(0,
18117 deletedPackage.applicationInfo.getCodePath(),
18118 deletedPackage.applicationInfo.getResourcePath(),
18119 getAppDexInstructionSets(deletedPackage.applicationInfo));
18121 res.removedInfo.args = null;
18124 // Successfully disabled the old package. Now proceed with re-installation
18125 clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
18126 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
18127 clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
18129 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
18130 pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
18131 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
18133 PackageParser.Package newPackage = null;
18135 // Add the package to the internal data structures
18136 newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user);
18138 // Set the update and install times
18139 PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
18140 setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
18141 System.currentTimeMillis());
18143 // Update the package dynamic state if succeeded
18144 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
18145 // Now that the install succeeded make sure we remove data
18146 // directories for any child package the update removed.
18147 final int deletedChildCount = (deletedPackage.childPackages != null)
18148 ? deletedPackage.childPackages.size() : 0;
18149 final int newChildCount = (newPackage.childPackages != null)
18150 ? newPackage.childPackages.size() : 0;
18151 for (int i = 0; i < deletedChildCount; i++) {
18152 PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
18153 boolean childPackageDeleted = true;
18154 for (int j = 0; j < newChildCount; j++) {
18155 PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
18156 if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
18157 childPackageDeleted = false;
18161 if (childPackageDeleted) {
18162 PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
18163 deletedChildPkg.packageName);
18164 if (ps != null && res.removedInfo.removedChildPackages != null) {
18165 PackageRemovedInfo removedChildRes = res.removedInfo
18166 .removedChildPackages.get(deletedChildPkg.packageName);
18167 removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
18168 removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
18173 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
18175 prepareAppDataAfterInstallLIF(newPackage);
18177 mDexManager.notifyPackageUpdated(newPackage.packageName,
18178 newPackage.baseCodePath, newPackage.splitCodePaths);
18180 } catch (PackageManagerException e) {
18181 res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
18182 res.setError("Package couldn't be installed in " + pkg.codePath, e);
18185 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
18186 // Re installation failed. Restore old information
18187 // Remove new pkg information
18188 if (newPackage != null) {
18189 removeInstalledPackageLI(newPackage, true);
18191 // Add back the old system package
18193 scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user);
18194 } catch (PackageManagerException e) {
18195 Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
18198 synchronized (mPackages) {
18199 if (disabledSystem) {
18200 enableSystemPackageLPw(deletedPackage);
18203 // Ensure the installer package name up to date
18204 setInstallerPackageNameLPw(deletedPackage, installerPackageName);
18206 // Update permissions for restored package
18207 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
18209 mSettings.writeLPr();
18212 Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
18213 + " after failed upgrade");
18218 * Checks whether the parent or any of the child packages have a change shared
18219 * user. For a package to be a valid update the shred users of the parent and
18220 * the children should match. We may later support changing child shared users.
18221 * @param oldPkg The updated package.
18222 * @param newPkg The update package.
18223 * @return The shared user that change between the versions.
18225 private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
18226 PackageParser.Package newPkg) {
18227 // Check parent shared user
18228 if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
18229 return newPkg.packageName;
18231 // Check child shared users
18232 final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
18233 final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
18234 for (int i = 0; i < newChildCount; i++) {
18235 PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
18236 // If this child was present, did it have the same shared user?
18237 for (int j = 0; j < oldChildCount; j++) {
18238 PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
18239 if (newChildPkg.packageName.equals(oldChildPkg.packageName)
18240 && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
18241 return newChildPkg.packageName;
18248 private void removeNativeBinariesLI(PackageSetting ps) {
18249 // Remove the lib path for the parent package
18251 NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
18252 // Remove the lib path for the child packages
18253 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
18254 for (int i = 0; i < childCount; i++) {
18255 PackageSetting childPs = null;
18256 synchronized (mPackages) {
18257 childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
18259 if (childPs != null) {
18260 NativeLibraryHelper.removeNativeBinariesLI(childPs
18261 .legacyNativeLibraryPathString);
18267 private void enableSystemPackageLPw(PackageParser.Package pkg) {
18268 // Enable the parent package
18269 mSettings.enableSystemPackageLPw(pkg.packageName);
18270 // Enable the child packages
18271 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
18272 for (int i = 0; i < childCount; i++) {
18273 PackageParser.Package childPkg = pkg.childPackages.get(i);
18274 mSettings.enableSystemPackageLPw(childPkg.packageName);
18278 private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
18279 PackageParser.Package newPkg) {
18280 // Disable the parent package (parent always replaced)
18281 boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
18282 // Disable the child packages
18283 final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
18284 for (int i = 0; i < childCount; i++) {
18285 PackageParser.Package childPkg = oldPkg.childPackages.get(i);
18286 final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
18287 disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
18292 private void setInstallerPackageNameLPw(PackageParser.Package pkg,
18293 String installerPackageName) {
18294 // Enable the parent package
18295 mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
18296 // Enable the child packages
18297 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
18298 for (int i = 0; i < childCount; i++) {
18299 PackageParser.Package childPkg = pkg.childPackages.get(i);
18300 mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
18304 private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
18305 // Collect all used permissions in the UID
18306 ArraySet<String> usedPermissions = new ArraySet<>();
18307 final int packageCount = su.packages.size();
18308 for (int i = 0; i < packageCount; i++) {
18309 PackageSetting ps = su.packages.valueAt(i);
18310 if (ps.pkg == null) {
18313 final int requestedPermCount = ps.pkg.requestedPermissions.size();
18314 for (int j = 0; j < requestedPermCount; j++) {
18315 String permission = ps.pkg.requestedPermissions.get(j);
18316 BasePermission bp = mSettings.mPermissions.get(permission);
18318 usedPermissions.add(permission);
18323 PermissionsState permissionsState = su.getPermissionsState();
18324 // Prune install permissions
18325 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
18326 final int installPermCount = installPermStates.size();
18327 for (int i = installPermCount - 1; i >= 0; i--) {
18328 PermissionState permissionState = installPermStates.get(i);
18329 if (!usedPermissions.contains(permissionState.getName())) {
18330 BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
18332 permissionsState.revokeInstallPermission(bp);
18333 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
18334 PackageManager.MASK_PERMISSION_FLAGS, 0);
18339 int[] runtimePermissionChangedUserIds = EmptyArray.INT;
18341 // Prune runtime permissions
18342 for (int userId : allUserIds) {
18343 List<PermissionState> runtimePermStates = permissionsState
18344 .getRuntimePermissionStates(userId);
18345 final int runtimePermCount = runtimePermStates.size();
18346 for (int i = runtimePermCount - 1; i >= 0; i--) {
18347 PermissionState permissionState = runtimePermStates.get(i);
18348 if (!usedPermissions.contains(permissionState.getName())) {
18349 BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
18351 permissionsState.revokeRuntimePermission(bp, userId);
18352 permissionsState.updatePermissionFlags(bp, userId,
18353 PackageManager.MASK_PERMISSION_FLAGS, 0);
18354 runtimePermissionChangedUserIds = ArrayUtils.appendInt(
18355 runtimePermissionChangedUserIds, userId);
18361 return runtimePermissionChangedUserIds;
18364 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
18365 int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
18366 // Update the parent package setting
18367 updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
18368 res, user, installReason);
18369 // Update the child packages setting
18370 final int childCount = (newPackage.childPackages != null)
18371 ? newPackage.childPackages.size() : 0;
18372 for (int i = 0; i < childCount; i++) {
18373 PackageParser.Package childPackage = newPackage.childPackages.get(i);
18374 PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
18375 updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
18376 childRes.origUsers, childRes, user, installReason);
18380 private void updateSettingsInternalLI(PackageParser.Package newPackage,
18381 String installerPackageName, int[] allUsers, int[] installedForUsers,
18382 PackageInstalledInfo res, UserHandle user, int installReason) {
18383 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
18385 String pkgName = newPackage.packageName;
18386 synchronized (mPackages) {
18387 //write settings. the installStatus will be incomplete at this stage.
18388 //note that the new package setting would have already been
18389 //added to mPackages. It hasn't been persisted yet.
18390 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
18391 // TODO: Remove this write? It's also written at the end of this method
18392 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
18393 mSettings.writeLPr();
18394 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18397 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
18398 synchronized (mPackages) {
18399 updatePermissionsLPw(newPackage.packageName, newPackage,
18400 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
18401 ? UPDATE_PERMISSIONS_ALL : 0));
18402 // For system-bundled packages, we assume that installing an upgraded version
18403 // of the package implies that the user actually wants to run that new code,
18404 // so we enable the package.
18405 PackageSetting ps = mSettings.mPackages.get(pkgName);
18406 final int userId = user.getIdentifier();
18408 if (isSystemApp(newPackage)) {
18409 if (DEBUG_INSTALL) {
18410 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
18412 // Enable system package for requested users
18413 if (res.origUsers != null) {
18414 for (int origUserId : res.origUsers) {
18415 if (userId == UserHandle.USER_ALL || userId == origUserId) {
18416 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
18417 origUserId, installerPackageName);
18421 // Also convey the prior install/uninstall state
18422 if (allUsers != null && installedForUsers != null) {
18423 for (int currentUserId : allUsers) {
18424 final boolean installed = ArrayUtils.contains(
18425 installedForUsers, currentUserId);
18426 if (DEBUG_INSTALL) {
18427 Slog.d(TAG, " user " + currentUserId + " => " + installed);
18429 ps.setInstalled(installed, currentUserId);
18431 // these install state changes will be persisted in the
18432 // upcoming call to mSettings.writeLPr().
18435 // It's implied that when a user requests installation, they want the app to be
18436 // installed and enabled.
18437 if (userId != UserHandle.USER_ALL) {
18438 ps.setInstalled(true, userId);
18439 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
18442 // When replacing an existing package, preserve the original install reason for all
18443 // users that had the package installed before.
18444 final Set<Integer> previousUserIds = new ArraySet<>();
18445 if (res.removedInfo != null && res.removedInfo.installReasons != null) {
18446 final int installReasonCount = res.removedInfo.installReasons.size();
18447 for (int i = 0; i < installReasonCount; i++) {
18448 final int previousUserId = res.removedInfo.installReasons.keyAt(i);
18449 final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
18450 ps.setInstallReason(previousInstallReason, previousUserId);
18451 previousUserIds.add(previousUserId);
18455 // Set install reason for users that are having the package newly installed.
18456 if (userId == UserHandle.USER_ALL) {
18457 for (int currentUserId : sUserManager.getUserIds()) {
18458 if (!previousUserIds.contains(currentUserId)) {
18459 ps.setInstallReason(installReason, currentUserId);
18462 } else if (!previousUserIds.contains(userId)) {
18463 ps.setInstallReason(installReason, userId);
18465 mSettings.writeKernelMappingLPr(ps);
18467 res.name = pkgName;
18468 res.uid = newPackage.applicationInfo.uid;
18469 res.pkg = newPackage;
18470 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
18471 mSettings.setInstallerPackageName(pkgName, installerPackageName);
18472 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
18473 //to update install status
18474 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
18475 mSettings.writeLPr();
18476 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18479 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18482 private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
18484 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
18485 installPackageLI(args, res);
18487 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18491 private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
18492 final int installFlags = args.installFlags;
18493 final String installerPackageName = args.installerPackageName;
18494 final String volumeUuid = args.volumeUuid;
18495 final File tmpPackageFile = new File(args.getCodePath());
18496 final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
18497 final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
18498 || (args.volumeUuid != null));
18499 final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
18500 final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
18501 final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
18502 final boolean virtualPreload =
18503 ((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
18504 boolean replace = false;
18505 int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
18506 if (args.move != null) {
18507 // moving a complete application; perform an initial scan on the new install location
18508 scanFlags |= SCAN_INITIAL;
18510 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
18511 scanFlags |= SCAN_DONT_KILL_APP;
18514 scanFlags |= SCAN_AS_INSTANT_APP;
18517 scanFlags |= SCAN_AS_FULL_APP;
18519 if (virtualPreload) {
18520 scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
18523 // Result object to be returned
18524 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
18525 res.installerPackageName = installerPackageName;
18527 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
18530 if (instantApp && (forwardLocked || onExternal)) {
18531 Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
18532 + " external=" + onExternal);
18533 res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
18537 // Retrieve PackageSettings and parse package
18538 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
18539 | PackageParser.PARSE_ENFORCE_CODE
18540 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
18541 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
18542 | (instantApp ? PackageParser.PARSE_IS_EPHEMERAL : 0)
18543 | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
18544 PackageParser pp = new PackageParser();
18545 pp.setSeparateProcesses(mSeparateProcesses);
18546 pp.setDisplayMetrics(mMetrics);
18547 pp.setCallback(mPackageParserCallback);
18549 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
18550 final PackageParser.Package pkg;
18552 pkg = pp.parsePackage(tmpPackageFile, parseFlags);
18553 } catch (PackageParserException e) {
18554 res.setError("Failed parse during installPackageLI", e);
18557 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18560 // Instant apps must have target SDK >= O and have targetSanboxVersion >= 2
18561 if (instantApp && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
18562 Slog.w(TAG, "Instant app package " + pkg.packageName + " does not target O");
18563 res.setError(INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
18564 "Instant app package must target O");
18567 if (instantApp && pkg.applicationInfo.targetSandboxVersion != 2) {
18568 Slog.w(TAG, "Instant app package " + pkg.packageName
18569 + " does not target targetSandboxVersion 2");
18570 res.setError(INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
18571 "Instant app package must use targetSanboxVersion 2");
18575 if (pkg.applicationInfo.isStaticSharedLibrary()) {
18576 // Static shared libraries have synthetic package names
18577 renameStaticSharedLibraryPackage(pkg);
18579 // No static shared libs on external storage
18581 Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
18582 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
18583 "Packages declaring static-shared libs cannot be updated");
18588 // If we are installing a clustered package add results for the children
18589 if (pkg.childPackages != null) {
18590 synchronized (mPackages) {
18591 final int childCount = pkg.childPackages.size();
18592 for (int i = 0; i < childCount; i++) {
18593 PackageParser.Package childPkg = pkg.childPackages.get(i);
18594 PackageInstalledInfo childRes = new PackageInstalledInfo();
18595 childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
18596 childRes.pkg = childPkg;
18597 childRes.name = childPkg.packageName;
18598 PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
18599 if (childPs != null) {
18600 childRes.origUsers = childPs.queryInstalledUsers(
18601 sUserManager.getUserIds(), true);
18603 if ((mPackages.containsKey(childPkg.packageName))) {
18604 childRes.removedInfo = new PackageRemovedInfo(this);
18605 childRes.removedInfo.removedPackage = childPkg.packageName;
18606 childRes.removedInfo.installerPackageName = childPs.installerPackageName;
18608 if (res.addedChildPackages == null) {
18609 res.addedChildPackages = new ArrayMap<>();
18611 res.addedChildPackages.put(childPkg.packageName, childRes);
18616 // If package doesn't declare API override, mark that we have an install
18617 // time CPU ABI override.
18618 if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
18619 pkg.cpuAbiOverride = args.abiOverride;
18622 String pkgName = res.name = pkg.packageName;
18623 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
18624 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
18625 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
18631 // either use what we've been given or parse directly from the APK
18632 if (args.certificates != null) {
18634 PackageParser.populateCertificates(pkg, args.certificates);
18635 } catch (PackageParserException e) {
18636 // there was something wrong with the certificates we were given;
18637 // try to pull them from the APK
18638 PackageParser.collectCertificates(pkg, parseFlags);
18641 PackageParser.collectCertificates(pkg, parseFlags);
18643 } catch (PackageParserException e) {
18644 res.setError("Failed collect during installPackageLI", e);
18648 // Get rid of all references to package scan path via parser.
18650 String oldCodePath = null;
18651 boolean systemApp = false;
18652 synchronized (mPackages) {
18653 // Check if installing already existing package
18654 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
18655 String oldName = mSettings.getRenamedPackageLPr(pkgName);
18656 if (pkg.mOriginalPackages != null
18657 && pkg.mOriginalPackages.contains(oldName)
18658 && mPackages.containsKey(oldName)) {
18659 // This package is derived from an original package,
18660 // and this device has been updating from that original
18661 // name. We must continue using the original name, so
18662 // rename the new package here.
18663 pkg.setPackageName(oldName);
18664 pkgName = pkg.packageName;
18666 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
18667 + oldName + " pkgName=" + pkgName);
18668 } else if (mPackages.containsKey(pkgName)) {
18669 // This package, under its official name, already exists
18670 // on the device; we should replace it.
18672 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
18675 // Child packages are installed through the parent package
18676 if (pkg.parentPackage != null) {
18677 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
18678 "Package " + pkg.packageName + " is child of package "
18679 + pkg.parentPackage.parentPackage + ". Child packages "
18680 + "can be updated only through the parent package.");
18685 // Prevent apps opting out from runtime permissions
18686 PackageParser.Package oldPackage = mPackages.get(pkgName);
18687 final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
18688 final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
18689 if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
18690 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
18691 res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
18692 "Package " + pkg.packageName + " new target SDK " + newTargetSdk
18693 + " doesn't support runtime permissions but the old"
18694 + " target SDK " + oldTargetSdk + " does.");
18697 // Prevent apps from downgrading their targetSandbox.
18698 final int oldTargetSandbox = oldPackage.applicationInfo.targetSandboxVersion;
18699 final int newTargetSandbox = pkg.applicationInfo.targetSandboxVersion;
18700 if (oldTargetSandbox == 2 && newTargetSandbox != 2) {
18701 res.setError(PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
18702 "Package " + pkg.packageName + " new target sandbox "
18703 + newTargetSandbox + " is incompatible with the previous value of"
18704 + oldTargetSandbox + ".");
18708 // Prevent installing of child packages
18709 if (oldPackage.parentPackage != null) {
18710 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
18711 "Package " + pkg.packageName + " is child of package "
18712 + oldPackage.parentPackage + ". Child packages "
18713 + "can be updated only through the parent package.");
18719 PackageSetting ps = mSettings.mPackages.get(pkgName);
18721 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
18723 // Static shared libs have same package with different versions where
18724 // we internally use a synthetic package name to allow multiple versions
18725 // of the same package, therefore we need to compare signatures against
18726 // the package setting for the latest library version.
18727 PackageSetting signatureCheckPs = ps;
18728 if (pkg.applicationInfo.isStaticSharedLibrary()) {
18729 SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
18730 if (libraryEntry != null) {
18731 signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
18735 // Quick sanity check that we're signed correctly if updating;
18736 // we'll check this again later when scanning, but we want to
18737 // bail early here before tripping over redefined permissions.
18738 if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
18739 if (!checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
18740 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
18741 + pkg.packageName + " upgrade keys do not match the "
18742 + "previously installed version");
18747 verifySignaturesLP(signatureCheckPs, pkg);
18748 } catch (PackageManagerException e) {
18749 res.setError(e.error, e.getMessage());
18754 oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
18755 if (ps.pkg != null && ps.pkg.applicationInfo != null) {
18756 systemApp = (ps.pkg.applicationInfo.flags &
18757 ApplicationInfo.FLAG_SYSTEM) != 0;
18759 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
18762 int N = pkg.permissions.size();
18763 for (int i = N-1; i >= 0; i--) {
18764 PackageParser.Permission perm = pkg.permissions.get(i);
18765 BasePermission bp = mSettings.mPermissions.get(perm.info.name);
18767 // Don't allow anyone but the system to define ephemeral permissions.
18768 if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0
18770 Slog.w(TAG, "Non-System package " + pkg.packageName
18771 + " attempting to delcare ephemeral permission "
18772 + perm.info.name + "; Removing ephemeral.");
18773 perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_INSTANT;
18775 // Check whether the newly-scanned package wants to define an already-defined perm
18777 // If the defining package is signed with our cert, it's okay. This
18778 // also includes the "updating the same package" case, of course.
18779 // "updating same package" could also involve key-rotation.
18780 final boolean sigsOk;
18781 if (bp.sourcePackage.equals(pkg.packageName)
18782 && (bp.packageSetting instanceof PackageSetting)
18783 && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting,
18785 sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
18787 sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
18788 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
18791 // If the owning package is the system itself, we log but allow
18792 // install to proceed; we fail the install on all other permission
18794 if (!bp.sourcePackage.equals("android")) {
18795 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
18796 + pkg.packageName + " attempting to redeclare permission "
18797 + perm.info.name + " already owned by " + bp.sourcePackage);
18798 res.origPermission = perm.info.name;
18799 res.origPackage = bp.sourcePackage;
18802 Slog.w(TAG, "Package " + pkg.packageName
18803 + " attempting to redeclare system permission "
18804 + perm.info.name + "; ignoring new declaration");
18805 pkg.permissions.remove(i);
18807 } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
18808 // Prevent apps to change protection level to dangerous from any other
18809 // type as this would allow a privilege escalation where an app adds a
18810 // normal/signature permission in other app's group and later redefines
18811 // it as dangerous leading to the group auto-grant.
18812 if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
18813 == PermissionInfo.PROTECTION_DANGEROUS) {
18814 if (bp != null && !bp.isRuntime()) {
18815 Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
18816 + "non-runtime permission " + perm.info.name
18817 + " to runtime; keeping old protection level");
18818 perm.info.protectionLevel = bp.protectionLevel;
18828 // Abort update; system app can't be replaced with app on sdcard
18829 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
18830 "Cannot install updates to system apps on sdcard");
18832 } else if (instantApp) {
18833 // Abort update; system app can't be replaced with an instant app
18834 res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
18835 "Cannot update a system app with an instant app");
18840 if (args.move != null) {
18841 // We did an in-place move, so dex is ready to roll
18842 scanFlags |= SCAN_NO_DEX;
18843 scanFlags |= SCAN_MOVE;
18845 synchronized (mPackages) {
18846 final PackageSetting ps = mSettings.mPackages.get(pkgName);
18848 res.setError(INSTALL_FAILED_INTERNAL_ERROR,
18849 "Missing settings for moved package " + pkgName);
18852 // We moved the entire application as-is, so bring over the
18853 // previously derived ABI information.
18854 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
18855 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
18858 } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
18859 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
18860 scanFlags |= SCAN_NO_DEX;
18863 String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
18864 args.abiOverride : pkg.cpuAbiOverride);
18865 final boolean extractNativeLibs = !pkg.isLibrary();
18866 derivePackageAbi(pkg, new File(pkg.codePath), abiOverride,
18867 extractNativeLibs, mAppLib32InstallDir);
18868 } catch (PackageManagerException pme) {
18869 Slog.e(TAG, "Error deriving application ABI", pme);
18870 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
18874 // Shared libraries for the package need to be updated.
18875 synchronized (mPackages) {
18877 updateSharedLibrariesLPr(pkg, null);
18878 } catch (PackageManagerException e) {
18879 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
18884 if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
18885 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
18889 // Verify if we need to dexopt the app.
18891 // NOTE: it is *important* to call dexopt after doRename which will sync the
18892 // package data from PackageParser.Package and its corresponding ApplicationInfo.
18894 // We only need to dexopt if the package meets ALL of the following conditions:
18895 // 1) it is not forward locked.
18896 // 2) it is not on on an external ASEC container.
18897 // 3) it is not an instant app or if it is then dexopt is enabled via gservices.
18899 // Note that we do not dexopt instant apps by default. dexopt can take some time to
18900 // complete, so we skip this step during installation. Instead, we'll take extra time
18901 // the first time the instant app starts. It's preferred to do it this way to provide
18902 // continuous progress to the useur instead of mysteriously blocking somewhere in the
18903 // middle of running an instant app. The default behaviour can be overridden
18905 final boolean performDexopt = !forwardLocked
18906 && !pkg.applicationInfo.isExternalAsec()
18907 && (!instantApp || Global.getInt(mContext.getContentResolver(),
18908 Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0);
18910 if (performDexopt) {
18911 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
18912 // Do not run PackageDexOptimizer through the local performDexOpt
18913 // method because `pkg` may not be in `mPackages` yet.
18915 // Also, don't fail application installs if the dexopt step fails.
18916 DexoptOptions dexoptOptions = new DexoptOptions(pkg.packageName,
18918 DexoptOptions.DEXOPT_BOOT_COMPLETE);
18919 mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
18920 null /* instructionSets */,
18921 getOrCreateCompilerPackageStats(pkg),
18922 mDexManager.getPackageUseInfoOrDefault(pkg.packageName),
18924 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18927 // Notify BackgroundDexOptService that the package has been changed.
18928 // If this is an update of a package which used to fail to compile,
18929 // BackgroundDexOptService will remove it from its blacklist.
18930 // TODO: Layering violation
18931 BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
18933 startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
18935 try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
18936 "installPackageLI")) {
18938 if (pkg.applicationInfo.isStaticSharedLibrary()) {
18939 // Static libs have a synthetic package name containing the version
18940 // and cannot be updated as an update would get a new package name,
18941 // unless this is the exact same version code which is useful for
18943 PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
18944 if (existingPkg != null && existingPkg.mVersionCode != pkg.mVersionCode) {
18945 res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
18946 + "static-shared libs cannot be updated");
18950 replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
18951 installerPackageName, res, args.installReason);
18953 installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
18954 args.user, installerPackageName, volumeUuid, res, args.installReason);
18958 synchronized (mPackages) {
18959 final PackageSetting ps = mSettings.mPackages.get(pkgName);
18961 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
18962 ps.setUpdateAvailable(false /*updateAvailable*/);
18965 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
18966 for (int i = 0; i < childCount; i++) {
18967 PackageParser.Package childPkg = pkg.childPackages.get(i);
18968 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
18969 PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
18970 if (childPs != null) {
18971 childRes.newUsers = childPs.queryInstalledUsers(
18972 sUserManager.getUserIds(), true);
18976 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
18977 updateSequenceNumberLP(ps, res.newUsers);
18978 updateInstantAppInstallerLocked(pkgName);
18983 private void startIntentFilterVerifications(int userId, boolean replacing,
18984 PackageParser.Package pkg) {
18985 if (mIntentFilterVerifierComponent == null) {
18986 Slog.w(TAG, "No IntentFilter verification will not be done as "
18987 + "there is no IntentFilterVerifier available!");
18991 final int verifierUid = getPackageUid(
18992 mIntentFilterVerifierComponent.getPackageName(),
18993 MATCH_DEBUG_TRIAGED_MISSING,
18994 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
18996 Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
18997 msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
18998 mHandler.sendMessage(msg);
19000 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
19001 for (int i = 0; i < childCount; i++) {
19002 PackageParser.Package childPkg = pkg.childPackages.get(i);
19003 msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
19004 msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
19005 mHandler.sendMessage(msg);
19009 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
19010 PackageParser.Package pkg) {
19011 int size = pkg.activities.size();
19013 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
19014 "No activity, so no need to verify any IntentFilter!");
19018 final boolean hasDomainURLs = hasDomainURLs(pkg);
19019 if (!hasDomainURLs) {
19020 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
19021 "No domain URLs, so no need to verify any IntentFilter!");
19025 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
19026 + " if any IntentFilter from the " + size
19027 + " Activities needs verification ...");
19030 final String packageName = pkg.packageName;
19032 synchronized (mPackages) {
19033 // If this is a new install and we see that we've already run verification for this
19034 // package, we have nothing to do: it means the state was restored from backup.
19036 IntentFilterVerificationInfo ivi =
19037 mSettings.getIntentFilterVerificationLPr(packageName);
19039 if (DEBUG_DOMAIN_VERIFICATION) {
19040 Slog.i(TAG, "Package " + packageName+ " already verified: status="
19041 + ivi.getStatusString());
19047 // If any filters need to be verified, then all need to be.
19048 boolean needToVerify = false;
19049 for (PackageParser.Activity a : pkg.activities) {
19050 for (ActivityIntentInfo filter : a.intents) {
19051 if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
19052 if (DEBUG_DOMAIN_VERIFICATION) {
19053 Slog.d(TAG, "Intent filter needs verification, so processing all filters");
19055 needToVerify = true;
19061 if (needToVerify) {
19062 final int verificationId = mIntentFilterVerificationToken++;
19063 for (PackageParser.Activity a : pkg.activities) {
19064 for (ActivityIntentInfo filter : a.intents) {
19065 if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
19066 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
19067 "Verification needed for IntentFilter:" + filter.toString());
19068 mIntentFilterVerifier.addOneIntentFilterVerification(
19069 verifierUid, userId, verificationId, filter, packageName);
19078 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
19079 + " IntentFilter verification" + (count > 1 ? "s" : "")
19080 + " for userId:" + userId);
19081 mIntentFilterVerifier.startVerifications(userId);
19083 if (DEBUG_DOMAIN_VERIFICATION) {
19084 Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
19089 private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
19090 final ComponentName cn = filter.activity.getComponentName();
19091 final String packageName = cn.getPackageName();
19093 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
19098 int status = ivi.getStatus();
19100 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
19101 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
19110 private static boolean isMultiArch(ApplicationInfo info) {
19111 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
19114 private static boolean isExternal(PackageParser.Package pkg) {
19115 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
19118 private static boolean isExternal(PackageSetting ps) {
19119 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
19122 private static boolean isSystemApp(PackageParser.Package pkg) {
19123 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
19126 private static boolean isPrivilegedApp(PackageParser.Package pkg) {
19127 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
19130 private static boolean hasDomainURLs(PackageParser.Package pkg) {
19131 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
19134 private static boolean isSystemApp(PackageSetting ps) {
19135 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
19138 private static boolean isUpdatedSystemApp(PackageSetting ps) {
19139 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
19142 private int packageFlagsToInstallFlags(PackageSetting ps) {
19143 int installFlags = 0;
19144 if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
19145 // This existing package was an external ASEC install when we have
19146 // the external flag without a UUID
19147 installFlags |= PackageManager.INSTALL_EXTERNAL;
19149 if (ps.isForwardLocked()) {
19150 installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
19152 return installFlags;
19155 private String getVolumeUuidForPackage(PackageParser.Package pkg) {
19156 if (isExternal(pkg)) {
19157 if (TextUtils.isEmpty(pkg.volumeUuid)) {
19158 return StorageManager.UUID_PRIMARY_PHYSICAL;
19160 return pkg.volumeUuid;
19163 return StorageManager.UUID_PRIVATE_INTERNAL;
19167 private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
19168 if (isExternal(pkg)) {
19169 if (TextUtils.isEmpty(pkg.volumeUuid)) {
19170 return mSettings.getExternalVersion();
19172 return mSettings.findOrCreateVersion(pkg.volumeUuid);
19175 return mSettings.getInternalVersion();
19179 private void deleteTempPackageFiles() {
19180 final FilenameFilter filter = new FilenameFilter() {
19181 public boolean accept(File dir, String name) {
19182 return name.startsWith("vmdl") && name.endsWith(".tmp");
19185 for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
19191 public void deletePackageAsUser(String packageName, int versionCode,
19192 IPackageDeleteObserver observer, int userId, int flags) {
19193 deletePackageVersioned(new VersionedPackage(packageName, versionCode),
19194 new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
19198 public void deletePackageVersioned(VersionedPackage versionedPackage,
19199 final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
19200 final int callingUid = Binder.getCallingUid();
19201 mContext.enforceCallingOrSelfPermission(
19202 android.Manifest.permission.DELETE_PACKAGES, null);
19203 final boolean canViewInstantApps = canViewInstantApps(callingUid, userId);
19204 Preconditions.checkNotNull(versionedPackage);
19205 Preconditions.checkNotNull(observer);
19206 Preconditions.checkArgumentInRange(versionedPackage.getVersionCode(),
19207 PackageManager.VERSION_CODE_HIGHEST,
19208 Integer.MAX_VALUE, "versionCode must be >= -1");
19210 final String packageName = versionedPackage.getPackageName();
19211 final int versionCode = versionedPackage.getVersionCode();
19212 final String internalPackageName;
19213 synchronized (mPackages) {
19214 // Normalize package name to handle renamed packages and static libs
19215 internalPackageName = resolveInternalPackageNameLPr(versionedPackage.getPackageName(),
19216 versionedPackage.getVersionCode());
19219 final int uid = Binder.getCallingUid();
19220 if (!isOrphaned(internalPackageName)
19221 && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
19223 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
19224 intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
19225 intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
19226 observer.onUserActionRequired(intent);
19227 } catch (RemoteException re) {
19231 final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
19232 final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
19233 if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
19234 mContext.enforceCallingOrSelfPermission(
19235 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
19236 "deletePackage for user " + userId);
19239 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
19241 observer.onPackageDeleted(packageName,
19242 PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
19243 } catch (RemoteException re) {
19248 if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
19250 observer.onPackageDeleted(packageName,
19251 PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
19252 } catch (RemoteException re) {
19257 if (DEBUG_REMOVE) {
19258 Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
19259 + " deleteAllUsers: " + deleteAllUsers + " version="
19260 + (versionCode == PackageManager.VERSION_CODE_HIGHEST
19261 ? "VERSION_CODE_HIGHEST" : versionCode));
19263 // Queue up an async operation since the package deletion may take a little while.
19264 mHandler.post(new Runnable() {
19265 public void run() {
19266 mHandler.removeCallbacks(this);
19268 final PackageSetting ps = mSettings.mPackages.get(internalPackageName);
19269 boolean doDeletePackage = true;
19271 final boolean targetIsInstantApp =
19272 ps.getInstantApp(UserHandle.getUserId(callingUid));
19273 doDeletePackage = !targetIsInstantApp
19274 || canViewInstantApps;
19276 if (doDeletePackage) {
19277 if (!deleteAllUsers) {
19278 returnCode = deletePackageX(internalPackageName, versionCode,
19279 userId, deleteFlags);
19281 int[] blockUninstallUserIds = getBlockUninstallForUsers(
19282 internalPackageName, users);
19283 // If nobody is blocking uninstall, proceed with delete for all users
19284 if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
19285 returnCode = deletePackageX(internalPackageName, versionCode,
19286 userId, deleteFlags);
19288 // Otherwise uninstall individually for users with blockUninstalls=false
19289 final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
19290 for (int userId : users) {
19291 if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
19292 returnCode = deletePackageX(internalPackageName, versionCode,
19293 userId, userFlags);
19294 if (returnCode != PackageManager.DELETE_SUCCEEDED) {
19295 Slog.w(TAG, "Package delete failed for user " + userId
19296 + ", returnCode " + returnCode);
19300 // The app has only been marked uninstalled for certain users.
19301 // We still need to report that delete was blocked
19302 returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
19306 returnCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
19309 observer.onPackageDeleted(packageName, returnCode, null);
19310 } catch (RemoteException e) {
19311 Log.i(TAG, "Observer no longer exists.");
19317 private String resolveExternalPackageNameLPr(PackageParser.Package pkg) {
19318 if (pkg.staticSharedLibName != null) {
19319 return pkg.manifestPackageName;
19321 return pkg.packageName;
19324 private String resolveInternalPackageNameLPr(String packageName, int versionCode) {
19325 // Handle renamed packages
19326 String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
19327 packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
19329 // Is this a static library?
19330 SparseArray<SharedLibraryEntry> versionedLib =
19331 mStaticLibsByDeclaringPackage.get(packageName);
19332 if (versionedLib == null || versionedLib.size() <= 0) {
19333 return packageName;
19336 // Figure out which lib versions the caller can see
19337 SparseIntArray versionsCallerCanSee = null;
19338 final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
19339 if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
19340 && callingAppId != Process.ROOT_UID) {
19341 versionsCallerCanSee = new SparseIntArray();
19342 String libName = versionedLib.valueAt(0).info.getName();
19343 String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
19344 if (uidPackages != null) {
19345 for (String uidPackage : uidPackages) {
19346 PackageSetting ps = mSettings.getPackageLPr(uidPackage);
19347 final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
19349 final int libVersion = ps.usesStaticLibrariesVersions[libIdx];
19350 versionsCallerCanSee.append(libVersion, libVersion);
19356 // Caller can see nothing - done
19357 if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
19358 return packageName;
19361 // Find the version the caller can see and the app version code
19362 SharedLibraryEntry highestVersion = null;
19363 final int versionCount = versionedLib.size();
19364 for (int i = 0; i < versionCount; i++) {
19365 SharedLibraryEntry libEntry = versionedLib.valueAt(i);
19366 if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
19367 libEntry.info.getVersion()) < 0) {
19370 final int libVersionCode = libEntry.info.getDeclaringPackage().getVersionCode();
19371 if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
19372 if (libVersionCode == versionCode) {
19373 return libEntry.apk;
19375 } else if (highestVersion == null) {
19376 highestVersion = libEntry;
19377 } else if (libVersionCode > highestVersion.info
19378 .getDeclaringPackage().getVersionCode()) {
19379 highestVersion = libEntry;
19383 if (highestVersion != null) {
19384 return highestVersion.apk;
19387 return packageName;
19390 boolean isCallerVerifier(int callingUid) {
19391 final int callingUserId = UserHandle.getUserId(callingUid);
19392 return mRequiredVerifierPackage != null &&
19393 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId);
19396 private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
19397 if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
19398 || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
19401 final int callingUserId = UserHandle.getUserId(callingUid);
19402 // If the caller installed the pkgName, then allow it to silently uninstall.
19403 if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
19407 // Allow package verifier to silently uninstall.
19408 if (mRequiredVerifierPackage != null &&
19409 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
19413 // Allow package uninstaller to silently uninstall.
19414 if (mRequiredUninstallerPackage != null &&
19415 callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
19419 // Allow storage manager to silently uninstall.
19420 if (mStorageManagerPackage != null &&
19421 callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
19425 // Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently
19426 // uninstall for device owner provisioning.
19427 if (checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid)
19428 == PERMISSION_GRANTED) {
19435 private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
19436 int[] result = EMPTY_INT_ARRAY;
19437 for (int userId : userIds) {
19438 if (getBlockUninstallForUser(packageName, userId)) {
19439 result = ArrayUtils.appendInt(result, userId);
19446 public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
19447 final int callingUid = Binder.getCallingUid();
19448 if (checkUidPermission(android.Manifest.permission.MANAGE_USERS, callingUid)
19449 != PERMISSION_GRANTED) {
19450 EventLog.writeEvent(0x534e4554, "128599183", -1, "");
19451 throw new SecurityException(android.Manifest.permission.MANAGE_USERS
19452 + " permission is required to call this API");
19454 if (getInstantAppPackageName(callingUid) != null
19455 && !isCallerSameApp(packageName, callingUid)) {
19458 return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
19461 private boolean isPackageDeviceAdmin(String packageName, int userId) {
19462 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
19463 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
19466 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
19467 /* callingUserOnly =*/ false);
19468 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
19469 : deviceOwnerComponentName.getPackageName();
19470 // Does the package contains the device owner?
19471 // TODO Do we have to do it even if userId != UserHandle.USER_ALL? Otherwise,
19472 // this check is probably not needed, since DO should be registered as a device
19473 // admin on some user too. (Original bug for this: b/17657954)
19474 if (packageName.equals(deviceOwnerPackageName)) {
19477 // Does it contain a device admin for any user?
19479 if (userId == UserHandle.USER_ALL) {
19480 users = sUserManager.getUserIds();
19482 users = new int[]{userId};
19484 for (int i = 0; i < users.length; ++i) {
19485 if (dpm.packageHasActiveAdmins(packageName, users[i])) {
19490 } catch (RemoteException e) {
19495 private boolean shouldKeepUninstalledPackageLPr(String packageName) {
19496 return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
19500 * This method is an internal method that could be get invoked either
19501 * to delete an installed package or to clean up a failed installation.
19502 * After deleting an installed package, a broadcast is sent to notify any
19503 * listeners that the package has been removed. For cleaning up a failed
19504 * installation, the broadcast is not necessary since the package's
19505 * installation wouldn't have sent the initial broadcast either
19506 * The key steps in deleting a package are
19507 * deleting the package information in internal structures like mPackages,
19508 * deleting the packages base directories through installd
19509 * updating mSettings to reflect current status
19510 * persisting settings for later use
19511 * sending a broadcast if necessary
19513 int deletePackageX(String packageName, int versionCode, int userId, int deleteFlags) {
19514 final PackageRemovedInfo info = new PackageRemovedInfo(this);
19517 final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
19518 ? UserHandle.USER_ALL : userId;
19520 if (isPackageDeviceAdmin(packageName, removeUser)) {
19521 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
19522 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
19525 PackageSetting uninstalledPs = null;
19526 PackageParser.Package pkg = null;
19528 // for the uninstall-updates case and restricted profiles, remember the per-
19529 // user handle installed state
19531 synchronized (mPackages) {
19532 uninstalledPs = mSettings.mPackages.get(packageName);
19533 if (uninstalledPs == null) {
19534 Slog.w(TAG, "Not removing non-existent package " + packageName);
19535 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
19538 if (versionCode != PackageManager.VERSION_CODE_HIGHEST
19539 && uninstalledPs.versionCode != versionCode) {
19540 Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
19541 + uninstalledPs.versionCode + " != " + versionCode);
19542 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
19545 // Static shared libs can be declared by any package, so let us not
19546 // allow removing a package if it provides a lib others depend on.
19547 pkg = mPackages.get(packageName);
19549 allUsers = sUserManager.getUserIds();
19551 if (pkg != null && pkg.staticSharedLibName != null) {
19552 SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName,
19553 pkg.staticSharedLibVersion);
19554 if (libEntry != null) {
19555 for (int currUserId : allUsers) {
19556 if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
19559 List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
19560 libEntry.info, 0, currUserId);
19561 if (!ArrayUtils.isEmpty(libClientPackages)) {
19562 Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
19563 + " hosting lib " + libEntry.info.getName() + " version "
19564 + libEntry.info.getVersion() + " used by " + libClientPackages
19565 + " for user " + currUserId);
19566 return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
19572 info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
19575 final int freezeUser;
19576 if (isUpdatedSystemApp(uninstalledPs)
19577 && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
19578 // We're downgrading a system app, which will apply to all users, so
19579 // freeze them all during the downgrade
19580 freezeUser = UserHandle.USER_ALL;
19582 freezeUser = removeUser;
19585 synchronized (mInstallLock) {
19586 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
19587 try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
19588 deleteFlags, "deletePackageX")) {
19589 res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
19590 deleteFlags | FLAGS_REMOVE_CHATTY, info, true, null);
19592 synchronized (mPackages) {
19595 mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
19597 updateSequenceNumberLP(uninstalledPs, info.removedUsers);
19598 updateInstantAppInstallerLocked(packageName);
19604 final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
19605 info.sendPackageRemovedBroadcasts(killApp);
19606 info.sendSystemPackageUpdatedBroadcasts();
19607 info.sendSystemPackageAppearedBroadcasts();
19609 // Force a gc here.
19610 Runtime.getRuntime().gc();
19611 // Delete the resources here after sending the broadcast to let
19612 // other processes clean up before deleting resources.
19613 if (info.args != null) {
19614 synchronized (mInstallLock) {
19615 info.args.doPostDeleteLI(true);
19619 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
19622 static class PackageRemovedInfo {
19623 final PackageSender packageSender;
19624 String removedPackage;
19625 String installerPackageName;
19627 int removedAppId = -1;
19629 int[] removedUsers = null;
19630 int[] broadcastUsers = null;
19631 SparseArray<Integer> installReasons;
19632 boolean isRemovedPackageSystemUpdate = false;
19634 boolean dataRemoved;
19635 boolean removedForAllUsers;
19636 boolean isStaticSharedLib;
19637 // Clean up resources deleted packages.
19638 InstallArgs args = null;
19639 ArrayMap<String, PackageRemovedInfo> removedChildPackages;
19640 ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
19642 PackageRemovedInfo(PackageSender packageSender) {
19643 this.packageSender = packageSender;
19646 void sendPackageRemovedBroadcasts(boolean killApp) {
19647 sendPackageRemovedBroadcastInternal(killApp);
19648 final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
19649 for (int i = 0; i < childCount; i++) {
19650 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
19651 childInfo.sendPackageRemovedBroadcastInternal(killApp);
19655 void sendSystemPackageUpdatedBroadcasts() {
19656 if (isRemovedPackageSystemUpdate) {
19657 sendSystemPackageUpdatedBroadcastsInternal();
19658 final int childCount = (removedChildPackages != null)
19659 ? removedChildPackages.size() : 0;
19660 for (int i = 0; i < childCount; i++) {
19661 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
19662 if (childInfo.isRemovedPackageSystemUpdate) {
19663 childInfo.sendSystemPackageUpdatedBroadcastsInternal();
19669 void sendSystemPackageAppearedBroadcasts() {
19670 final int packageCount = (appearedChildPackages != null)
19671 ? appearedChildPackages.size() : 0;
19672 for (int i = 0; i < packageCount; i++) {
19673 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
19674 packageSender.sendPackageAddedForNewUsers(installedInfo.name,
19675 true /*sendBootCompleted*/, false /*startReceiver*/,
19676 UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers);
19680 private void sendSystemPackageUpdatedBroadcastsInternal() {
19681 Bundle extras = new Bundle(2);
19682 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
19683 extras.putBoolean(Intent.EXTRA_REPLACING, true);
19684 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
19685 removedPackage, extras, 0, null /*targetPackage*/, null, null);
19686 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
19687 removedPackage, extras, 0, null /*targetPackage*/, null, null);
19688 packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
19689 null, null, 0, removedPackage, null, null);
19690 if (installerPackageName != null) {
19691 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
19692 removedPackage, extras, 0 /*flags*/,
19693 installerPackageName, null, null);
19694 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
19695 removedPackage, extras, 0 /*flags*/,
19696 installerPackageName, null, null);
19700 private void sendPackageRemovedBroadcastInternal(boolean killApp) {
19701 // Don't send static shared library removal broadcasts as these
19702 // libs are visible only the the apps that depend on them an one
19703 // cannot remove the library if it has a dependency.
19704 if (isStaticSharedLib) {
19707 Bundle extras = new Bundle(2);
19708 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
19709 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
19710 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
19711 if (isUpdate || isRemovedPackageSystemUpdate) {
19712 extras.putBoolean(Intent.EXTRA_REPLACING, true);
19714 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
19715 if (removedPackage != null) {
19716 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
19717 removedPackage, extras, 0, null /*targetPackage*/, null, broadcastUsers);
19718 if (installerPackageName != null) {
19719 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
19720 removedPackage, extras, 0 /*flags*/,
19721 installerPackageName, null, broadcastUsers);
19723 if (dataRemoved && !isRemovedPackageSystemUpdate) {
19724 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
19725 removedPackage, extras,
19726 Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
19727 null, null, broadcastUsers);
19730 if (removedAppId >= 0) {
19731 packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
19732 null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
19733 null, null, broadcastUsers);
19737 void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
19738 removedUsers = userIds;
19739 if (removedUsers == null) {
19740 broadcastUsers = null;
19744 broadcastUsers = EMPTY_INT_ARRAY;
19745 for (int i = userIds.length - 1; i >= 0; --i) {
19746 final int userId = userIds[i];
19747 if (deletedPackageSetting.getInstantApp(userId)) {
19750 broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
19756 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
19757 * flag is not set, the data directory is removed as well.
19758 * make sure this flag is set for partially installed apps. If not its meaningless to
19759 * delete a partially installed application.
19761 private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
19762 PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
19763 String packageName = ps.name;
19764 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
19765 // Retrieve object to delete permissions for shared user later on
19766 final PackageParser.Package deletedPkg;
19767 final PackageSetting deletedPs;
19769 synchronized (mPackages) {
19770 deletedPkg = mPackages.get(packageName);
19771 deletedPs = mSettings.mPackages.get(packageName);
19772 if (outInfo != null) {
19773 outInfo.removedPackage = packageName;
19774 outInfo.installerPackageName = ps.installerPackageName;
19775 outInfo.isStaticSharedLib = deletedPkg != null
19776 && deletedPkg.staticSharedLibName != null;
19777 outInfo.populateUsers(deletedPs == null ? null
19778 : deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true), deletedPs);
19782 removePackageLI(ps, (flags & FLAGS_REMOVE_CHATTY) != 0);
19784 if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
19785 final PackageParser.Package resolvedPkg;
19786 if (deletedPkg != null) {
19787 resolvedPkg = deletedPkg;
19789 // We don't have a parsed package when it lives on an ejected
19790 // adopted storage device, so fake something together
19791 resolvedPkg = new PackageParser.Package(ps.name);
19792 resolvedPkg.setVolumeUuid(ps.volumeUuid);
19794 destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
19795 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19796 destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
19797 if (outInfo != null) {
19798 outInfo.dataRemoved = true;
19800 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
19803 int removedAppId = -1;
19806 synchronized (mPackages) {
19807 boolean installedStateChanged = false;
19808 if (deletedPs != null) {
19809 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
19810 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
19811 clearDefaultBrowserIfNeeded(packageName);
19812 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
19813 removedAppId = mSettings.removePackageLPw(packageName);
19814 if (outInfo != null) {
19815 outInfo.removedAppId = removedAppId;
19817 updatePermissionsLPw(deletedPs.name, null, 0);
19818 if (deletedPs.sharedUser != null) {
19819 // Remove permissions associated with package. Since runtime
19820 // permissions are per user we have to kill the removed package
19821 // or packages running under the shared user of the removed
19822 // package if revoking the permissions requested only by the removed
19823 // package is successful and this causes a change in gids.
19824 for (int userId : UserManagerService.getInstance().getUserIds()) {
19825 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
19827 if (userIdToKill == UserHandle.USER_ALL
19828 || userIdToKill >= UserHandle.USER_SYSTEM) {
19829 // If gids changed for this user, kill all affected packages.
19830 mHandler.post(new Runnable() {
19832 public void run() {
19833 // This has to happen with no lock held.
19834 killApplication(deletedPs.name, deletedPs.appId,
19835 KILL_APP_REASON_GIDS_CHANGED);
19842 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
19844 // make sure to preserve per-user disabled state if this removal was just
19845 // a downgrade of a system app to the factory package
19846 if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
19847 if (DEBUG_REMOVE) {
19848 Slog.d(TAG, "Propagating install state across downgrade");
19850 for (int userId : allUserHandles) {
19851 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
19852 if (DEBUG_REMOVE) {
19853 Slog.d(TAG, " user " + userId + " => " + installed);
19855 if (installed != ps.getInstalled(userId)) {
19856 installedStateChanged = true;
19858 ps.setInstalled(installed, userId);
19862 // can downgrade to reader
19863 if (writeSettings) {
19864 // Save settings now
19865 mSettings.writeLPr();
19867 if (installedStateChanged) {
19868 mSettings.writeKernelMappingLPr(ps);
19871 if (removedAppId != -1) {
19872 // A user ID was deleted here. Go through all users and remove it
19874 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId);
19878 static boolean locationIsPrivileged(File path) {
19880 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
19881 .getCanonicalPath();
19882 return path.getCanonicalPath().startsWith(privilegedAppDir);
19883 } catch (IOException e) {
19884 Slog.e(TAG, "Unable to access code path " + path);
19890 * Tries to delete system package.
19892 private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
19893 PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
19894 boolean writeSettings) {
19895 if (deletedPs.parentPackageName != null) {
19896 Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
19900 final boolean applyUserRestrictions
19901 = (allUserHandles != null) && (outInfo.origUsers != null);
19902 final PackageSetting disabledPs;
19903 // Confirm if the system package has been updated
19904 // An updated system app can be deleted. This will also have to restore
19905 // the system pkg from system partition
19907 synchronized (mPackages) {
19908 disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
19911 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
19912 + " disabledPs=" + disabledPs);
19914 if (disabledPs == null) {
19915 Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
19917 } else if (DEBUG_REMOVE) {
19918 Slog.d(TAG, "Deleting system pkg from data partition");
19921 if (DEBUG_REMOVE) {
19922 if (applyUserRestrictions) {
19923 Slog.d(TAG, "Remembering install states:");
19924 for (int userId : allUserHandles) {
19925 final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
19926 Slog.d(TAG, " u=" + userId + " inst=" + finstalled);
19931 // Delete the updated package
19932 outInfo.isRemovedPackageSystemUpdate = true;
19933 if (outInfo.removedChildPackages != null) {
19934 final int childCount = (deletedPs.childPackageNames != null)
19935 ? deletedPs.childPackageNames.size() : 0;
19936 for (int i = 0; i < childCount; i++) {
19937 String childPackageName = deletedPs.childPackageNames.get(i);
19938 if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
19939 .contains(childPackageName)) {
19940 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
19942 if (childInfo != null) {
19943 childInfo.isRemovedPackageSystemUpdate = true;
19949 if (disabledPs.versionCode < deletedPs.versionCode) {
19950 // Delete data for downgrades
19951 flags &= ~PackageManager.DELETE_KEEP_DATA;
19953 // Preserve data by setting flag
19954 flags |= PackageManager.DELETE_KEEP_DATA;
19957 boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
19958 outInfo, writeSettings, disabledPs.pkg);
19964 synchronized (mPackages) {
19965 // NOTE: The system package always needs to be enabled; even if it's for
19966 // a compressed stub. If we don't, installing the system package fails
19967 // during scan [scanning checks the disabled packages]. We will reverse
19968 // this later, after we've "installed" the stub.
19969 // Reinstate the old system package
19970 enableSystemPackageLPw(disabledPs.pkg);
19971 // Remove any native libraries from the upgraded package.
19972 removeNativeBinariesLI(deletedPs);
19975 // Install the system package
19976 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
19978 installPackageFromSystemLIF(disabledPs.codePath, false /*isPrivileged*/, allUserHandles,
19979 outInfo.origUsers, deletedPs.getPermissionsState(), writeSettings);
19980 } catch (PackageManagerException e) {
19981 Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
19985 if (disabledPs.pkg.isStub) {
19986 mSettings.disableSystemPackageLPw(disabledPs.name, true /*replaced*/);
19993 * Installs a package that's already on the system partition.
19995 private PackageParser.Package installPackageFromSystemLIF(@NonNull File codePath,
19996 boolean isPrivileged, @Nullable int[] allUserHandles, @Nullable int[] origUserHandles,
19997 @Nullable PermissionsState origPermissionState, boolean writeSettings)
19998 throws PackageManagerException {
19999 int parseFlags = mDefParseFlags
20000 | PackageParser.PARSE_MUST_BE_APK
20001 | PackageParser.PARSE_IS_SYSTEM
20002 | PackageParser.PARSE_IS_SYSTEM_DIR;
20003 if (isPrivileged || locationIsPrivileged(codePath)) {
20004 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
20007 final PackageParser.Package newPkg =
20008 scanPackageTracedLI(codePath, parseFlags, 0 /*scanFlags*/, 0 /*currentTime*/, null);
20011 // update shared libraries for the newly re-installed system package
20012 updateSharedLibrariesLPr(newPkg, null);
20013 } catch (PackageManagerException e) {
20014 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
20017 prepareAppDataAfterInstallLIF(newPkg);
20020 synchronized (mPackages) {
20021 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
20023 // Propagate the permissions state as we do not want to drop on the floor
20024 // runtime permissions. The update permissions method below will take
20025 // care of removing obsolete permissions and grant install permissions.
20026 if (origPermissionState != null) {
20027 ps.getPermissionsState().copyFrom(origPermissionState);
20029 updatePermissionsLPw(newPkg.packageName, newPkg,
20030 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
20032 final boolean applyUserRestrictions
20033 = (allUserHandles != null) && (origUserHandles != null);
20034 if (applyUserRestrictions) {
20035 boolean installedStateChanged = false;
20036 if (DEBUG_REMOVE) {
20037 Slog.d(TAG, "Propagating install state across reinstall");
20039 for (int userId : allUserHandles) {
20040 final boolean installed = ArrayUtils.contains(origUserHandles, userId);
20041 if (DEBUG_REMOVE) {
20042 Slog.d(TAG, " user " + userId + " => " + installed);
20044 if (installed != ps.getInstalled(userId)) {
20045 installedStateChanged = true;
20047 ps.setInstalled(installed, userId);
20049 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
20051 // Regardless of writeSettings we need to ensure that this restriction
20052 // state propagation is persisted
20053 mSettings.writeAllUsersPackageRestrictionsLPr();
20054 if (installedStateChanged) {
20055 mSettings.writeKernelMappingLPr(ps);
20058 // can downgrade to reader here
20059 if (writeSettings) {
20060 mSettings.writeLPr();
20066 private boolean deleteInstalledPackageLIF(PackageSetting ps,
20067 boolean deleteCodeAndResources, int flags, int[] allUserHandles,
20068 PackageRemovedInfo outInfo, boolean writeSettings,
20069 PackageParser.Package replacingPackage) {
20070 synchronized (mPackages) {
20071 if (outInfo != null) {
20072 outInfo.uid = ps.appId;
20075 if (outInfo != null && outInfo.removedChildPackages != null) {
20076 final int childCount = (ps.childPackageNames != null)
20077 ? ps.childPackageNames.size() : 0;
20078 for (int i = 0; i < childCount; i++) {
20079 String childPackageName = ps.childPackageNames.get(i);
20080 PackageSetting childPs = mSettings.mPackages.get(childPackageName);
20081 if (childPs == null) {
20084 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
20086 if (childInfo != null) {
20087 childInfo.uid = childPs.appId;
20093 // Delete package data from internal structures and also remove data if flag is set
20094 removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
20096 // Delete the child packages data
20097 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
20098 for (int i = 0; i < childCount; i++) {
20099 PackageSetting childPs;
20100 synchronized (mPackages) {
20101 childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
20103 if (childPs != null) {
20104 PackageRemovedInfo childOutInfo = (outInfo != null
20105 && outInfo.removedChildPackages != null)
20106 ? outInfo.removedChildPackages.get(childPs.name) : null;
20107 final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
20108 && (replacingPackage != null
20109 && !replacingPackage.hasChildPackage(childPs.name))
20110 ? flags & ~DELETE_KEEP_DATA : flags;
20111 removePackageDataLIF(childPs, allUserHandles, childOutInfo,
20112 deleteFlags, writeSettings);
20116 // Delete application code and resources only for parent packages
20117 if (ps.parentPackageName == null) {
20118 if (deleteCodeAndResources && (outInfo != null)) {
20119 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
20120 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
20121 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
20129 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
20131 mContext.enforceCallingOrSelfPermission(
20132 android.Manifest.permission.DELETE_PACKAGES, null);
20133 synchronized (mPackages) {
20134 // Cannot block uninstall of static shared libs as they are
20135 // considered a part of the using app (emulating static linking).
20136 // Also static libs are installed always on internal storage.
20137 PackageParser.Package pkg = mPackages.get(packageName);
20138 if (pkg != null && pkg.staticSharedLibName != null) {
20139 Slog.w(TAG, "Cannot block uninstall of package: " + packageName
20140 + " providing static shared library: " + pkg.staticSharedLibName);
20143 mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
20144 mSettings.writePackageRestrictionsLPr(userId);
20150 public boolean getBlockUninstallForUser(String packageName, int userId) {
20151 synchronized (mPackages) {
20152 final PackageSetting ps = mSettings.mPackages.get(packageName);
20153 if (ps == null || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
20156 return mSettings.getBlockUninstallLPr(userId, packageName);
20161 public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
20162 enforceSystemOrRoot("setRequiredForSystemUser can only be run by the system or root");
20163 synchronized (mPackages) {
20164 PackageSetting ps = mSettings.mPackages.get(packageName);
20166 Log.w(TAG, "Package doesn't exist: " + packageName);
20169 if (systemUserApp) {
20170 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
20172 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
20174 mSettings.writeLPr();
20180 * This method handles package deletion in general
20182 private boolean deletePackageLIF(String packageName, UserHandle user,
20183 boolean deleteCodeAndResources, int[] allUserHandles, int flags,
20184 PackageRemovedInfo outInfo, boolean writeSettings,
20185 PackageParser.Package replacingPackage) {
20186 if (packageName == null) {
20187 Slog.w(TAG, "Attempt to delete null packageName.");
20191 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
20194 synchronized (mPackages) {
20195 ps = mSettings.mPackages.get(packageName);
20197 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
20201 if (ps.parentPackageName != null && (!isSystemApp(ps)
20202 || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
20203 if (DEBUG_REMOVE) {
20204 Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
20205 + ((user == null) ? UserHandle.USER_ALL : user));
20207 final int removedUserId = (user != null) ? user.getIdentifier()
20208 : UserHandle.USER_ALL;
20209 if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
20212 markPackageUninstalledForUserLPw(ps, user);
20213 scheduleWritePackageRestrictionsLocked(user);
20218 if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
20219 && user.getIdentifier() != UserHandle.USER_ALL)) {
20220 // The caller is asking that the package only be deleted for a single
20221 // user. To do this, we just mark its uninstalled state and delete
20222 // its data. If this is a system app, we only allow this to happen if
20223 // they have set the special DELETE_SYSTEM_APP which requests different
20224 // semantics than normal for uninstalling system apps.
20225 markPackageUninstalledForUserLPw(ps, user);
20227 if (!isSystemApp(ps)) {
20228 // Do not uninstall the APK if an app should be cached
20229 boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
20230 if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
20231 // Other user still have this package installed, so all
20232 // we need to do is clear this user's data and save that
20233 // it is uninstalled.
20234 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
20235 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
20238 scheduleWritePackageRestrictionsLocked(user);
20241 // We need to set it back to 'installed' so the uninstall
20242 // broadcasts will be sent correctly.
20243 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
20244 ps.setInstalled(true, user.getIdentifier());
20245 mSettings.writeKernelMappingLPr(ps);
20248 // This is a system app, so we assume that the
20249 // other users still have this package installed, so all
20250 // we need to do is clear this user's data and save that
20251 // it is uninstalled.
20252 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
20253 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
20256 scheduleWritePackageRestrictionsLocked(user);
20261 // If we are deleting a composite package for all users, keep track
20262 // of result for each child.
20263 if (ps.childPackageNames != null && outInfo != null) {
20264 synchronized (mPackages) {
20265 final int childCount = ps.childPackageNames.size();
20266 outInfo.removedChildPackages = new ArrayMap<>(childCount);
20267 for (int i = 0; i < childCount; i++) {
20268 String childPackageName = ps.childPackageNames.get(i);
20269 PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
20270 childInfo.removedPackage = childPackageName;
20271 childInfo.installerPackageName = ps.installerPackageName;
20272 outInfo.removedChildPackages.put(childPackageName, childInfo);
20273 PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
20274 if (childPs != null) {
20275 childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
20281 boolean ret = false;
20282 if (isSystemApp(ps)) {
20283 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
20284 // When an updated system application is deleted we delete the existing resources
20285 // as well and fall back to existing code in system partition
20286 ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
20288 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
20289 ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
20290 outInfo, writeSettings, replacingPackage);
20293 // Take a note whether we deleted the package for all users
20294 if (outInfo != null) {
20295 outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
20296 if (outInfo.removedChildPackages != null) {
20297 synchronized (mPackages) {
20298 final int childCount = outInfo.removedChildPackages.size();
20299 for (int i = 0; i < childCount; i++) {
20300 PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
20301 if (childInfo != null) {
20302 childInfo.removedForAllUsers = mPackages.get(
20303 childInfo.removedPackage) == null;
20308 // If we uninstalled an update to a system app there may be some
20309 // child packages that appeared as they are declared in the system
20310 // app but were not declared in the update.
20311 if (isSystemApp(ps)) {
20312 synchronized (mPackages) {
20313 PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
20314 final int childCount = (updatedPs.childPackageNames != null)
20315 ? updatedPs.childPackageNames.size() : 0;
20316 for (int i = 0; i < childCount; i++) {
20317 String childPackageName = updatedPs.childPackageNames.get(i);
20318 if (outInfo.removedChildPackages == null
20319 || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
20320 PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
20321 if (childPs == null) {
20324 PackageInstalledInfo installRes = new PackageInstalledInfo();
20325 installRes.name = childPackageName;
20326 installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
20327 installRes.pkg = mPackages.get(childPackageName);
20328 installRes.uid = childPs.pkg.applicationInfo.uid;
20329 if (outInfo.appearedChildPackages == null) {
20330 outInfo.appearedChildPackages = new ArrayMap<>();
20332 outInfo.appearedChildPackages.put(childPackageName, installRes);
20342 private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
20343 final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
20344 ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
20345 for (int nextUserId : userIds) {
20346 if (DEBUG_REMOVE) {
20347 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
20349 ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
20350 false /*installed*/,
20352 true /*notLaunched*/,
20354 false /*suspended*/,
20355 false /*instantApp*/,
20356 false /*virtualPreload*/,
20357 null /*lastDisableAppCaller*/,
20358 null /*enabledComponents*/,
20359 null /*disabledComponents*/,
20360 ps.readUserState(nextUserId).domainVerificationStatus,
20361 0, PackageManager.INSTALL_REASON_UNKNOWN);
20363 mSettings.writeKernelMappingLPr(ps);
20366 private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
20367 PackageRemovedInfo outInfo) {
20368 final PackageParser.Package pkg;
20369 synchronized (mPackages) {
20370 pkg = mPackages.get(ps.name);
20373 final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
20374 : new int[] {userId};
20375 for (int nextUserId : userIds) {
20376 if (DEBUG_REMOVE) {
20377 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
20381 destroyAppDataLIF(pkg, userId,
20382 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
20383 destroyAppProfilesLIF(pkg, userId);
20384 clearDefaultBrowserIfNeededForUser(ps.name, userId);
20385 removeKeystoreDataIfNeeded(nextUserId, ps.appId);
20386 schedulePackageCleaning(ps.name, nextUserId, false);
20387 synchronized (mPackages) {
20388 if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
20389 scheduleWritePackageRestrictionsLocked(nextUserId);
20391 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
20395 if (outInfo != null) {
20396 outInfo.removedPackage = ps.name;
20397 outInfo.installerPackageName = ps.installerPackageName;
20398 outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
20399 outInfo.removedAppId = ps.appId;
20400 outInfo.removedUsers = userIds;
20401 outInfo.broadcastUsers = userIds;
20407 private final class ClearStorageConnection implements ServiceConnection {
20408 IMediaContainerService mContainerService;
20411 public void onServiceConnected(ComponentName name, IBinder service) {
20412 synchronized (this) {
20413 mContainerService = IMediaContainerService.Stub
20414 .asInterface(Binder.allowBlocking(service));
20420 public void onServiceDisconnected(ComponentName name) {
20424 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
20425 if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
20427 final boolean mounted;
20428 if (Environment.isExternalStorageEmulated()) {
20431 final String status = Environment.getExternalStorageState();
20433 mounted = status.equals(Environment.MEDIA_MOUNTED)
20434 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
20441 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
20443 if (userId == UserHandle.USER_ALL) {
20444 users = sUserManager.getUserIds();
20446 users = new int[] { userId };
20448 final ClearStorageConnection conn = new ClearStorageConnection();
20449 if (mContext.bindServiceAsUser(
20450 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
20452 for (int curUser : users) {
20453 long timeout = SystemClock.uptimeMillis() + 5000;
20454 synchronized (conn) {
20456 while (conn.mContainerService == null &&
20457 (now = SystemClock.uptimeMillis()) < timeout) {
20459 conn.wait(timeout - now);
20460 } catch (InterruptedException e) {
20464 if (conn.mContainerService == null) {
20468 final UserEnvironment userEnv = new UserEnvironment(curUser);
20469 clearDirectory(conn.mContainerService,
20470 userEnv.buildExternalStorageAppCacheDirs(packageName));
20472 clearDirectory(conn.mContainerService,
20473 userEnv.buildExternalStorageAppDataDirs(packageName));
20474 clearDirectory(conn.mContainerService,
20475 userEnv.buildExternalStorageAppMediaDirs(packageName));
20479 mContext.unbindService(conn);
20485 public void clearApplicationProfileData(String packageName) {
20486 enforceSystemOrRoot("Only the system can clear all profile data");
20488 final PackageParser.Package pkg;
20489 synchronized (mPackages) {
20490 pkg = mPackages.get(packageName);
20493 try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
20494 synchronized (mInstallLock) {
20495 clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
20501 public void clearApplicationUserData(final String packageName,
20502 final IPackageDataObserver observer, final int userId) {
20503 mContext.enforceCallingOrSelfPermission(
20504 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
20506 final int callingUid = Binder.getCallingUid();
20507 enforceCrossUserPermission(callingUid, userId,
20508 true /* requireFullPermission */, false /* checkShell */, "clear application data");
20510 final PackageSetting ps = mSettings.getPackageLPr(packageName);
20511 final boolean filterApp = (ps != null && filterAppAccessLPr(ps, callingUid, userId));
20512 if (!filterApp && mProtectedPackages.isPackageDataProtected(userId, packageName)) {
20513 throw new SecurityException("Cannot clear data for a protected package: "
20516 // Queue up an async operation since the package deletion may take a little while.
20517 mHandler.post(new Runnable() {
20518 public void run() {
20519 mHandler.removeCallbacks(this);
20520 final boolean succeeded;
20522 try (PackageFreezer freezer = freezePackage(packageName,
20523 "clearApplicationUserData")) {
20524 synchronized (mInstallLock) {
20525 succeeded = clearApplicationUserDataLIF(packageName, userId);
20527 clearExternalStorageDataSync(packageName, userId, true);
20528 synchronized (mPackages) {
20529 mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
20530 packageName, userId);
20534 // invoke DeviceStorageMonitor's update method to clear any notifications
20535 DeviceStorageMonitorInternal dsm = LocalServices
20536 .getService(DeviceStorageMonitorInternal.class);
20544 if (observer != null) {
20546 observer.onRemoveCompleted(packageName, succeeded);
20547 } catch (RemoteException e) {
20548 Log.i(TAG, "Observer no longer exists.");
20550 } //end if observer
20555 private boolean clearApplicationUserDataLIF(String packageName, int userId) {
20556 if (packageName == null) {
20557 Slog.w(TAG, "Attempt to delete null packageName.");
20561 // Try finding details about the requested package
20562 PackageParser.Package pkg;
20563 synchronized (mPackages) {
20564 pkg = mPackages.get(packageName);
20566 final PackageSetting ps = mSettings.mPackages.get(packageName);
20573 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
20577 PackageSetting ps = (PackageSetting) pkg.mExtras;
20578 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
20581 clearAppDataLIF(pkg, userId,
20582 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
20584 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
20585 removeKeystoreDataIfNeeded(userId, appId);
20587 UserManagerInternal umInternal = getUserManagerInternal();
20589 if (umInternal.isUserUnlockingOrUnlocked(userId)) {
20590 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
20591 } else if (umInternal.isUserRunning(userId)) {
20592 flags = StorageManager.FLAG_STORAGE_DE;
20596 prepareAppDataContentsLIF(pkg, userId, flags);
20602 * Reverts user permission state changes (permissions and flags) in
20603 * all packages for a given user.
20605 * @param userId The device user for which to do a reset.
20607 private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
20608 final int packageCount = mPackages.size();
20609 for (int i = 0; i < packageCount; i++) {
20610 PackageParser.Package pkg = mPackages.valueAt(i);
20611 PackageSetting ps = (PackageSetting) pkg.mExtras;
20612 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
20616 private void resetNetworkPolicies(int userId) {
20617 LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
20621 * Reverts user permission state changes (permissions and flags).
20623 * @param ps The package for which to reset.
20624 * @param userId The device user for which to do a reset.
20626 private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
20627 final PackageSetting ps, final int userId) {
20628 if (ps.pkg == null) {
20632 // These are flags that can change base on user actions.
20633 final int userSettableMask = FLAG_PERMISSION_USER_SET
20634 | FLAG_PERMISSION_USER_FIXED
20635 | FLAG_PERMISSION_REVOKE_ON_UPGRADE
20636 | FLAG_PERMISSION_REVIEW_REQUIRED;
20638 final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
20639 | FLAG_PERMISSION_POLICY_FIXED;
20641 boolean writeInstallPermissions = false;
20642 boolean writeRuntimePermissions = false;
20644 final int permissionCount = ps.pkg.requestedPermissions.size();
20645 for (int i = 0; i < permissionCount; i++) {
20646 String permission = ps.pkg.requestedPermissions.get(i);
20648 BasePermission bp = mSettings.mPermissions.get(permission);
20653 // If shared user we just reset the state to which only this app contributed.
20654 if (ps.sharedUser != null) {
20655 boolean used = false;
20656 final int packageCount = ps.sharedUser.packages.size();
20657 for (int j = 0; j < packageCount; j++) {
20658 PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
20659 if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
20660 && pkg.pkg.requestedPermissions.contains(permission)) {
20670 PermissionsState permissionsState = ps.getPermissionsState();
20672 final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
20674 // Always clear the user settable flags.
20675 final boolean hasInstallState = permissionsState.getInstallPermissionState(
20677 // If permission review is enabled and this is a legacy app, mark the
20678 // permission as requiring a review as this is the initial state.
20680 if (mPermissionReviewRequired
20681 && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
20682 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
20684 if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
20685 if (hasInstallState) {
20686 writeInstallPermissions = true;
20688 writeRuntimePermissions = true;
20692 // Below is only runtime permission handling.
20693 if (!bp.isRuntime()) {
20697 // Never clobber system or policy.
20698 if ((oldFlags & policyOrSystemFlags) != 0) {
20702 // If this permission was granted by default, make sure it is.
20703 if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
20704 if (permissionsState.grantRuntimePermission(bp, userId)
20705 != PERMISSION_OPERATION_FAILURE) {
20706 writeRuntimePermissions = true;
20708 // If permission review is enabled the permissions for a legacy apps
20709 // are represented as constantly granted runtime ones, so don't revoke.
20710 } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
20711 // Otherwise, reset the permission.
20712 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
20713 switch (revokeResult) {
20714 case PERMISSION_OPERATION_SUCCESS:
20715 case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
20716 writeRuntimePermissions = true;
20717 final int appId = ps.appId;
20718 mHandler.post(new Runnable() {
20720 public void run() {
20721 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
20729 // Synchronously write as we are taking permissions away.
20730 if (writeRuntimePermissions) {
20731 mSettings.writeRuntimePermissionsForUserLPr(userId, true);
20734 // Synchronously write as we are taking permissions away.
20735 if (writeInstallPermissions) {
20736 mSettings.writeLPr();
20741 * Remove entries from the keystore daemon. Will only remove it if the
20742 * {@code appId} is valid.
20744 private static void removeKeystoreDataIfNeeded(int userId, int appId) {
20749 final KeyStore keyStore = KeyStore.getInstance();
20750 if (keyStore != null) {
20751 if (userId == UserHandle.USER_ALL) {
20752 for (final int individual : sUserManager.getUserIds()) {
20753 keyStore.clearUid(UserHandle.getUid(individual, appId));
20756 keyStore.clearUid(UserHandle.getUid(userId, appId));
20759 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
20764 public void deleteApplicationCacheFiles(final String packageName,
20765 final IPackageDataObserver observer) {
20766 final int userId = UserHandle.getCallingUserId();
20767 deleteApplicationCacheFilesAsUser(packageName, userId, observer);
20771 public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
20772 final IPackageDataObserver observer) {
20773 final int callingUid = Binder.getCallingUid();
20774 mContext.enforceCallingOrSelfPermission(
20775 android.Manifest.permission.DELETE_CACHE_FILES, null);
20776 enforceCrossUserPermission(callingUid, userId,
20777 /* requireFullPermission= */ true, /* checkShell= */ false,
20778 "delete application cache files");
20779 final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
20780 android.Manifest.permission.ACCESS_INSTANT_APPS);
20782 final PackageParser.Package pkg;
20783 synchronized (mPackages) {
20784 pkg = mPackages.get(packageName);
20787 // Queue up an async operation since the package deletion may take a little while.
20788 mHandler.post(new Runnable() {
20789 public void run() {
20790 final PackageSetting ps = pkg == null ? null : (PackageSetting) pkg.mExtras;
20791 boolean doClearData = true;
20793 final boolean targetIsInstantApp =
20794 ps.getInstantApp(UserHandle.getUserId(callingUid));
20795 doClearData = !targetIsInstantApp
20796 || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
20799 synchronized (mInstallLock) {
20800 final int flags = StorageManager.FLAG_STORAGE_DE
20801 | StorageManager.FLAG_STORAGE_CE;
20802 // We're only clearing cache files, so we don't care if the
20803 // app is unfrozen and still able to run
20804 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
20805 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
20807 clearExternalStorageDataSync(packageName, userId, false);
20809 if (observer != null) {
20811 observer.onRemoveCompleted(packageName, true);
20812 } catch (RemoteException e) {
20813 Log.i(TAG, "Observer no longer exists.");
20821 public void getPackageSizeInfo(final String packageName, int userHandle,
20822 final IPackageStatsObserver observer) {
20823 throw new UnsupportedOperationException(
20824 "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
20827 private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
20828 final PackageSetting ps;
20829 synchronized (mPackages) {
20830 ps = mSettings.mPackages.get(packageName);
20832 Slog.w(TAG, "Failed to find settings for " + packageName);
20837 final String[] packageNames = { packageName };
20838 final long[] ceDataInodes = { ps.getCeDataInode(userId) };
20839 final String[] codePaths = { ps.codePathString };
20842 mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
20843 ps.appId, ceDataInodes, codePaths, stats);
20845 // For now, ignore code size of packages on system partition
20846 if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
20847 stats.codeSize = 0;
20850 // External clients expect these to be tracked separately
20851 stats.dataSize -= stats.cacheSize;
20853 } catch (InstallerException e) {
20854 Slog.w(TAG, String.valueOf(e));
20861 private int getUidTargetSdkVersionLockedLPr(int uid) {
20862 Object obj = mSettings.getUserIdLPr(uid);
20863 if (obj instanceof SharedUserSetting) {
20864 final SharedUserSetting sus = (SharedUserSetting) obj;
20865 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
20866 final Iterator<PackageSetting> it = sus.packages.iterator();
20867 while (it.hasNext()) {
20868 final PackageSetting ps = it.next();
20869 if (ps.pkg != null) {
20870 int v = ps.pkg.applicationInfo.targetSdkVersion;
20871 if (v < vers) vers = v;
20875 } else if (obj instanceof PackageSetting) {
20876 final PackageSetting ps = (PackageSetting) obj;
20877 if (ps.pkg != null) {
20878 return ps.pkg.applicationInfo.targetSdkVersion;
20881 return Build.VERSION_CODES.CUR_DEVELOPMENT;
20885 public void addPreferredActivity(IntentFilter filter, int match,
20886 ComponentName[] set, ComponentName activity, int userId) {
20887 addPreferredActivityInternal(filter, match, set, activity, true, userId,
20888 "Adding preferred");
20891 private void addPreferredActivityInternal(IntentFilter filter, int match,
20892 ComponentName[] set, ComponentName activity, boolean always, int userId,
20895 int callingUid = Binder.getCallingUid();
20896 enforceCrossUserPermission(callingUid, userId,
20897 true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
20898 if (filter.countActions() == 0) {
20899 Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
20902 synchronized (mPackages) {
20903 if (mContext.checkCallingOrSelfPermission(
20904 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
20905 != PackageManager.PERMISSION_GRANTED) {
20906 if (getUidTargetSdkVersionLockedLPr(callingUid)
20907 < Build.VERSION_CODES.FROYO) {
20908 Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
20912 mContext.enforceCallingOrSelfPermission(
20913 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20916 PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
20917 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
20919 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
20920 pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
20921 scheduleWritePackageRestrictionsLocked(userId);
20922 postPreferredActivityChangedBroadcast(userId);
20926 private void postPreferredActivityChangedBroadcast(int userId) {
20927 mHandler.post(() -> {
20928 final IActivityManager am = ActivityManager.getService();
20933 final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
20934 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20936 am.broadcastIntent(null, intent, null, null,
20937 0, null, null, null, android.app.AppOpsManager.OP_NONE,
20938 null, false, false, userId);
20939 } catch (RemoteException e) {
20945 public void replacePreferredActivity(IntentFilter filter, int match,
20946 ComponentName[] set, ComponentName activity, int userId) {
20947 if (filter.countActions() != 1) {
20948 throw new IllegalArgumentException(
20949 "replacePreferredActivity expects filter to have only 1 action.");
20951 if (filter.countDataAuthorities() != 0
20952 || filter.countDataPaths() != 0
20953 || filter.countDataSchemes() > 1
20954 || filter.countDataTypes() != 0) {
20955 throw new IllegalArgumentException(
20956 "replacePreferredActivity expects filter to have no data authorities, " +
20957 "paths, or types; and at most one scheme.");
20960 final int callingUid = Binder.getCallingUid();
20961 enforceCrossUserPermission(callingUid, userId,
20962 true /* requireFullPermission */, false /* checkShell */,
20963 "replace preferred activity");
20964 synchronized (mPackages) {
20965 if (mContext.checkCallingOrSelfPermission(
20966 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
20967 != PackageManager.PERMISSION_GRANTED) {
20968 if (getUidTargetSdkVersionLockedLPr(callingUid)
20969 < Build.VERSION_CODES.FROYO) {
20970 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
20971 + Binder.getCallingUid());
20974 mContext.enforceCallingOrSelfPermission(
20975 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20978 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
20980 // Get all of the existing entries that exactly match this filter.
20981 ArrayList<PreferredActivity> existing = pir.findFilters(filter);
20982 if (existing != null && existing.size() == 1) {
20983 PreferredActivity cur = existing.get(0);
20984 if (DEBUG_PREFERRED) {
20985 Slog.i(TAG, "Checking replace of preferred:");
20986 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
20987 if (!cur.mPref.mAlways) {
20988 Slog.i(TAG, " -- CUR; not mAlways!");
20990 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch);
20991 Slog.i(TAG, " -- CUR: mSet="
20992 + Arrays.toString(cur.mPref.mSetComponents));
20993 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent);
20994 Slog.i(TAG, " -- NEW: mMatch="
20995 + (match&IntentFilter.MATCH_CATEGORY_MASK));
20996 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set));
20997 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString());
21000 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
21001 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
21002 && cur.mPref.sameSet(set)) {
21003 // Setting the preferred activity to what it happens to be already
21004 if (DEBUG_PREFERRED) {
21005 Slog.i(TAG, "Replacing with same preferred activity "
21006 + cur.mPref.mShortComponent + " for user "
21008 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
21014 if (existing != null) {
21015 if (DEBUG_PREFERRED) {
21016 Slog.i(TAG, existing.size() + " existing preferred matches for:");
21017 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
21019 for (int i = 0; i < existing.size(); i++) {
21020 PreferredActivity pa = existing.get(i);
21021 if (DEBUG_PREFERRED) {
21022 Slog.i(TAG, "Removing existing preferred activity "
21023 + pa.mPref.mComponent + ":");
21024 pa.dump(new LogPrinter(Log.INFO, TAG), " ");
21026 pir.removeFilter(pa);
21030 addPreferredActivityInternal(filter, match, set, activity, true, userId,
21031 "Replacing preferred");
21036 public void clearPackagePreferredActivities(String packageName) {
21037 final int callingUid = Binder.getCallingUid();
21038 if (getInstantAppPackageName(callingUid) != null) {
21042 synchronized (mPackages) {
21043 PackageParser.Package pkg = mPackages.get(packageName);
21044 if (pkg == null || pkg.applicationInfo.uid != callingUid) {
21045 if (mContext.checkCallingOrSelfPermission(
21046 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
21047 != PackageManager.PERMISSION_GRANTED) {
21048 if (getUidTargetSdkVersionLockedLPr(callingUid)
21049 < Build.VERSION_CODES.FROYO) {
21050 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
21054 mContext.enforceCallingOrSelfPermission(
21055 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
21058 final PackageSetting ps = mSettings.getPackageLPr(packageName);
21060 && filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
21063 int user = UserHandle.getCallingUserId();
21064 if (clearPackagePreferredActivitiesLPw(packageName, user)) {
21065 scheduleWritePackageRestrictionsLocked(user);
21070 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
21071 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
21072 ArrayList<PreferredActivity> removed = null;
21073 boolean changed = false;
21074 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
21075 final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
21076 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
21077 if (userId != UserHandle.USER_ALL && userId != thisUserId) {
21080 Iterator<PreferredActivity> it = pir.filterIterator();
21081 while (it.hasNext()) {
21082 PreferredActivity pa = it.next();
21083 // Mark entry for removal only if it matches the package name
21084 // and the entry is of type "always".
21085 if (packageName == null ||
21086 (pa.mPref.mComponent.getPackageName().equals(packageName)
21087 && pa.mPref.mAlways)) {
21088 if (removed == null) {
21089 removed = new ArrayList<PreferredActivity>();
21094 if (removed != null) {
21095 for (int j=0; j<removed.size(); j++) {
21096 PreferredActivity pa = removed.get(j);
21097 pir.removeFilter(pa);
21103 postPreferredActivityChangedBroadcast(userId);
21108 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
21109 private void clearIntentFilterVerificationsLPw(int userId) {
21110 final int packageCount = mPackages.size();
21111 for (int i = 0; i < packageCount; i++) {
21112 PackageParser.Package pkg = mPackages.valueAt(i);
21113 clearIntentFilterVerificationsLPw(pkg.packageName, userId);
21117 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
21118 void clearIntentFilterVerificationsLPw(String packageName, int userId) {
21119 if (userId == UserHandle.USER_ALL) {
21120 if (mSettings.removeIntentFilterVerificationLPw(packageName,
21121 sUserManager.getUserIds())) {
21122 for (int oneUserId : sUserManager.getUserIds()) {
21123 scheduleWritePackageRestrictionsLocked(oneUserId);
21127 if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
21128 scheduleWritePackageRestrictionsLocked(userId);
21133 /** Clears state for all users, and touches intent filter verification policy */
21134 void clearDefaultBrowserIfNeeded(String packageName) {
21135 for (int oneUserId : sUserManager.getUserIds()) {
21136 clearDefaultBrowserIfNeededForUser(packageName, oneUserId);
21140 private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
21141 final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
21142 if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
21143 if (packageName.equals(defaultBrowserPackageName)) {
21144 setDefaultBrowserPackageName(null, userId);
21150 public void resetApplicationPreferences(int userId) {
21151 mContext.enforceCallingOrSelfPermission(
21152 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
21153 final long identity = Binder.clearCallingIdentity();
21156 synchronized (mPackages) {
21157 clearPackagePreferredActivitiesLPw(null, userId);
21158 mSettings.applyDefaultPreferredAppsLPw(this, userId);
21159 // TODO: We have to reset the default SMS and Phone. This requires
21160 // significant refactoring to keep all default apps in the package
21161 // manager (cleaner but more work) or have the services provide
21162 // callbacks to the package manager to request a default app reset.
21163 applyFactoryDefaultBrowserLPw(userId);
21164 clearIntentFilterVerificationsLPw(userId);
21165 primeDomainVerificationsLPw(userId);
21166 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
21167 scheduleWritePackageRestrictionsLocked(userId);
21169 resetNetworkPolicies(userId);
21171 Binder.restoreCallingIdentity(identity);
21176 public int getPreferredActivities(List<IntentFilter> outFilters,
21177 List<ComponentName> outActivities, String packageName) {
21178 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
21182 final int userId = UserHandle.getCallingUserId();
21184 synchronized (mPackages) {
21185 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
21187 final Iterator<PreferredActivity> it = pir.filterIterator();
21188 while (it.hasNext()) {
21189 final PreferredActivity pa = it.next();
21190 if (packageName == null
21191 || (pa.mPref.mComponent.getPackageName().equals(packageName)
21192 && pa.mPref.mAlways)) {
21193 if (outFilters != null) {
21194 outFilters.add(new IntentFilter(pa));
21196 if (outActivities != null) {
21197 outActivities.add(pa.mPref.mComponent);
21208 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
21210 int callingUid = Binder.getCallingUid();
21211 if (callingUid != Process.SYSTEM_UID) {
21212 throw new SecurityException(
21213 "addPersistentPreferredActivity can only be run by the system");
21215 if (filter.countActions() == 0) {
21216 Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
21219 synchronized (mPackages) {
21220 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
21222 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
21223 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
21224 new PersistentPreferredActivity(filter, activity));
21225 scheduleWritePackageRestrictionsLocked(userId);
21226 postPreferredActivityChangedBroadcast(userId);
21231 public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
21232 int callingUid = Binder.getCallingUid();
21233 if (callingUid != Process.SYSTEM_UID) {
21234 throw new SecurityException(
21235 "clearPackagePersistentPreferredActivities can only be run by the system");
21237 ArrayList<PersistentPreferredActivity> removed = null;
21238 boolean changed = false;
21239 synchronized (mPackages) {
21240 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
21241 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
21242 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
21244 if (userId != thisUserId) {
21247 Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
21248 while (it.hasNext()) {
21249 PersistentPreferredActivity ppa = it.next();
21250 // Mark entry for removal only if it matches the package name.
21251 if (ppa.mComponent.getPackageName().equals(packageName)) {
21252 if (removed == null) {
21253 removed = new ArrayList<PersistentPreferredActivity>();
21258 if (removed != null) {
21259 for (int j=0; j<removed.size(); j++) {
21260 PersistentPreferredActivity ppa = removed.get(j);
21261 ppir.removeFilter(ppa);
21268 scheduleWritePackageRestrictionsLocked(userId);
21269 postPreferredActivityChangedBroadcast(userId);
21275 * Common machinery for picking apart a restored XML blob and passing
21276 * it to a caller-supplied functor to be applied to the running system.
21278 private void restoreFromXml(XmlPullParser parser, int userId,
21279 String expectedStartTag, BlobXmlRestorer functor)
21280 throws IOException, XmlPullParserException {
21282 while ((type = parser.next()) != XmlPullParser.START_TAG
21283 && type != XmlPullParser.END_DOCUMENT) {
21285 if (type != XmlPullParser.START_TAG) {
21286 // oops didn't find a start tag?!
21287 if (DEBUG_BACKUP) {
21288 Slog.e(TAG, "Didn't find start tag during restore");
21292 Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
21293 // this is supposed to be TAG_PREFERRED_BACKUP
21294 if (!expectedStartTag.equals(parser.getName())) {
21295 if (DEBUG_BACKUP) {
21296 Slog.e(TAG, "Found unexpected tag " + parser.getName());
21301 // skip interfering stuff, then we're aligned with the backing implementation
21302 while ((type = parser.next()) == XmlPullParser.TEXT) { }
21303 Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
21304 functor.apply(parser, userId);
21307 private interface BlobXmlRestorer {
21308 public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
21312 * Non-Binder method, support for the backup/restore mechanism: write the
21313 * full set of preferred activities in its canonical XML format. Returns the
21314 * XML output as a byte array, or null if there is none.
21317 public byte[] getPreferredActivityBackup(int userId) {
21318 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21319 throw new SecurityException("Only the system may call getPreferredActivityBackup()");
21322 ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
21324 final XmlSerializer serializer = new FastXmlSerializer();
21325 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
21326 serializer.startDocument(null, true);
21327 serializer.startTag(null, TAG_PREFERRED_BACKUP);
21329 synchronized (mPackages) {
21330 mSettings.writePreferredActivitiesLPr(serializer, userId, true);
21333 serializer.endTag(null, TAG_PREFERRED_BACKUP);
21334 serializer.endDocument();
21335 serializer.flush();
21336 } catch (Exception e) {
21337 if (DEBUG_BACKUP) {
21338 Slog.e(TAG, "Unable to write preferred activities for backup", e);
21343 return dataStream.toByteArray();
21347 public void restorePreferredActivities(byte[] backup, int userId) {
21348 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21349 throw new SecurityException("Only the system may call restorePreferredActivities()");
21353 final XmlPullParser parser = Xml.newPullParser();
21354 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
21355 restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
21356 new BlobXmlRestorer() {
21358 public void apply(XmlPullParser parser, int userId)
21359 throws XmlPullParserException, IOException {
21360 synchronized (mPackages) {
21361 mSettings.readPreferredActivitiesLPw(parser, userId);
21365 } catch (Exception e) {
21366 if (DEBUG_BACKUP) {
21367 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
21373 * Non-Binder method, support for the backup/restore mechanism: write the
21374 * default browser (etc) settings in its canonical XML format. Returns the default
21375 * browser XML representation as a byte array, or null if there is none.
21378 public byte[] getDefaultAppsBackup(int userId) {
21379 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21380 throw new SecurityException("Only the system may call getDefaultAppsBackup()");
21383 ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
21385 final XmlSerializer serializer = new FastXmlSerializer();
21386 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
21387 serializer.startDocument(null, true);
21388 serializer.startTag(null, TAG_DEFAULT_APPS);
21390 synchronized (mPackages) {
21391 mSettings.writeDefaultAppsLPr(serializer, userId);
21394 serializer.endTag(null, TAG_DEFAULT_APPS);
21395 serializer.endDocument();
21396 serializer.flush();
21397 } catch (Exception e) {
21398 if (DEBUG_BACKUP) {
21399 Slog.e(TAG, "Unable to write default apps for backup", e);
21404 return dataStream.toByteArray();
21408 public void restoreDefaultApps(byte[] backup, int userId) {
21409 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21410 throw new SecurityException("Only the system may call restoreDefaultApps()");
21414 final XmlPullParser parser = Xml.newPullParser();
21415 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
21416 restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
21417 new BlobXmlRestorer() {
21419 public void apply(XmlPullParser parser, int userId)
21420 throws XmlPullParserException, IOException {
21421 synchronized (mPackages) {
21422 mSettings.readDefaultAppsLPw(parser, userId);
21426 } catch (Exception e) {
21427 if (DEBUG_BACKUP) {
21428 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
21434 public byte[] getIntentFilterVerificationBackup(int userId) {
21435 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21436 throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
21439 ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
21441 final XmlSerializer serializer = new FastXmlSerializer();
21442 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
21443 serializer.startDocument(null, true);
21444 serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
21446 synchronized (mPackages) {
21447 mSettings.writeAllDomainVerificationsLPr(serializer, userId);
21450 serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
21451 serializer.endDocument();
21452 serializer.flush();
21453 } catch (Exception e) {
21454 if (DEBUG_BACKUP) {
21455 Slog.e(TAG, "Unable to write default apps for backup", e);
21460 return dataStream.toByteArray();
21464 public void restoreIntentFilterVerification(byte[] backup, int userId) {
21465 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21466 throw new SecurityException("Only the system may call restorePreferredActivities()");
21470 final XmlPullParser parser = Xml.newPullParser();
21471 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
21472 restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
21473 new BlobXmlRestorer() {
21475 public void apply(XmlPullParser parser, int userId)
21476 throws XmlPullParserException, IOException {
21477 synchronized (mPackages) {
21478 mSettings.readAllDomainVerificationsLPr(parser, userId);
21479 mSettings.writeLPr();
21483 } catch (Exception e) {
21484 if (DEBUG_BACKUP) {
21485 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
21491 public byte[] getPermissionGrantBackup(int userId) {
21492 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21493 throw new SecurityException("Only the system may call getPermissionGrantBackup()");
21496 ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
21498 final XmlSerializer serializer = new FastXmlSerializer();
21499 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
21500 serializer.startDocument(null, true);
21501 serializer.startTag(null, TAG_PERMISSION_BACKUP);
21503 synchronized (mPackages) {
21504 serializeRuntimePermissionGrantsLPr(serializer, userId);
21507 serializer.endTag(null, TAG_PERMISSION_BACKUP);
21508 serializer.endDocument();
21509 serializer.flush();
21510 } catch (Exception e) {
21511 if (DEBUG_BACKUP) {
21512 Slog.e(TAG, "Unable to write default apps for backup", e);
21517 return dataStream.toByteArray();
21521 public void restorePermissionGrants(byte[] backup, int userId) {
21522 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21523 throw new SecurityException("Only the system may call restorePermissionGrants()");
21527 final XmlPullParser parser = Xml.newPullParser();
21528 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
21529 restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
21530 new BlobXmlRestorer() {
21532 public void apply(XmlPullParser parser, int userId)
21533 throws XmlPullParserException, IOException {
21534 synchronized (mPackages) {
21535 processRestoredPermissionGrantsLPr(parser, userId);
21539 } catch (Exception e) {
21540 if (DEBUG_BACKUP) {
21541 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
21546 private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
21547 throws IOException {
21548 serializer.startTag(null, TAG_ALL_GRANTS);
21550 final int N = mSettings.mPackages.size();
21551 for (int i = 0; i < N; i++) {
21552 final PackageSetting ps = mSettings.mPackages.valueAt(i);
21553 boolean pkgGrantsKnown = false;
21555 PermissionsState packagePerms = ps.getPermissionsState();
21557 for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
21558 final int grantFlags = state.getFlags();
21559 // only look at grants that are not system/policy fixed
21560 if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
21561 final boolean isGranted = state.isGranted();
21562 // And only back up the user-twiddled state bits
21563 if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
21564 final String packageName = mSettings.mPackages.keyAt(i);
21565 if (!pkgGrantsKnown) {
21566 serializer.startTag(null, TAG_GRANT);
21567 serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
21568 pkgGrantsKnown = true;
21571 final boolean userSet =
21572 (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
21573 final boolean userFixed =
21574 (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
21575 final boolean revoke =
21576 (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
21578 serializer.startTag(null, TAG_PERMISSION);
21579 serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
21581 serializer.attribute(null, ATTR_IS_GRANTED, "true");
21584 serializer.attribute(null, ATTR_USER_SET, "true");
21587 serializer.attribute(null, ATTR_USER_FIXED, "true");
21590 serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
21592 serializer.endTag(null, TAG_PERMISSION);
21597 if (pkgGrantsKnown) {
21598 serializer.endTag(null, TAG_GRANT);
21602 serializer.endTag(null, TAG_ALL_GRANTS);
21605 private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
21606 throws XmlPullParserException, IOException {
21607 String pkgName = null;
21608 int outerDepth = parser.getDepth();
21610 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
21611 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
21612 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
21616 final String tagName = parser.getName();
21617 if (tagName.equals(TAG_GRANT)) {
21618 pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
21619 if (DEBUG_BACKUP) {
21620 Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
21622 } else if (tagName.equals(TAG_PERMISSION)) {
21624 final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
21625 final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
21627 int newFlagSet = 0;
21628 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
21629 newFlagSet |= FLAG_PERMISSION_USER_SET;
21631 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
21632 newFlagSet |= FLAG_PERMISSION_USER_FIXED;
21634 if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
21635 newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
21637 if (DEBUG_BACKUP) {
21638 Slog.v(TAG, " + Restoring grant: pkg=" + pkgName + " perm=" + permName
21639 + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet));
21641 final PackageSetting ps = mSettings.mPackages.get(pkgName);
21643 // Already installed so we apply the grant immediately
21644 if (DEBUG_BACKUP) {
21645 Slog.v(TAG, " + already installed; applying");
21647 PermissionsState perms = ps.getPermissionsState();
21648 BasePermission bp = mSettings.mPermissions.get(permName);
21651 perms.grantRuntimePermission(bp, userId);
21653 if (newFlagSet != 0) {
21654 perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
21658 // Need to wait for post-restore install to apply the grant
21659 if (DEBUG_BACKUP) {
21660 Slog.v(TAG, " - not yet installed; saving for later");
21662 mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
21663 isGranted, newFlagSet, userId);
21666 PackageManagerService.reportSettingsProblem(Log.WARN,
21667 "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
21668 XmlUtils.skipCurrentTag(parser);
21672 scheduleWriteSettingsLocked();
21673 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
21677 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
21678 int sourceUserId, int targetUserId, int flags) {
21679 mContext.enforceCallingOrSelfPermission(
21680 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
21681 int callingUid = Binder.getCallingUid();
21682 enforceOwnerRights(ownerPackage, callingUid);
21683 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
21684 if (intentFilter.countActions() == 0) {
21685 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
21688 synchronized (mPackages) {
21689 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
21690 ownerPackage, targetUserId, flags);
21691 CrossProfileIntentResolver resolver =
21692 mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
21693 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
21694 // We have all those whose filter is equal. Now checking if the rest is equal as well.
21695 if (existing != null) {
21696 int size = existing.size();
21697 for (int i = 0; i < size; i++) {
21698 if (newFilter.equalsIgnoreFilter(existing.get(i))) {
21703 resolver.addFilter(newFilter);
21704 scheduleWritePackageRestrictionsLocked(sourceUserId);
21709 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
21710 mContext.enforceCallingOrSelfPermission(
21711 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
21712 final int callingUid = Binder.getCallingUid();
21713 enforceOwnerRights(ownerPackage, callingUid);
21714 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
21715 synchronized (mPackages) {
21716 CrossProfileIntentResolver resolver =
21717 mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
21718 ArraySet<CrossProfileIntentFilter> set =
21719 new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
21720 for (CrossProfileIntentFilter filter : set) {
21721 if (filter.getOwnerPackage().equals(ownerPackage)) {
21722 resolver.removeFilter(filter);
21725 scheduleWritePackageRestrictionsLocked(sourceUserId);
21729 // Enforcing that callingUid is owning pkg on userId
21730 private void enforceOwnerRights(String pkg, int callingUid) {
21731 // The system owns everything.
21732 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
21735 final int callingUserId = UserHandle.getUserId(callingUid);
21736 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
21738 throw new IllegalArgumentException("Unknown package " + pkg + " on user "
21741 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
21742 throw new SecurityException("Calling uid " + callingUid
21743 + " does not own package " + pkg);
21748 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
21749 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
21752 return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
21755 public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
21756 UserManagerService ums = UserManagerService.getInstance();
21758 final UserInfo parent = ums.getProfileParent(userId);
21759 final int launcherUid = (parent != null) ? parent.id : userId;
21760 final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
21761 if (launcherComponent != null) {
21762 Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
21763 .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
21764 .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
21765 .setPackage(launcherComponent.getPackageName());
21766 mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUid));
21772 * Report the 'Home' activity which is currently set as "always use this one". If non is set
21773 * then reports the most likely home activity or null if there are more than one.
21775 private ComponentName getDefaultHomeActivity(int userId) {
21776 List<ResolveInfo> allHomeCandidates = new ArrayList<>();
21777 ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
21782 // Find the launcher with the highest priority and return that component if there are no
21783 // other home activity with the same priority.
21784 int lastPriority = Integer.MIN_VALUE;
21785 ComponentName lastComponent = null;
21786 final int size = allHomeCandidates.size();
21787 for (int i = 0; i < size; i++) {
21788 final ResolveInfo ri = allHomeCandidates.get(i);
21789 if (ri.priority > lastPriority) {
21790 lastComponent = ri.activityInfo.getComponentName();
21791 lastPriority = ri.priority;
21792 } else if (ri.priority == lastPriority) {
21793 // Two components found with same priority.
21794 lastComponent = null;
21797 return lastComponent;
21800 private Intent getHomeIntent() {
21801 Intent intent = new Intent(Intent.ACTION_MAIN);
21802 intent.addCategory(Intent.CATEGORY_HOME);
21803 intent.addCategory(Intent.CATEGORY_DEFAULT);
21807 private IntentFilter getHomeFilter() {
21808 IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
21809 filter.addCategory(Intent.CATEGORY_HOME);
21810 filter.addCategory(Intent.CATEGORY_DEFAULT);
21814 ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
21816 Intent intent = getHomeIntent();
21817 List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
21818 PackageManager.GET_META_DATA, userId);
21819 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
21820 true, false, false, userId);
21822 allHomeCandidates.clear();
21823 if (list != null) {
21824 for (ResolveInfo ri : list) {
21825 allHomeCandidates.add(ri);
21828 return (preferred == null || preferred.activityInfo == null)
21830 : new ComponentName(preferred.activityInfo.packageName,
21831 preferred.activityInfo.name);
21835 public void setHomeActivity(ComponentName comp, int userId) {
21836 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
21839 ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
21840 getHomeActivitiesAsUser(homeActivities, userId);
21842 boolean found = false;
21844 final int size = homeActivities.size();
21845 final ComponentName[] set = new ComponentName[size];
21846 for (int i = 0; i < size; i++) {
21847 final ResolveInfo candidate = homeActivities.get(i);
21848 final ActivityInfo info = candidate.activityInfo;
21849 final ComponentName activityName = new ComponentName(info.packageName, info.name);
21850 set[i] = activityName;
21851 if (!found && activityName.equals(comp)) {
21856 throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
21859 replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
21860 set, comp, userId);
21863 private @Nullable String getSetupWizardPackageName() {
21864 final Intent intent = new Intent(Intent.ACTION_MAIN);
21865 intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
21867 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
21868 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
21869 | MATCH_DISABLED_COMPONENTS,
21870 UserHandle.myUserId());
21871 if (matches.size() == 1) {
21872 return matches.get(0).getComponentInfo().packageName;
21874 Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
21875 + ": matches=" + matches);
21880 private @Nullable String getStorageManagerPackageName() {
21881 final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
21883 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
21884 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
21885 | MATCH_DISABLED_COMPONENTS,
21886 UserHandle.myUserId());
21887 if (matches.size() == 1) {
21888 return matches.get(0).getComponentInfo().packageName;
21890 Slog.e(TAG, "There should probably be exactly one storage manager; found "
21891 + matches.size() + ": matches=" + matches);
21897 public void setApplicationEnabledSetting(String appPackageName,
21898 int newState, int flags, int userId, String callingPackage) {
21899 if (!sUserManager.exists(userId)) return;
21900 if (callingPackage == null) {
21901 callingPackage = Integer.toString(Binder.getCallingUid());
21903 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
21907 public void setUpdateAvailable(String packageName, boolean updateAvailable) {
21908 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
21909 synchronized (mPackages) {
21910 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
21911 if (pkgSetting != null) {
21912 pkgSetting.setUpdateAvailable(updateAvailable);
21918 public void setComponentEnabledSetting(ComponentName componentName,
21919 int newState, int flags, int userId) {
21920 if (!sUserManager.exists(userId)) return;
21921 setEnabledSetting(componentName.getPackageName(),
21922 componentName.getClassName(), newState, flags, userId, null);
21925 private void setEnabledSetting(final String packageName, String className, int newState,
21926 final int flags, int userId, String callingPackage) {
21927 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
21928 || newState == COMPONENT_ENABLED_STATE_ENABLED
21929 || newState == COMPONENT_ENABLED_STATE_DISABLED
21930 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
21931 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
21932 throw new IllegalArgumentException("Invalid new component state: "
21935 PackageSetting pkgSetting;
21936 final int callingUid = Binder.getCallingUid();
21937 final int permission;
21938 if (callingUid == Process.SYSTEM_UID) {
21939 permission = PackageManager.PERMISSION_GRANTED;
21941 permission = mContext.checkCallingOrSelfPermission(
21942 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
21944 enforceCrossUserPermission(callingUid, userId,
21945 false /* requireFullPermission */, true /* checkShell */, "set enabled");
21946 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
21947 boolean sendNow = false;
21948 boolean isApp = (className == null);
21949 final boolean isCallerInstantApp = (getInstantAppPackageName(callingUid) != null);
21950 String componentName = isApp ? packageName : className;
21951 int packageUid = -1;
21952 ArrayList<String> components;
21955 synchronized (mPackages) {
21956 pkgSetting = mSettings.mPackages.get(packageName);
21957 if (pkgSetting == null) {
21958 if (!isCallerInstantApp) {
21959 if (className == null) {
21960 throw new IllegalArgumentException("Unknown package: " + packageName);
21962 throw new IllegalArgumentException(
21963 "Unknown component: " + packageName + "/" + className);
21965 // throw SecurityException to prevent leaking package information
21966 throw new SecurityException(
21967 "Attempt to change component state; "
21968 + "pid=" + Binder.getCallingPid()
21969 + ", uid=" + callingUid
21970 + (className == null
21971 ? ", package=" + packageName
21972 : ", component=" + packageName + "/" + className));
21977 // Limit who can change which apps
21978 if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
21979 // Don't allow apps that don't have permission to modify other apps
21980 if (!allowedByPermission
21981 || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
21982 throw new SecurityException(
21983 "Attempt to change component state; "
21984 + "pid=" + Binder.getCallingPid()
21985 + ", uid=" + callingUid
21986 + (className == null
21987 ? ", package=" + packageName
21988 : ", component=" + packageName + "/" + className));
21990 // Don't allow changing protected packages.
21991 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
21992 throw new SecurityException("Cannot disable a protected package: " + packageName);
21996 synchronized (mPackages) {
21997 if (callingUid == Process.SHELL_UID
21998 && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
21999 // Shell can only change whole packages between ENABLED and DISABLED_USER states
22000 // unless it is a test package.
22001 int oldState = pkgSetting.getEnabled(userId);
22002 if (className == null
22004 (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
22005 || oldState == COMPONENT_ENABLED_STATE_DEFAULT
22006 || oldState == COMPONENT_ENABLED_STATE_ENABLED)
22008 (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
22009 || newState == COMPONENT_ENABLED_STATE_DEFAULT
22010 || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
22013 throw new SecurityException(
22014 "Shell cannot change component state for " + packageName + "/"
22015 + className + " to " + newState);
22019 if (className == null) {
22020 // We're dealing with an application/package level state change
22021 synchronized (mPackages) {
22022 if (pkgSetting.getEnabled(userId) == newState) {
22027 // If we're enabling a system stub, there's a little more work to do.
22028 // Prior to enabling the package, we need to decompress the APK(s) to the
22029 // data partition and then replace the version on the system partition.
22030 final PackageParser.Package deletedPkg = pkgSetting.pkg;
22031 final boolean isSystemStub = deletedPkg.isStub
22032 && deletedPkg.isSystemApp();
22034 && (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
22035 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED)) {
22036 final File codePath = decompressPackage(deletedPkg);
22037 if (codePath == null) {
22038 Slog.e(TAG, "couldn't decompress pkg: " + pkgSetting.name);
22041 // TODO remove direct parsing of the package object during internal cleanup
22043 // We need to call parse directly here for no other reason than we need
22044 // the new package in order to disable the old one [we use the information
22045 // for some internal optimization to optionally create a new package setting
22046 // object on replace]. However, we can't get the package from the scan
22047 // because the scan modifies live structures and we need to remove the
22048 // old [system] package from the system before a scan can be attempted.
22049 // Once scan is indempotent we can remove this parse and use the package
22050 // object we scanned, prior to adding it to package settings.
22051 final PackageParser pp = new PackageParser();
22052 pp.setSeparateProcesses(mSeparateProcesses);
22053 pp.setDisplayMetrics(mMetrics);
22054 pp.setCallback(mPackageParserCallback);
22055 final PackageParser.Package tmpPkg;
22057 final int parseFlags = mDefParseFlags
22058 | PackageParser.PARSE_MUST_BE_APK
22059 | PackageParser.PARSE_IS_SYSTEM
22060 | PackageParser.PARSE_IS_SYSTEM_DIR;
22061 tmpPkg = pp.parsePackage(codePath, parseFlags);
22062 } catch (PackageParserException e) {
22063 Slog.w(TAG, "Failed to parse compressed system package:" + pkgSetting.name, e);
22066 synchronized (mInstallLock) {
22067 // Disable the stub and remove any package entries
22068 removePackageLI(deletedPkg, true);
22069 synchronized (mPackages) {
22070 disableSystemPackageLPw(deletedPkg, tmpPkg);
22072 final PackageParser.Package newPkg;
22073 try (PackageFreezer freezer =
22074 freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
22075 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
22076 | PackageParser.PARSE_ENFORCE_CODE;
22077 newPkg = scanPackageTracedLI(codePath, parseFlags, 0 /*scanFlags*/,
22078 0 /*currentTime*/, null /*user*/);
22079 prepareAppDataAfterInstallLIF(newPkg);
22080 synchronized (mPackages) {
22082 updateSharedLibrariesLPr(newPkg, null);
22083 } catch (PackageManagerException e) {
22084 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: ", e);
22086 updatePermissionsLPw(newPkg.packageName, newPkg,
22087 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
22088 mSettings.writeLPr();
22090 } catch (PackageManagerException e) {
22091 // Whoops! Something went wrong; try to roll back to the stub
22092 Slog.w(TAG, "Failed to install compressed system package:"
22093 + pkgSetting.name, e);
22094 // Remove the failed install
22095 removeCodePathLI(codePath);
22097 // Install the system package
22098 try (PackageFreezer freezer =
22099 freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
22100 synchronized (mPackages) {
22101 // NOTE: The system package always needs to be enabled; even
22102 // if it's for a compressed stub. If we don't, installing the
22103 // system package fails during scan [scanning checks the disabled
22104 // packages]. We will reverse this later, after we've "installed"
22106 // This leaves us in a fragile state; the stub should never be
22107 // enabled, so, cross your fingers and hope nothing goes wrong
22108 // until we can disable the package later.
22109 enableSystemPackageLPw(deletedPkg);
22111 installPackageFromSystemLIF(new File(deletedPkg.codePath),
22112 false /*isPrivileged*/, null /*allUserHandles*/,
22113 null /*origUserHandles*/, null /*origPermissionsState*/,
22114 true /*writeSettings*/);
22115 } catch (PackageManagerException pme) {
22116 Slog.w(TAG, "Failed to restore system package:"
22117 + deletedPkg.packageName, pme);
22119 synchronized (mPackages) {
22120 mSettings.disableSystemPackageLPw(
22121 deletedPkg.packageName, true /*replaced*/);
22122 mSettings.writeLPr();
22127 clearAppDataLIF(newPkg, UserHandle.USER_ALL, FLAG_STORAGE_DE
22128 | FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
22129 clearAppProfilesLIF(newPkg, UserHandle.USER_ALL);
22130 mDexManager.notifyPackageUpdated(newPkg.packageName,
22131 newPkg.baseCodePath, newPkg.splitCodePaths);
22134 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
22135 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
22136 // Don't care about who enables an app.
22137 callingPackage = null;
22139 synchronized (mPackages) {
22140 pkgSetting.setEnabled(newState, userId, callingPackage);
22143 synchronized (mPackages) {
22144 // We're dealing with a component level state change
22145 // First, verify that this is a valid class name.
22146 PackageParser.Package pkg = pkgSetting.pkg;
22147 if (pkg == null || !pkg.hasComponentClassName(className)) {
22149 pkg.applicationInfo.targetSdkVersion >=
22150 Build.VERSION_CODES.JELLY_BEAN) {
22151 throw new IllegalArgumentException("Component class " + className
22152 + " does not exist in " + packageName);
22154 Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
22155 + className + " does not exist in " + packageName);
22158 switch (newState) {
22159 case COMPONENT_ENABLED_STATE_ENABLED:
22160 if (!pkgSetting.enableComponentLPw(className, userId)) {
22164 case COMPONENT_ENABLED_STATE_DISABLED:
22165 if (!pkgSetting.disableComponentLPw(className, userId)) {
22169 case COMPONENT_ENABLED_STATE_DEFAULT:
22170 if (!pkgSetting.restoreComponentLPw(className, userId)) {
22175 Slog.e(TAG, "Invalid new component state: " + newState);
22180 synchronized (mPackages) {
22181 scheduleWritePackageRestrictionsLocked(userId);
22182 updateSequenceNumberLP(pkgSetting, new int[] { userId });
22183 final long callingId = Binder.clearCallingIdentity();
22185 updateInstantAppInstallerLocked(packageName);
22187 Binder.restoreCallingIdentity(callingId);
22189 components = mPendingBroadcasts.get(userId, packageName);
22190 final boolean newPackage = components == null;
22192 components = new ArrayList<String>();
22194 if (!components.contains(componentName)) {
22195 components.add(componentName);
22197 if ((flags&PackageManager.DONT_KILL_APP) == 0) {
22199 // Purge entry from pending broadcast list if another one exists already
22200 // since we are sending one right away.
22201 mPendingBroadcasts.remove(userId, packageName);
22204 mPendingBroadcasts.put(userId, packageName, components);
22206 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
22207 // Schedule a message
22208 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
22213 long callingId = Binder.clearCallingIdentity();
22216 packageUid = UserHandle.getUid(userId, pkgSetting.appId);
22217 sendPackageChangedBroadcast(packageName,
22218 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
22221 Binder.restoreCallingIdentity(callingId);
22226 public void flushPackageRestrictionsAsUser(int userId) {
22227 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
22230 if (!sUserManager.exists(userId)) {
22233 enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
22234 false /* checkShell */, "flushPackageRestrictions");
22235 synchronized (mPackages) {
22236 mSettings.writePackageRestrictionsLPr(userId);
22237 mDirtyUsers.remove(userId);
22238 if (mDirtyUsers.isEmpty()) {
22239 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
22244 private void sendPackageChangedBroadcast(String packageName,
22245 boolean killFlag, ArrayList<String> componentNames, int packageUid) {
22247 Log.v(TAG, "Sending package changed: package=" + packageName + " components="
22249 Bundle extras = new Bundle(4);
22250 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
22251 String nameList[] = new String[componentNames.size()];
22252 componentNames.toArray(nameList);
22253 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
22254 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
22255 extras.putInt(Intent.EXTRA_UID, packageUid);
22256 // If this is not reporting a change of the overall package, then only send it
22257 // to registered receivers. We don't want to launch a swath of apps for every
22258 // little component state change.
22259 final int flags = !componentNames.contains(packageName)
22260 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
22261 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, flags, null, null,
22262 new int[] {UserHandle.getUserId(packageUid)});
22266 public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
22267 if (!sUserManager.exists(userId)) return;
22268 final int callingUid = Binder.getCallingUid();
22269 if (getInstantAppPackageName(callingUid) != null) {
22272 final int permission = mContext.checkCallingOrSelfPermission(
22273 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
22274 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
22275 enforceCrossUserPermission(callingUid, userId,
22276 true /* requireFullPermission */, true /* checkShell */, "stop package");
22278 synchronized (mPackages) {
22279 final PackageSetting ps = mSettings.mPackages.get(packageName);
22280 if (!filterAppAccessLPr(ps, callingUid, userId)
22281 && mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
22282 allowedByPermission, callingUid, userId)) {
22283 scheduleWritePackageRestrictionsLocked(userId);
22289 public String getInstallerPackageName(String packageName) {
22290 final int callingUid = Binder.getCallingUid();
22291 if (getInstantAppPackageName(callingUid) != null) {
22295 synchronized (mPackages) {
22296 final PackageSetting ps = mSettings.mPackages.get(packageName);
22297 if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
22300 return mSettings.getInstallerPackageNameLPr(packageName);
22304 public boolean isOrphaned(String packageName) {
22306 synchronized (mPackages) {
22307 return mSettings.isOrphaned(packageName);
22312 public int getApplicationEnabledSetting(String packageName, int userId) {
22313 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
22314 int callingUid = Binder.getCallingUid();
22315 enforceCrossUserPermission(callingUid, userId,
22316 false /* requireFullPermission */, false /* checkShell */, "get enabled");
22318 synchronized (mPackages) {
22319 if (filterAppAccessLPr(mSettings.getPackageLPr(packageName), callingUid, userId)) {
22320 return COMPONENT_ENABLED_STATE_DISABLED;
22322 return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
22327 public int getComponentEnabledSetting(ComponentName component, int userId) {
22328 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
22329 int callingUid = Binder.getCallingUid();
22330 enforceCrossUserPermission(callingUid, userId,
22331 false /*requireFullPermission*/, false /*checkShell*/, "getComponentEnabled");
22332 synchronized (mPackages) {
22333 if (filterAppAccessLPr(mSettings.getPackageLPr(component.getPackageName()), callingUid,
22334 component, TYPE_UNKNOWN, userId)) {
22335 return COMPONENT_ENABLED_STATE_DISABLED;
22337 return mSettings.getComponentEnabledSettingLPr(component, userId);
22342 public void enterSafeMode() {
22343 enforceSystemOrRoot("Only the system can request entering safe mode");
22345 if (!mSystemReady) {
22351 public void systemReady() {
22352 enforceSystemOrRoot("Only the system can claim the system is ready");
22354 mSystemReady = true;
22355 final ContentResolver resolver = mContext.getContentResolver();
22356 ContentObserver co = new ContentObserver(mHandler) {
22358 public void onChange(boolean selfChange) {
22359 mEphemeralAppsDisabled =
22360 (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) ||
22361 (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0);
22364 mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
22365 .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
22366 false, co, UserHandle.USER_SYSTEM);
22367 mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
22368 .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM);
22371 // Disable any carrier apps. We do this very early in boot to prevent the apps from being
22372 // disabled after already being started.
22373 CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
22374 mContext.getContentResolver(), UserHandle.USER_SYSTEM);
22376 // Read the compatibilty setting when the system is ready.
22377 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
22378 mContext.getContentResolver(),
22379 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
22380 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
22381 if (DEBUG_SETTINGS) {
22382 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
22385 int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
22387 synchronized (mPackages) {
22388 // Verify that all of the preferred activity components actually
22389 // exist. It is possible for applications to be updated and at
22390 // that point remove a previously declared activity component that
22391 // had been set as a preferred activity. We try to clean this up
22392 // the next time we encounter that preferred activity, but it is
22393 // possible for the user flow to never be able to return to that
22394 // situation so here we do a sanity check to make sure we haven't
22395 // left any junk around.
22396 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
22397 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
22398 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
22400 for (PreferredActivity pa : pir.filterSet()) {
22401 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
22405 if (removed.size() > 0) {
22406 for (int r=0; r<removed.size(); r++) {
22407 PreferredActivity pa = removed.get(r);
22408 Slog.w(TAG, "Removing dangling preferred activity: "
22409 + pa.mPref.mComponent);
22410 pir.removeFilter(pa);
22412 mSettings.writePackageRestrictionsLPr(
22413 mSettings.mPreferredActivities.keyAt(i));
22417 for (int userId : UserManagerService.getInstance().getUserIds()) {
22418 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
22419 grantPermissionsUserIds = ArrayUtils.appendInt(
22420 grantPermissionsUserIds, userId);
22424 sUserManager.systemReady();
22426 // If we upgraded grant all default permissions before kicking off.
22427 for (int userId : grantPermissionsUserIds) {
22428 mDefaultPermissionPolicy.grantDefaultPermissions(userId);
22431 // If we did not grant default permissions, we preload from this the
22432 // default permission exceptions lazily to ensure we don't hit the
22433 // disk on a new user creation.
22434 if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
22435 mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
22438 // Kick off any messages waiting for system ready
22439 if (mPostSystemReadyMessages != null) {
22440 for (Message msg : mPostSystemReadyMessages) {
22441 msg.sendToTarget();
22443 mPostSystemReadyMessages = null;
22446 // Watch for external volumes that come and go over time
22447 final StorageManager storage = mContext.getSystemService(StorageManager.class);
22448 storage.registerListener(mStorageListener);
22450 mInstallerService.systemReady();
22451 mPackageDexOptimizer.systemReady();
22453 StorageManagerInternal StorageManagerInternal = LocalServices.getService(
22454 StorageManagerInternal.class);
22455 StorageManagerInternal.addExternalStoragePolicy(
22456 new StorageManagerInternal.ExternalStorageMountPolicy() {
22458 public int getMountMode(int uid, String packageName) {
22459 if (Process.isIsolated(uid)) {
22460 return Zygote.MOUNT_EXTERNAL_NONE;
22462 if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
22463 return Zygote.MOUNT_EXTERNAL_DEFAULT;
22465 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
22466 return Zygote.MOUNT_EXTERNAL_DEFAULT;
22468 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
22469 return Zygote.MOUNT_EXTERNAL_READ;
22471 return Zygote.MOUNT_EXTERNAL_WRITE;
22475 public boolean hasExternalStorage(int uid, String packageName) {
22480 // Now that we're mostly running, clean up stale users and apps
22481 sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
22482 reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
22484 if (mPrivappPermissionsViolations != null) {
22485 Slog.wtf(TAG,"Signature|privileged permissions not in "
22486 + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
22487 mPrivappPermissionsViolations = null;
22491 public void waitForAppDataPrepared() {
22492 if (mPrepareAppDataFuture == null) {
22495 ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
22496 mPrepareAppDataFuture = null;
22500 public boolean isSafeMode() {
22501 // allow instant applications
22506 public boolean hasSystemUidErrors() {
22507 // allow instant applications
22508 return mHasSystemUidErrors;
22511 static String arrayToString(int[] array) {
22512 StringBuffer buf = new StringBuffer(128);
22514 if (array != null) {
22515 for (int i=0; i<array.length; i++) {
22516 if (i > 0) buf.append(", ");
22517 buf.append(array[i]);
22521 return buf.toString();
22524 static class DumpState {
22525 public static final int DUMP_LIBS = 1 << 0;
22526 public static final int DUMP_FEATURES = 1 << 1;
22527 public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2;
22528 public static final int DUMP_SERVICE_RESOLVERS = 1 << 3;
22529 public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4;
22530 public static final int DUMP_CONTENT_RESOLVERS = 1 << 5;
22531 public static final int DUMP_PERMISSIONS = 1 << 6;
22532 public static final int DUMP_PACKAGES = 1 << 7;
22533 public static final int DUMP_SHARED_USERS = 1 << 8;
22534 public static final int DUMP_MESSAGES = 1 << 9;
22535 public static final int DUMP_PROVIDERS = 1 << 10;
22536 public static final int DUMP_VERIFIERS = 1 << 11;
22537 public static final int DUMP_PREFERRED = 1 << 12;
22538 public static final int DUMP_PREFERRED_XML = 1 << 13;
22539 public static final int DUMP_KEYSETS = 1 << 14;
22540 public static final int DUMP_VERSION = 1 << 15;
22541 public static final int DUMP_INSTALLS = 1 << 16;
22542 public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17;
22543 public static final int DUMP_DOMAIN_PREFERRED = 1 << 18;
22544 public static final int DUMP_FROZEN = 1 << 19;
22545 public static final int DUMP_DEXOPT = 1 << 20;
22546 public static final int DUMP_COMPILER_STATS = 1 << 21;
22547 public static final int DUMP_CHANGES = 1 << 22;
22548 public static final int DUMP_VOLUMES = 1 << 23;
22550 public static final int OPTION_SHOW_FILTERS = 1 << 0;
22552 private int mTypes;
22554 private int mOptions;
22556 private boolean mTitlePrinted;
22558 private SharedUserSetting mSharedUser;
22560 public boolean isDumping(int type) {
22561 if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
22565 return (mTypes & type) != 0;
22568 public void setDump(int type) {
22572 public boolean isOptionEnabled(int option) {
22573 return (mOptions & option) != 0;
22576 public void setOptionEnabled(int option) {
22577 mOptions |= option;
22580 public boolean onTitlePrinted() {
22581 final boolean printed = mTitlePrinted;
22582 mTitlePrinted = true;
22586 public boolean getTitlePrinted() {
22587 return mTitlePrinted;
22590 public void setTitlePrinted(boolean enabled) {
22591 mTitlePrinted = enabled;
22594 public SharedUserSetting getSharedUser() {
22595 return mSharedUser;
22598 public void setSharedUser(SharedUserSetting user) {
22599 mSharedUser = user;
22604 public void onShellCommand(FileDescriptor in, FileDescriptor out,
22605 FileDescriptor err, String[] args, ShellCallback callback,
22606 ResultReceiver resultReceiver) {
22607 (new PackageManagerShellCommand(this)).exec(
22608 this, in, out, err, args, callback, resultReceiver);
22612 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
22613 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
22615 DumpState dumpState = new DumpState();
22616 boolean fullPreferred = false;
22617 boolean checkin = false;
22619 String packageName = null;
22620 ArraySet<String> permissionNames = null;
22623 while (opti < args.length) {
22624 String opt = args[opti];
22625 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
22630 if ("-a".equals(opt)) {
22631 // Right now we only know how to print all.
22632 } else if ("-h".equals(opt)) {
22633 pw.println("Package manager dump options:");
22634 pw.println(" [-h] [-f] [--checkin] [cmd] ...");
22635 pw.println(" --checkin: dump for a checkin");
22636 pw.println(" -f: print details of intent filters");
22637 pw.println(" -h: print this help");
22638 pw.println(" cmd may be one of:");
22639 pw.println(" l[ibraries]: list known shared libraries");
22640 pw.println(" f[eatures]: list device features");
22641 pw.println(" k[eysets]: print known keysets");
22642 pw.println(" r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
22643 pw.println(" perm[issions]: dump permissions");
22644 pw.println(" permission [name ...]: dump declaration and use of given permission");
22645 pw.println(" pref[erred]: print preferred package settings");
22646 pw.println(" preferred-xml [--full]: print preferred package settings as xml");
22647 pw.println(" prov[iders]: dump content providers");
22648 pw.println(" p[ackages]: dump installed packages");
22649 pw.println(" s[hared-users]: dump shared user IDs");
22650 pw.println(" m[essages]: print collected runtime messages");
22651 pw.println(" v[erifiers]: print package verifier info");
22652 pw.println(" d[omain-preferred-apps]: print domains preferred apps");
22653 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
22654 pw.println(" version: print database version info");
22655 pw.println(" write: write current settings now");
22656 pw.println(" installs: details about install sessions");
22657 pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?");
22658 pw.println(" dexopt: dump dexopt state");
22659 pw.println(" compiler-stats: dump compiler statistics");
22660 pw.println(" enabled-overlays: dump list of enabled overlay packages");
22661 pw.println(" <package.name>: info about given package");
22663 } else if ("--checkin".equals(opt)) {
22665 } else if ("-f".equals(opt)) {
22666 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
22667 } else if ("--proto".equals(opt)) {
22671 pw.println("Unknown argument: " + opt + "; use -h for help");
22675 // Is the caller requesting to dump a particular piece of data?
22676 if (opti < args.length) {
22677 String cmd = args[opti];
22679 // Is this a package name?
22680 if ("android".equals(cmd) || cmd.contains(".")) {
22682 // When dumping a single package, we always dump all of its
22683 // filter information since the amount of data will be reasonable.
22684 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
22685 } else if ("check-permission".equals(cmd)) {
22686 if (opti >= args.length) {
22687 pw.println("Error: check-permission missing permission argument");
22690 String perm = args[opti];
22692 if (opti >= args.length) {
22693 pw.println("Error: check-permission missing package argument");
22697 String pkg = args[opti];
22699 int user = UserHandle.getUserId(Binder.getCallingUid());
22700 if (opti < args.length) {
22702 user = Integer.parseInt(args[opti]);
22703 } catch (NumberFormatException e) {
22704 pw.println("Error: check-permission user argument is not a number: "
22710 // Normalize package name to handle renamed packages and static libs
22711 pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
22713 pw.println(checkPermission(perm, pkg, user));
22715 } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
22716 dumpState.setDump(DumpState.DUMP_LIBS);
22717 } else if ("f".equals(cmd) || "features".equals(cmd)) {
22718 dumpState.setDump(DumpState.DUMP_FEATURES);
22719 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
22720 if (opti >= args.length) {
22721 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
22722 | DumpState.DUMP_SERVICE_RESOLVERS
22723 | DumpState.DUMP_RECEIVER_RESOLVERS
22724 | DumpState.DUMP_CONTENT_RESOLVERS);
22726 while (opti < args.length) {
22727 String name = args[opti];
22728 if ("a".equals(name) || "activity".equals(name)) {
22729 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
22730 } else if ("s".equals(name) || "service".equals(name)) {
22731 dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
22732 } else if ("r".equals(name) || "receiver".equals(name)) {
22733 dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
22734 } else if ("c".equals(name) || "content".equals(name)) {
22735 dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
22737 pw.println("Error: unknown resolver table type: " + name);
22743 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
22744 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
22745 } else if ("permission".equals(cmd)) {
22746 if (opti >= args.length) {
22747 pw.println("Error: permission requires permission name");
22750 permissionNames = new ArraySet<>();
22751 while (opti < args.length) {
22752 permissionNames.add(args[opti]);
22755 dumpState.setDump(DumpState.DUMP_PERMISSIONS
22756 | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
22757 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
22758 dumpState.setDump(DumpState.DUMP_PREFERRED);
22759 } else if ("preferred-xml".equals(cmd)) {
22760 dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
22761 if (opti < args.length && "--full".equals(args[opti])) {
22762 fullPreferred = true;
22765 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
22766 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
22767 } else if ("p".equals(cmd) || "packages".equals(cmd)) {
22768 dumpState.setDump(DumpState.DUMP_PACKAGES);
22769 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
22770 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
22771 } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
22772 dumpState.setDump(DumpState.DUMP_PROVIDERS);
22773 } else if ("m".equals(cmd) || "messages".equals(cmd)) {
22774 dumpState.setDump(DumpState.DUMP_MESSAGES);
22775 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
22776 dumpState.setDump(DumpState.DUMP_VERIFIERS);
22777 } else if ("i".equals(cmd) || "ifv".equals(cmd)
22778 || "intent-filter-verifiers".equals(cmd)) {
22779 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
22780 } else if ("version".equals(cmd)) {
22781 dumpState.setDump(DumpState.DUMP_VERSION);
22782 } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
22783 dumpState.setDump(DumpState.DUMP_KEYSETS);
22784 } else if ("installs".equals(cmd)) {
22785 dumpState.setDump(DumpState.DUMP_INSTALLS);
22786 } else if ("frozen".equals(cmd)) {
22787 dumpState.setDump(DumpState.DUMP_FROZEN);
22788 } else if ("volumes".equals(cmd)) {
22789 dumpState.setDump(DumpState.DUMP_VOLUMES);
22790 } else if ("dexopt".equals(cmd)) {
22791 dumpState.setDump(DumpState.DUMP_DEXOPT);
22792 } else if ("compiler-stats".equals(cmd)) {
22793 dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
22794 } else if ("changes".equals(cmd)) {
22795 dumpState.setDump(DumpState.DUMP_CHANGES);
22796 } else if ("write".equals(cmd)) {
22797 synchronized (mPackages) {
22798 mSettings.writeLPr();
22799 pw.println("Settings written.");
22806 pw.println("vers,1");
22810 synchronized (mPackages) {
22811 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
22813 if (dumpState.onTitlePrinted())
22815 pw.println("Database versions:");
22816 mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, " "));
22820 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
22822 if (dumpState.onTitlePrinted())
22824 pw.println("Verifiers:");
22825 pw.print(" Required: ");
22826 pw.print(mRequiredVerifierPackage);
22827 pw.print(" (uid=");
22828 pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
22829 UserHandle.USER_SYSTEM));
22831 } else if (mRequiredVerifierPackage != null) {
22832 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
22834 pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
22835 UserHandle.USER_SYSTEM));
22839 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
22840 packageName == null) {
22841 if (mIntentFilterVerifierComponent != null) {
22842 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
22844 if (dumpState.onTitlePrinted())
22846 pw.println("Intent Filter Verifier:");
22847 pw.print(" Using: ");
22848 pw.print(verifierPackageName);
22849 pw.print(" (uid=");
22850 pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
22851 UserHandle.USER_SYSTEM));
22853 } else if (verifierPackageName != null) {
22854 pw.print("ifv,"); pw.print(verifierPackageName);
22856 pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
22857 UserHandle.USER_SYSTEM));
22861 pw.println("No Intent Filter Verifier available!");
22865 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
22866 boolean printedHeader = false;
22867 final Iterator<String> it = mSharedLibraries.keySet().iterator();
22868 while (it.hasNext()) {
22869 String libName = it.next();
22870 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
22871 if (versionedLib == null) {
22874 final int versionCount = versionedLib.size();
22875 for (int i = 0; i < versionCount; i++) {
22876 SharedLibraryEntry libEntry = versionedLib.valueAt(i);
22878 if (!printedHeader) {
22879 if (dumpState.onTitlePrinted())
22881 pw.println("Libraries:");
22882 printedHeader = true;
22888 pw.print(libEntry.info.getName());
22889 if (libEntry.info.isStatic()) {
22890 pw.print(" version=" + libEntry.info.getVersion());
22895 if (libEntry.path != null) {
22896 pw.print(" (jar) ");
22897 pw.print(libEntry.path);
22899 pw.print(" (apk) ");
22900 pw.print(libEntry.apk);
22907 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
22908 if (dumpState.onTitlePrinted())
22911 pw.println("Features:");
22914 synchronized (mAvailableFeatures) {
22915 for (FeatureInfo feat : mAvailableFeatures.values()) {
22918 pw.print(feat.name);
22920 pw.println(feat.version);
22923 pw.print(feat.name);
22924 if (feat.version > 0) {
22925 pw.print(" version=");
22926 pw.print(feat.version);
22934 if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
22935 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
22936 : "Activity Resolver Table:", " ", packageName,
22937 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
22938 dumpState.setTitlePrinted(true);
22941 if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
22942 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
22943 : "Receiver Resolver Table:", " ", packageName,
22944 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
22945 dumpState.setTitlePrinted(true);
22948 if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
22949 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
22950 : "Service Resolver Table:", " ", packageName,
22951 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
22952 dumpState.setTitlePrinted(true);
22955 if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
22956 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
22957 : "Provider Resolver Table:", " ", packageName,
22958 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
22959 dumpState.setTitlePrinted(true);
22963 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
22964 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
22965 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
22966 int user = mSettings.mPreferredActivities.keyAt(i);
22968 dumpState.getTitlePrinted()
22969 ? "\nPreferred Activities User " + user + ":"
22970 : "Preferred Activities User " + user + ":", " ",
22971 packageName, true, false)) {
22972 dumpState.setTitlePrinted(true);
22977 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
22979 FileOutputStream fout = new FileOutputStream(fd);
22980 BufferedOutputStream str = new BufferedOutputStream(fout);
22981 XmlSerializer serializer = new FastXmlSerializer();
22983 serializer.setOutput(str, StandardCharsets.UTF_8.name());
22984 serializer.startDocument(null, true);
22985 serializer.setFeature(
22986 "http://xmlpull.org/v1/doc/features.html#indent-output", true);
22987 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
22988 serializer.endDocument();
22989 serializer.flush();
22990 } catch (IllegalArgumentException e) {
22991 pw.println("Failed writing: " + e);
22992 } catch (IllegalStateException e) {
22993 pw.println("Failed writing: " + e);
22994 } catch (IOException e) {
22995 pw.println("Failed writing: " + e);
23000 && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
23001 && packageName == null) {
23003 int count = mSettings.mPackages.size();
23005 pw.println("No applications!");
23008 final String prefix = " ";
23009 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
23010 if (allPackageSettings.size() == 0) {
23011 pw.println("No domain preferred apps!");
23014 pw.println("App verification status:");
23017 for (PackageSetting ps : allPackageSettings) {
23018 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
23019 if (ivi == null || ivi.getPackageName() == null) continue;
23020 pw.println(prefix + "Package: " + ivi.getPackageName());
23021 pw.println(prefix + "Domains: " + ivi.getDomainsString());
23022 pw.println(prefix + "Status: " + ivi.getStatusString());
23027 pw.println(prefix + "No app verification established.");
23030 for (int userId : sUserManager.getUserIds()) {
23031 pw.println("App linkages for user " + userId + ":");
23034 for (PackageSetting ps : allPackageSettings) {
23035 final long status = ps.getDomainVerificationStatusForUser(userId);
23036 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
23037 && !DEBUG_DOMAIN_VERIFICATION) {
23040 pw.println(prefix + "Package: " + ps.name);
23041 pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
23042 String statusStr = IntentFilterVerificationInfo.
23043 getStatusStringFromValue(status);
23044 pw.println(prefix + "Status: " + statusStr);
23049 pw.println(prefix + "No configured app linkages.");
23057 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
23058 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
23059 if (packageName == null && permissionNames == null) {
23060 for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
23062 if (dumpState.onTitlePrinted())
23064 pw.println("AppOp Permissions:");
23066 pw.print(" AppOp Permission ");
23067 pw.print(mAppOpPermissionPackages.keyAt(iperm));
23069 ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
23070 for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
23071 pw.print(" "); pw.println(pkgs.valueAt(ipkg));
23077 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
23078 boolean printedSomething = false;
23079 for (PackageParser.Provider p : mProviders.mProviders.values()) {
23080 if (packageName != null && !packageName.equals(p.info.packageName)) {
23083 if (!printedSomething) {
23084 if (dumpState.onTitlePrinted())
23086 pw.println("Registered ContentProviders:");
23087 printedSomething = true;
23089 pw.print(" "); p.printComponentShortName(pw); pw.println(":");
23090 pw.print(" "); pw.println(p.toString());
23092 printedSomething = false;
23093 for (Map.Entry<String, PackageParser.Provider> entry :
23094 mProvidersByAuthority.entrySet()) {
23095 PackageParser.Provider p = entry.getValue();
23096 if (packageName != null && !packageName.equals(p.info.packageName)) {
23099 if (!printedSomething) {
23100 if (dumpState.onTitlePrinted())
23102 pw.println("ContentProvider Authorities:");
23103 printedSomething = true;
23105 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:");
23106 pw.print(" "); pw.println(p.toString());
23107 if (p.info != null && p.info.applicationInfo != null) {
23108 final String appInfo = p.info.applicationInfo.toString();
23109 pw.print(" applicationInfo="); pw.println(appInfo);
23114 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
23115 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
23118 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
23119 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
23122 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
23123 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
23126 if (dumpState.isDumping(DumpState.DUMP_CHANGES)) {
23127 if (dumpState.onTitlePrinted()) pw.println();
23128 pw.println("Package Changes:");
23129 pw.print(" Sequence number="); pw.println(mChangedPackagesSequenceNumber);
23130 final int K = mChangedPackages.size();
23131 for (int i = 0; i < K; i++) {
23132 final SparseArray<String> changes = mChangedPackages.valueAt(i);
23133 pw.print(" User "); pw.print(mChangedPackages.keyAt(i)); pw.println(":");
23134 final int N = changes.size();
23136 pw.print(" "); pw.println("No packages changed");
23138 for (int j = 0; j < N; j++) {
23139 final String pkgName = changes.valueAt(j);
23140 final int sequenceNumber = changes.keyAt(j);
23143 pw.print(sequenceNumber);
23144 pw.print(", package=");
23145 pw.println(pkgName);
23151 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
23152 mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
23155 if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
23156 // XXX should handle packageName != null by dumping only install data that
23157 // the given package is involved with.
23158 if (dumpState.onTitlePrinted()) pw.println();
23160 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120);
23162 ipw.println("Frozen packages:");
23163 ipw.increaseIndent();
23164 if (mFrozenPackages.size() == 0) {
23165 ipw.println("(none)");
23167 for (int i = 0; i < mFrozenPackages.size(); i++) {
23168 ipw.println(mFrozenPackages.valueAt(i));
23171 ipw.decreaseIndent();
23174 if (!checkin && dumpState.isDumping(DumpState.DUMP_VOLUMES) && packageName == null) {
23175 if (dumpState.onTitlePrinted()) pw.println();
23177 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120);
23179 ipw.println("Loaded volumes:");
23180 ipw.increaseIndent();
23181 if (mLoadedVolumes.size() == 0) {
23182 ipw.println("(none)");
23184 for (int i = 0; i < mLoadedVolumes.size(); i++) {
23185 ipw.println(mLoadedVolumes.valueAt(i));
23188 ipw.decreaseIndent();
23191 if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
23192 if (dumpState.onTitlePrinted()) pw.println();
23193 dumpDexoptStateLPr(pw, packageName);
23196 if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
23197 if (dumpState.onTitlePrinted()) pw.println();
23198 dumpCompilerStatsLPr(pw, packageName);
23201 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
23202 if (dumpState.onTitlePrinted()) pw.println();
23203 mSettings.dumpReadMessagesLPr(pw, dumpState);
23206 pw.println("Package warning messages:");
23207 BufferedReader in = null;
23208 String line = null;
23210 in = new BufferedReader(new FileReader(getSettingsProblemFile()));
23211 while ((line = in.readLine()) != null) {
23212 if (line.contains("ignored: updated version")) continue;
23215 } catch (IOException ignored) {
23217 IoUtils.closeQuietly(in);
23221 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
23222 BufferedReader in = null;
23223 String line = null;
23225 in = new BufferedReader(new FileReader(getSettingsProblemFile()));
23226 while ((line = in.readLine()) != null) {
23227 if (line.contains("ignored: updated version")) continue;
23231 } catch (IOException ignored) {
23233 IoUtils.closeQuietly(in);
23238 // PackageInstaller should be called outside of mPackages lock
23239 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
23240 // XXX should handle packageName != null by dumping only install data that
23241 // the given package is involved with.
23242 if (dumpState.onTitlePrinted()) pw.println();
23243 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120));
23247 private void dumpProto(FileDescriptor fd) {
23248 final ProtoOutputStream proto = new ProtoOutputStream(fd);
23250 synchronized (mPackages) {
23251 final long requiredVerifierPackageToken =
23252 proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
23253 proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
23255 PackageServiceDumpProto.PackageShortProto.UID,
23257 mRequiredVerifierPackage,
23258 MATCH_DEBUG_TRIAGED_MISSING,
23259 UserHandle.USER_SYSTEM));
23260 proto.end(requiredVerifierPackageToken);
23262 if (mIntentFilterVerifierComponent != null) {
23263 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
23264 final long verifierPackageToken =
23265 proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
23266 proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
23268 PackageServiceDumpProto.PackageShortProto.UID,
23270 verifierPackageName,
23271 MATCH_DEBUG_TRIAGED_MISSING,
23272 UserHandle.USER_SYSTEM));
23273 proto.end(verifierPackageToken);
23276 dumpSharedLibrariesProto(proto);
23277 dumpFeaturesProto(proto);
23278 mSettings.dumpPackagesProto(proto);
23279 mSettings.dumpSharedUsersProto(proto);
23280 dumpMessagesProto(proto);
23285 private void dumpMessagesProto(ProtoOutputStream proto) {
23286 BufferedReader in = null;
23287 String line = null;
23289 in = new BufferedReader(new FileReader(getSettingsProblemFile()));
23290 while ((line = in.readLine()) != null) {
23291 if (line.contains("ignored: updated version")) continue;
23292 proto.write(PackageServiceDumpProto.MESSAGES, line);
23294 } catch (IOException ignored) {
23296 IoUtils.closeQuietly(in);
23300 private void dumpFeaturesProto(ProtoOutputStream proto) {
23301 synchronized (mAvailableFeatures) {
23302 final int count = mAvailableFeatures.size();
23303 for (int i = 0; i < count; i++) {
23304 final FeatureInfo feat = mAvailableFeatures.valueAt(i);
23305 final long featureToken = proto.start(PackageServiceDumpProto.FEATURES);
23306 proto.write(PackageServiceDumpProto.FeatureProto.NAME, feat.name);
23307 proto.write(PackageServiceDumpProto.FeatureProto.VERSION, feat.version);
23308 proto.end(featureToken);
23313 private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
23314 final int count = mSharedLibraries.size();
23315 for (int i = 0; i < count; i++) {
23316 final String libName = mSharedLibraries.keyAt(i);
23317 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
23318 if (versionedLib == null) {
23321 final int versionCount = versionedLib.size();
23322 for (int j = 0; j < versionCount; j++) {
23323 final SharedLibraryEntry libEntry = versionedLib.valueAt(j);
23324 final long sharedLibraryToken =
23325 proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
23326 proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libEntry.info.getName());
23327 final boolean isJar = (libEntry.path != null);
23328 proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
23330 proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH, libEntry.path);
23332 proto.write(PackageServiceDumpProto.SharedLibraryProto.APK, libEntry.apk);
23334 proto.end(sharedLibraryToken);
23339 private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
23340 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120);
23342 ipw.println("Dexopt state:");
23343 ipw.increaseIndent();
23344 Collection<PackageParser.Package> packages = null;
23345 if (packageName != null) {
23346 PackageParser.Package targetPackage = mPackages.get(packageName);
23347 if (targetPackage != null) {
23348 packages = Collections.singletonList(targetPackage);
23350 ipw.println("Unable to find package: " + packageName);
23354 packages = mPackages.values();
23357 for (PackageParser.Package pkg : packages) {
23358 ipw.println("[" + pkg.packageName + "]");
23359 ipw.increaseIndent();
23360 mPackageDexOptimizer.dumpDexoptState(ipw, pkg,
23361 mDexManager.getPackageUseInfoOrDefault(pkg.packageName));
23362 ipw.decreaseIndent();
23366 private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
23367 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120);
23369 ipw.println("Compiler stats:");
23370 ipw.increaseIndent();
23371 Collection<PackageParser.Package> packages = null;
23372 if (packageName != null) {
23373 PackageParser.Package targetPackage = mPackages.get(packageName);
23374 if (targetPackage != null) {
23375 packages = Collections.singletonList(targetPackage);
23377 ipw.println("Unable to find package: " + packageName);
23381 packages = mPackages.values();
23384 for (PackageParser.Package pkg : packages) {
23385 ipw.println("[" + pkg.packageName + "]");
23386 ipw.increaseIndent();
23388 CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
23389 if (stats == null) {
23390 ipw.println("(No recorded stats)");
23394 ipw.decreaseIndent();
23398 private String dumpDomainString(String packageName) {
23399 List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
23401 List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
23403 ArraySet<String> result = new ArraySet<>();
23404 if (iviList.size() > 0) {
23405 for (IntentFilterVerificationInfo ivi : iviList) {
23406 for (String host : ivi.getDomains()) {
23411 if (filters != null && filters.size() > 0) {
23412 for (IntentFilter filter : filters) {
23413 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
23414 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
23415 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
23416 result.addAll(filter.getHostsList());
23421 StringBuilder sb = new StringBuilder(result.size() * 16);
23422 for (String domain : result) {
23423 if (sb.length() > 0) sb.append(" ");
23426 return sb.toString();
23429 // ------- apps on sdcard specific code -------
23430 static final boolean DEBUG_SD_INSTALL = false;
23432 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
23434 private static final String SD_ENCRYPTION_ALGORITHM = "AES";
23436 private boolean mMediaMounted = false;
23438 static String getEncryptKey() {
23440 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
23441 SD_ENCRYPTION_KEYSTORE_NAME);
23442 if (sdEncKey == null) {
23443 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
23444 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
23445 if (sdEncKey == null) {
23446 Slog.e(TAG, "Failed to create encryption keys");
23451 } catch (NoSuchAlgorithmException nsae) {
23452 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
23454 } catch (IOException ioe) {
23455 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
23461 * Update media status on PackageManager.
23464 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
23465 enforceSystemOrRoot("Media status can only be updated by the system");
23466 // reader; this apparently protects mMediaMounted, but should probably
23467 // be a different lock in that case.
23468 synchronized (mPackages) {
23469 Log.i(TAG, "Updating external media status from "
23470 + (mMediaMounted ? "mounted" : "unmounted") + " to "
23471 + (mediaStatus ? "mounted" : "unmounted"));
23472 if (DEBUG_SD_INSTALL)
23473 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
23474 + ", mMediaMounted=" + mMediaMounted);
23475 if (mediaStatus == mMediaMounted) {
23476 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
23478 mHandler.sendMessage(msg);
23481 mMediaMounted = mediaStatus;
23483 // Queue up an async operation since the package installation may take a
23485 mHandler.post(new Runnable() {
23486 public void run() {
23487 updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
23493 * Called by StorageManagerService when the initial ASECs to scan are available.
23494 * Should block until all the ASEC containers are finished being scanned.
23496 public void scanAvailableAsecs() {
23497 updateExternalMediaStatusInner(true, false, false);
23501 * Collect information of applications on external media, map them against
23502 * existing containers and update information based on current mount status.
23503 * Please note that we always have to report status if reportStatus has been
23504 * set to true especially when unloading packages.
23506 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
23507 boolean externalStorage) {
23508 ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
23509 int[] uidArr = EmptyArray.INT;
23511 final String[] list = PackageHelper.getSecureContainerList();
23512 if (ArrayUtils.isEmpty(list)) {
23513 Log.i(TAG, "No secure containers found");
23515 // Process list of secure containers and categorize them
23516 // as active or stale based on their package internal state.
23519 synchronized (mPackages) {
23520 for (String cid : list) {
23521 // Leave stages untouched for now; installer service owns them
23522 if (PackageInstallerService.isStageName(cid)) continue;
23524 if (DEBUG_SD_INSTALL)
23525 Log.i(TAG, "Processing container " + cid);
23526 String pkgName = getAsecPackageName(cid);
23527 if (pkgName == null) {
23528 Slog.i(TAG, "Found stale container " + cid + " with no package name");
23531 if (DEBUG_SD_INSTALL)
23532 Log.i(TAG, "Looking for pkg : " + pkgName);
23534 final PackageSetting ps = mSettings.mPackages.get(pkgName);
23536 Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
23541 * Skip packages that are not external if we're unmounting
23542 * external storage.
23544 if (externalStorage && !isMounted && !isExternal(ps)) {
23548 final AsecInstallArgs args = new AsecInstallArgs(cid,
23549 getAppDexInstructionSets(ps), ps.isForwardLocked());
23550 // The package status is changed only if the code path
23551 // matches between settings and the container id.
23552 if (ps.codePathString != null
23553 && ps.codePathString.startsWith(args.getCodePath())) {
23554 if (DEBUG_SD_INSTALL) {
23555 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
23556 + " at code path: " + ps.codePathString);
23559 // We do have a valid package installed on sdcard
23560 processCids.put(args, ps.codePathString);
23561 final int uid = ps.appId;
23563 uidArr = ArrayUtils.appendInt(uidArr, uid);
23566 Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
23567 + ps.codePathString);
23572 Arrays.sort(uidArr);
23575 // Process packages with valid entries.
23577 if (DEBUG_SD_INSTALL)
23578 Log.i(TAG, "Loading packages");
23579 loadMediaPackages(processCids, uidArr, externalStorage);
23580 startCleaningPackages();
23581 mInstallerService.onSecureContainersAvailable();
23583 if (DEBUG_SD_INSTALL)
23584 Log.i(TAG, "Unloading packages");
23585 unloadMediaPackages(processCids, uidArr, reportStatus);
23589 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
23590 ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
23591 final int size = infos.size();
23592 final String[] packageNames = new String[size];
23593 final int[] packageUids = new int[size];
23594 for (int i = 0; i < size; i++) {
23595 final ApplicationInfo info = infos.get(i);
23596 packageNames[i] = info.packageName;
23597 packageUids[i] = info.uid;
23599 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
23603 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
23604 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
23605 sendResourcesChangedBroadcast(mediaStatus, replacing,
23606 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
23609 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
23610 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
23611 int size = pkgList.length;
23613 // Send broadcasts here
23614 Bundle extras = new Bundle();
23615 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
23616 if (uidArr != null) {
23617 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
23620 extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
23622 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
23623 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
23624 sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null);
23629 * Look at potentially valid container ids from processCids If package
23630 * information doesn't match the one on record or package scanning fails,
23631 * the cid is added to list of removeCids. We currently don't delete stale
23634 private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr,
23635 boolean externalStorage) {
23636 ArrayList<String> pkgList = new ArrayList<String>();
23637 Set<AsecInstallArgs> keys = processCids.keySet();
23639 for (AsecInstallArgs args : keys) {
23640 String codePath = processCids.get(args);
23641 if (DEBUG_SD_INSTALL)
23642 Log.i(TAG, "Loading container : " + args.cid);
23643 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
23645 // Make sure there are no container errors first.
23646 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
23647 Slog.e(TAG, "Failed to mount cid : " + args.cid
23648 + " when installing from sdcard");
23651 // Check code path here.
23652 if (codePath == null || !codePath.startsWith(args.getCodePath())) {
23653 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
23654 + " does not match one in settings " + codePath);
23658 int parseFlags = mDefParseFlags;
23659 if (args.isExternalAsec()) {
23660 parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
23662 if (args.isFwdLocked()) {
23663 parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
23666 synchronized (mInstallLock) {
23667 PackageParser.Package pkg = null;
23669 // Sadly we don't know the package name yet to freeze it
23670 pkg = scanPackageTracedLI(new File(codePath), parseFlags,
23671 SCAN_IGNORE_FROZEN, 0, null);
23672 } catch (PackageManagerException e) {
23673 Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
23675 // Scan the package
23678 * TODO why is the lock being held? doPostInstall is
23679 * called in other places without the lock. This needs
23680 * to be straightened out.
23683 synchronized (mPackages) {
23684 retCode = PackageManager.INSTALL_SUCCEEDED;
23685 pkgList.add(pkg.packageName);
23686 // Post process args
23687 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
23688 pkg.applicationInfo.uid);
23691 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard");
23696 if (retCode != PackageManager.INSTALL_SUCCEEDED) {
23697 Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
23702 synchronized (mPackages) {
23703 // If the platform SDK has changed since the last time we booted,
23704 // we need to re-grant app permission to catch any new ones that
23705 // appear. This is really a hack, and means that apps can in some
23706 // cases get permissions that the user didn't initially explicitly
23707 // allow... it would be nice to have some better way to handle
23709 final VersionInfo ver = externalStorage ? mSettings.getExternalVersion()
23710 : mSettings.getInternalVersion();
23711 final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL
23712 : StorageManager.UUID_PRIVATE_INTERNAL;
23714 int updateFlags = UPDATE_PERMISSIONS_ALL;
23715 if (ver.sdkVersion != mSdkVersion) {
23716 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
23717 + mSdkVersion + "; regranting permissions for external");
23718 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
23720 updatePermissionsLPw(null, null, volumeUuid, updateFlags);
23722 // Yay, everything is now upgraded
23723 ver.forceCurrent();
23725 // can downgrade to reader
23726 // Persist settings
23727 mSettings.writeLPr();
23729 // Send a broadcast to let everyone know we are done processing
23730 if (pkgList.size() > 0) {
23731 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
23736 * Utility method to unload a list of specified containers
23738 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
23739 // Just unmount all valid containers.
23740 for (AsecInstallArgs arg : cidArgs) {
23741 synchronized (mInstallLock) {
23742 arg.doPostDeleteLI(false);
23748 * Unload packages mounted on external media. This involves deleting package
23749 * data from internal structures, sending broadcasts about disabled packages,
23750 * gc'ing to free up references, unmounting all secure containers
23751 * corresponding to packages on external media, and posting a
23752 * UPDATED_MEDIA_STATUS message if status has been requested. Please note
23753 * that we always have to post this message if status has been requested no
23756 private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
23757 final boolean reportStatus) {
23758 if (DEBUG_SD_INSTALL)
23759 Log.i(TAG, "unloading media packages");
23760 ArrayList<String> pkgList = new ArrayList<String>();
23761 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
23762 final Set<AsecInstallArgs> keys = processCids.keySet();
23763 for (AsecInstallArgs args : keys) {
23764 String pkgName = args.getPackageName();
23765 if (DEBUG_SD_INSTALL)
23766 Log.i(TAG, "Trying to unload pkg : " + pkgName);
23767 // Delete package internally
23768 PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
23769 synchronized (mInstallLock) {
23770 final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
23772 try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags,
23773 "unloadMediaPackages")) {
23774 res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false,
23778 pkgList.add(pkgName);
23780 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
23781 failedList.add(args);
23787 synchronized (mPackages) {
23788 // We didn't update the settings after removing each package;
23789 // write them now for all packages.
23790 mSettings.writeLPr();
23793 // We have to absolutely send UPDATED_MEDIA_STATUS only
23794 // after confirming that all the receivers processed the ordered
23795 // broadcast when packages get disabled, force a gc to clean things up.
23796 // and unload all the containers.
23797 if (pkgList.size() > 0) {
23798 sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
23799 new IIntentReceiver.Stub() {
23800 public void performReceive(Intent intent, int resultCode, String data,
23801 Bundle extras, boolean ordered, boolean sticky,
23802 int sendingUser) throws RemoteException {
23803 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
23804 reportStatus ? 1 : 0, 1, keys);
23805 mHandler.sendMessage(msg);
23809 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
23811 mHandler.sendMessage(msg);
23815 private void loadPrivatePackages(final VolumeInfo vol) {
23816 mHandler.post(new Runnable() {
23818 public void run() {
23819 loadPrivatePackagesInner(vol);
23824 private void loadPrivatePackagesInner(VolumeInfo vol) {
23825 final String volumeUuid = vol.fsUuid;
23826 if (TextUtils.isEmpty(volumeUuid)) {
23827 Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
23831 final ArrayList<PackageFreezer> freezers = new ArrayList<>();
23832 final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
23833 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
23835 final VersionInfo ver;
23836 final List<PackageSetting> packages;
23837 synchronized (mPackages) {
23838 ver = mSettings.findOrCreateVersion(volumeUuid);
23839 packages = mSettings.getVolumePackagesLPr(volumeUuid);
23842 for (PackageSetting ps : packages) {
23843 freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
23844 synchronized (mInstallLock) {
23845 final PackageParser.Package pkg;
23847 pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
23848 loaded.add(pkg.applicationInfo);
23850 } catch (PackageManagerException e) {
23851 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
23854 if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
23855 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
23856 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
23857 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
23862 // Reconcile app data for all started/unlocked users
23863 final StorageManager sm = mContext.getSystemService(StorageManager.class);
23864 final UserManager um = mContext.getSystemService(UserManager.class);
23865 UserManagerInternal umInternal = getUserManagerInternal();
23866 for (UserInfo user : um.getUsers()) {
23868 if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
23869 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
23870 } else if (umInternal.isUserRunning(user.id)) {
23871 flags = StorageManager.FLAG_STORAGE_DE;
23877 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
23878 synchronized (mInstallLock) {
23879 reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
23881 } catch (IllegalStateException e) {
23882 // Device was probably ejected, and we'll process that event momentarily
23883 Slog.w(TAG, "Failed to prepare storage: " + e);
23887 synchronized (mPackages) {
23888 int updateFlags = UPDATE_PERMISSIONS_ALL;
23889 if (ver.sdkVersion != mSdkVersion) {
23890 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
23891 + mSdkVersion + "; regranting permissions for " + volumeUuid);
23892 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
23894 updatePermissionsLPw(null, null, volumeUuid, updateFlags);
23896 // Yay, everything is now upgraded
23897 ver.forceCurrent();
23899 mSettings.writeLPr();
23902 for (PackageFreezer freezer : freezers) {
23906 if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
23907 sendResourcesChangedBroadcast(true, false, loaded, null);
23908 mLoadedVolumes.add(vol.getId());
23911 private void unloadPrivatePackages(final VolumeInfo vol) {
23912 mHandler.post(new Runnable() {
23914 public void run() {
23915 unloadPrivatePackagesInner(vol);
23920 private void unloadPrivatePackagesInner(VolumeInfo vol) {
23921 final String volumeUuid = vol.fsUuid;
23922 if (TextUtils.isEmpty(volumeUuid)) {
23923 Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
23927 final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
23928 synchronized (mInstallLock) {
23929 synchronized (mPackages) {
23930 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
23931 for (PackageSetting ps : packages) {
23932 if (ps.pkg == null) continue;
23934 final ApplicationInfo info = ps.pkg.applicationInfo;
23935 final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
23936 final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
23938 try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
23939 "unloadPrivatePackagesInner")) {
23940 if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
23942 unloaded.add(info);
23944 Slog.w(TAG, "Failed to unload " + ps.codePath);
23948 // Try very hard to release any references to this package
23949 // so we don't risk the system server being killed due to
23951 AttributeCache.instance().removePackage(ps.name);
23954 mSettings.writeLPr();
23958 if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
23959 sendResourcesChangedBroadcast(false, false, unloaded, null);
23960 mLoadedVolumes.remove(vol.getId());
23962 // Try very hard to release any references to this path so we don't risk
23963 // the system server being killed due to open FDs
23964 ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
23966 for (int i = 0; i < 3; i++) {
23968 System.runFinalization();
23972 private void assertPackageKnown(String volumeUuid, String packageName)
23973 throws PackageManagerException {
23974 synchronized (mPackages) {
23975 // Normalize package name to handle renamed packages
23976 packageName = normalizePackageNameLPr(packageName);
23978 final PackageSetting ps = mSettings.mPackages.get(packageName);
23980 throw new PackageManagerException("Package " + packageName + " is unknown");
23981 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
23982 throw new PackageManagerException(
23983 "Package " + packageName + " found on unknown volume " + volumeUuid
23984 + "; expected volume " + ps.volumeUuid);
23989 private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
23990 throws PackageManagerException {
23991 synchronized (mPackages) {
23992 // Normalize package name to handle renamed packages
23993 packageName = normalizePackageNameLPr(packageName);
23995 final PackageSetting ps = mSettings.mPackages.get(packageName);
23997 throw new PackageManagerException("Package " + packageName + " is unknown");
23998 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
23999 throw new PackageManagerException(
24000 "Package " + packageName + " found on unknown volume " + volumeUuid
24001 + "; expected volume " + ps.volumeUuid);
24002 } else if (!ps.getInstalled(userId)) {
24003 throw new PackageManagerException(
24004 "Package " + packageName + " not installed for user " + userId);
24009 private List<String> collectAbsoluteCodePaths() {
24010 synchronized (mPackages) {
24011 List<String> codePaths = new ArrayList<>();
24012 final int packageCount = mSettings.mPackages.size();
24013 for (int i = 0; i < packageCount; i++) {
24014 final PackageSetting ps = mSettings.mPackages.valueAt(i);
24015 codePaths.add(ps.codePath.getAbsolutePath());
24022 * Examine all apps present on given mounted volume, and destroy apps that
24023 * aren't expected, either due to uninstallation or reinstallation on
24026 private void reconcileApps(String volumeUuid) {
24027 List<String> absoluteCodePaths = collectAbsoluteCodePaths();
24028 List<File> filesToDelete = null;
24030 final File[] files = FileUtils.listFilesOrEmpty(
24031 Environment.getDataAppDirectory(volumeUuid));
24032 for (File file : files) {
24033 final boolean isPackage = (isApkFile(file) || file.isDirectory())
24034 && !PackageInstallerService.isStageName(file.getName());
24036 // Ignore entries which are not packages
24040 String absolutePath = file.getAbsolutePath();
24042 boolean pathValid = false;
24043 final int absoluteCodePathCount = absoluteCodePaths.size();
24044 for (int i = 0; i < absoluteCodePathCount; i++) {
24045 String absoluteCodePath = absoluteCodePaths.get(i);
24046 if (absolutePath.startsWith(absoluteCodePath)) {
24053 if (filesToDelete == null) {
24054 filesToDelete = new ArrayList<>();
24056 filesToDelete.add(file);
24060 if (filesToDelete != null) {
24061 final int fileToDeleteCount = filesToDelete.size();
24062 for (int i = 0; i < fileToDeleteCount; i++) {
24063 File fileToDelete = filesToDelete.get(i);
24064 logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
24065 synchronized (mInstallLock) {
24066 removeCodePathLI(fileToDelete);
24073 * Reconcile all app data for the given user.
24075 * Verifies that directories exist and that ownership and labeling is
24076 * correct for all installed apps on all mounted volumes.
24078 void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
24079 final StorageManager storage = mContext.getSystemService(StorageManager.class);
24080 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
24081 final String volumeUuid = vol.getFsUuid();
24082 synchronized (mInstallLock) {
24083 reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
24088 private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
24089 boolean migrateAppData) {
24090 reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
24094 * Reconcile all app data on given mounted volume.
24096 * Destroys app data that isn't expected, either due to uninstallation or
24097 * reinstallation on another volume.
24099 * Verifies that directories exist and that ownership and labeling is
24100 * correct for all installed apps.
24101 * @returns list of skipped non-core packages (if {@code onlyCoreApps} is true)
24103 private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
24104 boolean migrateAppData, boolean onlyCoreApps) {
24105 Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
24106 + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
24107 List<String> result = onlyCoreApps ? new ArrayList<>() : null;
24109 final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
24110 final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
24112 // First look for stale data that doesn't belong, and check if things
24113 // have changed since we did our last restorecon
24114 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
24115 if (StorageManager.isFileEncryptedNativeOrEmulated()
24116 && !StorageManager.isUserKeyUnlocked(userId)) {
24117 throw new RuntimeException(
24118 "Yikes, someone asked us to reconcile CE storage while " + userId
24119 + " was still locked; this would have caused massive data loss!");
24122 final File[] files = FileUtils.listFilesOrEmpty(ceDir);
24123 for (File file : files) {
24124 final String packageName = file.getName();
24126 assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
24127 } catch (PackageManagerException e) {
24128 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
24130 mInstaller.destroyAppData(volumeUuid, packageName, userId,
24131 StorageManager.FLAG_STORAGE_CE, 0);
24132 } catch (InstallerException e2) {
24133 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
24138 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
24139 final File[] files = FileUtils.listFilesOrEmpty(deDir);
24140 for (File file : files) {
24141 final String packageName = file.getName();
24143 assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
24144 } catch (PackageManagerException e) {
24145 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
24147 mInstaller.destroyAppData(volumeUuid, packageName, userId,
24148 StorageManager.FLAG_STORAGE_DE, 0);
24149 } catch (InstallerException e2) {
24150 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
24156 // Ensure that data directories are ready to roll for all packages
24157 // installed for this volume and user
24158 final List<PackageSetting> packages;
24159 synchronized (mPackages) {
24160 packages = mSettings.getVolumePackagesLPr(volumeUuid);
24162 int preparedCount = 0;
24163 for (PackageSetting ps : packages) {
24164 final String packageName = ps.name;
24165 if (ps.pkg == null) {
24166 Slog.w(TAG, "Odd, missing scanned package " + packageName);
24167 // TODO: might be due to legacy ASEC apps; we should circle back
24168 // and reconcile again once they're scanned
24171 // Skip non-core apps if requested
24172 if (onlyCoreApps && !ps.pkg.coreApp) {
24173 result.add(packageName);
24177 if (ps.getInstalled(userId)) {
24178 prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
24183 Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
24188 * Prepare app data for the given app just after it was installed or
24189 * upgraded. This method carefully only touches users that it's installed
24190 * for, and it forces a restorecon to handle any seinfo changes.
24192 * Verifies that directories exist and that ownership and labeling is
24193 * correct for all installed apps. If there is an ownership mismatch, it
24194 * will try recovering system apps by wiping data; third-party app data is
24197 * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
24199 private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
24200 final PackageSetting ps;
24201 synchronized (mPackages) {
24202 ps = mSettings.mPackages.get(pkg.packageName);
24203 mSettings.writeKernelMappingLPr(ps);
24206 final UserManager um = mContext.getSystemService(UserManager.class);
24207 UserManagerInternal umInternal = getUserManagerInternal();
24208 for (UserInfo user : um.getUsers()) {
24210 if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
24211 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
24212 } else if (umInternal.isUserRunning(user.id)) {
24213 flags = StorageManager.FLAG_STORAGE_DE;
24218 if (ps.getInstalled(user.id)) {
24219 // TODO: when user data is locked, mark that we're still dirty
24220 prepareAppDataLIF(pkg, user.id, flags);
24226 * Prepare app data for the given app.
24228 * Verifies that directories exist and that ownership and labeling is
24229 * correct for all installed apps. If there is an ownership mismatch, this
24230 * will try recovering system apps by wiping data; third-party app data is
24233 private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
24235 Slog.wtf(TAG, "Package was null!", new Throwable());
24238 prepareAppDataLeafLIF(pkg, userId, flags);
24239 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
24240 for (int i = 0; i < childCount; i++) {
24241 prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
24245 private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags,
24246 boolean maybeMigrateAppData) {
24247 prepareAppDataLIF(pkg, userId, flags);
24249 if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
24250 // We may have just shuffled around app data directories, so
24251 // prepare them one more time
24252 prepareAppDataLIF(pkg, userId, flags);
24256 private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
24257 if (DEBUG_APP_DATA) {
24258 Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
24259 + Integer.toHexString(flags));
24262 final String volumeUuid = pkg.volumeUuid;
24263 final String packageName = pkg.packageName;
24264 final ApplicationInfo app = pkg.applicationInfo;
24265 final int appId = UserHandle.getAppId(app.uid);
24267 Preconditions.checkNotNull(app.seInfo);
24269 long ceDataInode = -1;
24271 ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
24272 appId, app.seInfo, app.targetSdkVersion);
24273 } catch (InstallerException e) {
24274 if (app.isSystemApp()) {
24275 logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
24276 + ", but trying to recover: " + e);
24277 destroyAppDataLeafLIF(pkg, userId, flags);
24279 ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
24280 appId, app.seInfo, app.targetSdkVersion);
24281 logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
24282 } catch (InstallerException e2) {
24283 logCriticalInfo(Log.DEBUG, "Recovery failed!");
24286 Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
24290 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
24291 // TODO: mark this structure as dirty so we persist it!
24292 synchronized (mPackages) {
24293 final PackageSetting ps = mSettings.mPackages.get(packageName);
24295 ps.setCeDataInode(ceDataInode, userId);
24300 prepareAppDataContentsLeafLIF(pkg, userId, flags);
24303 private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
24305 Slog.wtf(TAG, "Package was null!", new Throwable());
24308 prepareAppDataContentsLeafLIF(pkg, userId, flags);
24309 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
24310 for (int i = 0; i < childCount; i++) {
24311 prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
24315 private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
24316 final String volumeUuid = pkg.volumeUuid;
24317 final String packageName = pkg.packageName;
24318 final ApplicationInfo app = pkg.applicationInfo;
24320 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
24321 // Create a native library symlink only if we have native libraries
24322 // and if the native libraries are 32 bit libraries. We do not provide
24323 // this symlink for 64 bit libraries.
24324 if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
24325 final String nativeLibPath = app.nativeLibraryDir;
24327 mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
24328 nativeLibPath, userId);
24329 } catch (InstallerException e) {
24330 Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
24337 * For system apps on non-FBE devices, this method migrates any existing
24338 * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
24339 * requested by the app.
24341 private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
24342 if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated()
24343 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
24344 final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
24345 ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
24347 mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
24349 } catch (InstallerException e) {
24350 logCriticalInfo(Log.WARN,
24351 "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
24359 public PackageFreezer freezePackage(String packageName, String killReason) {
24360 return freezePackage(packageName, UserHandle.USER_ALL, killReason);
24363 public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
24364 return new PackageFreezer(packageName, userId, killReason);
24367 public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
24368 String killReason) {
24369 return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
24372 public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
24373 String killReason) {
24374 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
24375 return new PackageFreezer();
24377 return freezePackage(packageName, userId, killReason);
24381 public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
24382 String killReason) {
24383 return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
24386 public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
24387 String killReason) {
24388 if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
24389 return new PackageFreezer();
24391 return freezePackage(packageName, userId, killReason);
24396 * Class that freezes and kills the given package upon creation, and
24397 * unfreezes it upon closing. This is typically used when doing surgery on
24398 * app code/data to prevent the app from running while you're working.
24400 private class PackageFreezer implements AutoCloseable {
24401 private final String mPackageName;
24402 private final PackageFreezer[] mChildren;
24404 private final boolean mWeFroze;
24406 private final AtomicBoolean mClosed = new AtomicBoolean();
24407 private final CloseGuard mCloseGuard = CloseGuard.get();
24410 * Create and return a stub freezer that doesn't actually do anything,
24411 * typically used when someone requested
24412 * {@link PackageManager#INSTALL_DONT_KILL_APP} or
24413 * {@link PackageManager#DELETE_DONT_KILL_APP}.
24415 public PackageFreezer() {
24416 mPackageName = null;
24419 mCloseGuard.open("close");
24422 public PackageFreezer(String packageName, int userId, String killReason) {
24423 synchronized (mPackages) {
24424 mPackageName = packageName;
24425 mWeFroze = mFrozenPackages.add(mPackageName);
24427 final PackageSetting ps = mSettings.mPackages.get(mPackageName);
24429 killApplication(ps.name, ps.appId, userId, killReason);
24432 final PackageParser.Package p = mPackages.get(packageName);
24433 if (p != null && p.childPackages != null) {
24434 final int N = p.childPackages.size();
24435 mChildren = new PackageFreezer[N];
24436 for (int i = 0; i < N; i++) {
24437 mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
24438 userId, killReason);
24444 mCloseGuard.open("close");
24448 protected void finalize() throws Throwable {
24450 if (mCloseGuard != null) {
24451 mCloseGuard.warnIfOpen();
24461 public void close() {
24462 mCloseGuard.close();
24463 if (mClosed.compareAndSet(false, true)) {
24464 synchronized (mPackages) {
24466 mFrozenPackages.remove(mPackageName);
24469 if (mChildren != null) {
24470 for (PackageFreezer freezer : mChildren) {
24480 * Verify that given package is currently frozen.
24482 private void checkPackageFrozen(String packageName) {
24483 synchronized (mPackages) {
24484 if (!mFrozenPackages.contains(packageName)) {
24485 Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
24491 public int movePackage(final String packageName, final String volumeUuid) {
24492 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
24494 final int callingUid = Binder.getCallingUid();
24495 final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
24496 final int moveId = mNextMoveId.getAndIncrement();
24497 mHandler.post(new Runnable() {
24499 public void run() {
24501 movePackageInternal(packageName, volumeUuid, moveId, callingUid, user);
24502 } catch (PackageManagerException e) {
24503 Slog.w(TAG, "Failed to move " + packageName, e);
24504 mMoveCallbacks.notifyStatusChanged(moveId, e.error);
24511 private void movePackageInternal(final String packageName, final String volumeUuid,
24512 final int moveId, final int callingUid, UserHandle user)
24513 throws PackageManagerException {
24514 final StorageManager storage = mContext.getSystemService(StorageManager.class);
24515 final PackageManager pm = mContext.getPackageManager();
24517 final boolean currentAsec;
24518 final String currentVolumeUuid;
24519 final File codeFile;
24520 final String installerPackageName;
24521 final String packageAbiOverride;
24523 final String seinfo;
24524 final String label;
24525 final int targetSdkVersion;
24526 final PackageFreezer freezer;
24527 final int[] installedUserIds;
24530 synchronized (mPackages) {
24531 final PackageParser.Package pkg = mPackages.get(packageName);
24532 final PackageSetting ps = mSettings.mPackages.get(packageName);
24535 || filterAppAccessLPr(ps, callingUid, user.getIdentifier())) {
24536 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
24538 if (pkg.applicationInfo.isSystemApp()) {
24539 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
24540 "Cannot move system application");
24543 final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
24544 final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
24545 com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
24546 if (isInternalStorage && !allow3rdPartyOnInternal) {
24547 throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
24548 "3rd party apps are not allowed on internal storage");
24551 if (pkg.applicationInfo.isExternalAsec()) {
24552 currentAsec = true;
24553 currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
24554 } else if (pkg.applicationInfo.isForwardLocked()) {
24555 currentAsec = true;
24556 currentVolumeUuid = "forward_locked";
24558 currentAsec = false;
24559 currentVolumeUuid = ps.volumeUuid;
24561 final File probe = new File(pkg.codePath);
24562 final File probeOat = new File(probe, "oat");
24563 if (!probe.isDirectory() || !probeOat.isDirectory()) {
24564 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24565 "Move only supported for modern cluster style installs");
24569 if (Objects.equals(currentVolumeUuid, volumeUuid)) {
24570 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24571 "Package already moved to " + volumeUuid);
24573 if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
24574 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
24575 "Device admin cannot be moved");
24578 if (mFrozenPackages.contains(packageName)) {
24579 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
24580 "Failed to move already frozen package");
24583 codeFile = new File(pkg.codePath);
24584 installerPackageName = ps.installerPackageName;
24585 packageAbiOverride = ps.cpuAbiOverrideString;
24586 appId = UserHandle.getAppId(pkg.applicationInfo.uid);
24587 seinfo = pkg.applicationInfo.seInfo;
24588 label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
24589 targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
24590 freezer = freezePackage(packageName, "movePackageInternal");
24591 installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
24594 final Bundle extras = new Bundle();
24595 extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
24596 extras.putString(Intent.EXTRA_TITLE, label);
24597 mMoveCallbacks.notifyCreated(moveId, extras);
24600 final boolean moveCompleteApp;
24601 final File measurePath;
24603 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
24604 installFlags = INSTALL_INTERNAL;
24605 moveCompleteApp = !currentAsec;
24606 measurePath = Environment.getDataAppDirectory(volumeUuid);
24607 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
24608 installFlags = INSTALL_EXTERNAL;
24609 moveCompleteApp = false;
24610 measurePath = storage.getPrimaryPhysicalVolume().getPath();
24612 final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
24613 if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
24614 || !volume.isMountedWritable()) {
24616 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24617 "Move location not mounted private volume");
24620 Preconditions.checkState(!currentAsec);
24622 installFlags = INSTALL_INTERNAL;
24623 moveCompleteApp = true;
24624 measurePath = Environment.getDataAppDirectory(volumeUuid);
24627 // If we're moving app data around, we need all the users unlocked
24628 if (moveCompleteApp) {
24629 for (int userId : installedUserIds) {
24630 if (StorageManager.isFileEncryptedNativeOrEmulated()
24631 && !StorageManager.isUserKeyUnlocked(userId)) {
24632 throw new PackageManagerException(MOVE_FAILED_LOCKED_USER,
24633 "User " + userId + " must be unlocked");
24638 final PackageStats stats = new PackageStats(null, -1);
24639 synchronized (mInstaller) {
24640 for (int userId : installedUserIds) {
24641 if (!getPackageSizeInfoLI(packageName, userId, stats)) {
24643 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24644 "Failed to measure package size");
24649 if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
24652 final long startFreeBytes = measurePath.getUsableSpace();
24653 final long sizeBytes;
24654 if (moveCompleteApp) {
24655 sizeBytes = stats.codeSize + stats.dataSize;
24657 sizeBytes = stats.codeSize;
24660 if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
24662 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24663 "Not enough free space to move");
24666 mMoveCallbacks.notifyStatusChanged(moveId, 10);
24668 final CountDownLatch installedLatch = new CountDownLatch(1);
24669 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
24671 public void onUserActionRequired(Intent intent) throws RemoteException {
24672 throw new IllegalStateException();
24676 public void onPackageInstalled(String basePackageName, int returnCode, String msg,
24677 Bundle extras) throws RemoteException {
24678 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
24679 + PackageManager.installStatusToString(returnCode, msg));
24681 installedLatch.countDown();
24684 final int status = PackageManager.installStatusToPublicStatus(returnCode);
24686 case PackageInstaller.STATUS_SUCCESS:
24687 mMoveCallbacks.notifyStatusChanged(moveId,
24688 PackageManager.MOVE_SUCCEEDED);
24690 case PackageInstaller.STATUS_FAILURE_STORAGE:
24691 mMoveCallbacks.notifyStatusChanged(moveId,
24692 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
24695 mMoveCallbacks.notifyStatusChanged(moveId,
24696 PackageManager.MOVE_FAILED_INTERNAL_ERROR);
24702 final MoveInfo move;
24703 if (moveCompleteApp) {
24704 // Kick off a thread to report progress estimates
24707 public void run() {
24710 if (installedLatch.await(1, TimeUnit.SECONDS)) {
24713 } catch (InterruptedException ignored) {
24716 final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
24717 final int progress = 10 + (int) MathUtils.constrain(
24718 ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
24719 mMoveCallbacks.notifyStatusChanged(moveId, progress);
24724 final String dataAppName = codeFile.getName();
24725 move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
24726 dataAppName, appId, seinfo, targetSdkVersion);
24731 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
24733 final Message msg = mHandler.obtainMessage(INIT_COPY);
24734 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
24735 final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
24736 installerPackageName, volumeUuid, null /*verificationInfo*/, user,
24737 packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/,
24738 PackageManager.INSTALL_REASON_UNKNOWN);
24739 params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
24742 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
24743 System.identityHashCode(msg.obj));
24744 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
24745 System.identityHashCode(msg.obj));
24747 mHandler.sendMessage(msg);
24751 public int movePrimaryStorage(String volumeUuid) throws RemoteException {
24752 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
24754 final int realMoveId = mNextMoveId.getAndIncrement();
24755 final Bundle extras = new Bundle();
24756 extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
24757 mMoveCallbacks.notifyCreated(realMoveId, extras);
24759 final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
24761 public void onCreated(int moveId, Bundle extras) {
24766 public void onStatusChanged(int moveId, int status, long estMillis) {
24767 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
24771 final StorageManager storage = mContext.getSystemService(StorageManager.class);
24772 storage.setPrimaryStorageUuid(volumeUuid, callback);
24777 public int getMoveStatus(int moveId) {
24778 mContext.enforceCallingOrSelfPermission(
24779 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
24780 return mMoveCallbacks.mLastStatus.get(moveId);
24784 public void registerMoveCallback(IPackageMoveObserver callback) {
24785 mContext.enforceCallingOrSelfPermission(
24786 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
24787 mMoveCallbacks.register(callback);
24791 public void unregisterMoveCallback(IPackageMoveObserver callback) {
24792 mContext.enforceCallingOrSelfPermission(
24793 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
24794 mMoveCallbacks.unregister(callback);
24798 public boolean setInstallLocation(int loc) {
24799 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
24801 if (getInstallLocation() == loc) {
24804 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
24805 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
24806 android.provider.Settings.Global.putInt(mContext.getContentResolver(),
24807 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
24814 public int getInstallLocation() {
24815 // allow instant app access
24816 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
24817 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
24818 PackageHelper.APP_INSTALL_AUTO);
24821 /** Called by UserManagerService */
24822 void cleanUpUser(UserManagerService userManager, int userHandle) {
24823 synchronized (mPackages) {
24824 mDirtyUsers.remove(userHandle);
24825 mUserNeedsBadging.delete(userHandle);
24826 mSettings.removeUserLPw(userHandle);
24827 mPendingBroadcasts.remove(userHandle);
24828 mInstantAppRegistry.onUserRemovedLPw(userHandle);
24829 removeUnusedPackagesLPw(userManager, userHandle);
24834 * We're removing userHandle and would like to remove any downloaded packages
24835 * that are no longer in use by any other user.
24836 * @param userHandle the user being removed
24838 private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
24839 final boolean DEBUG_CLEAN_APKS = false;
24840 int [] users = userManager.getUserIds();
24841 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
24842 while (psit.hasNext()) {
24843 PackageSetting ps = psit.next();
24844 if (ps.pkg == null) {
24847 final String packageName = ps.pkg.packageName;
24848 // Skip over if system app
24849 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
24852 if (DEBUG_CLEAN_APKS) {
24853 Slog.i(TAG, "Checking package " + packageName);
24855 boolean keep = shouldKeepUninstalledPackageLPr(packageName);
24857 if (DEBUG_CLEAN_APKS) {
24858 Slog.i(TAG, " Keeping package " + packageName + " - requested by DO");
24861 for (int i = 0; i < users.length; i++) {
24862 if (users[i] != userHandle && ps.getInstalled(users[i])) {
24864 if (DEBUG_CLEAN_APKS) {
24865 Slog.i(TAG, " Keeping package " + packageName + " for user "
24873 if (DEBUG_CLEAN_APKS) {
24874 Slog.i(TAG, " Removing package " + packageName);
24876 mHandler.post(new Runnable() {
24877 public void run() {
24878 deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
24886 /** Called by UserManagerService */
24887 void createNewUser(int userId, String[] disallowedPackages) {
24888 synchronized (mInstallLock) {
24889 mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages);
24891 synchronized (mPackages) {
24892 scheduleWritePackageRestrictionsLocked(userId);
24893 scheduleWritePackageListLocked(userId);
24894 applyFactoryDefaultBrowserLPw(userId);
24895 primeDomainVerificationsLPw(userId);
24899 void onNewUserCreated(final int userId) {
24900 mDefaultPermissionPolicy.grantDefaultPermissions(userId);
24901 // If permission review for legacy apps is required, we represent
24902 // dagerous permissions for such apps as always granted runtime
24903 // permissions to keep per user flag state whether review is needed.
24904 // Hence, if a new user is added we have to propagate dangerous
24905 // permission grants for these legacy apps.
24906 if (mPermissionReviewRequired) {
24907 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
24908 | UPDATE_PERMISSIONS_REPLACE_ALL);
24913 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
24914 mContext.enforceCallingOrSelfPermission(
24915 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
24916 "Only package verification agents can read the verifier device identity");
24918 synchronized (mPackages) {
24919 return mSettings.getVerifierDeviceIdentityLPw();
24924 public void setPermissionEnforced(String permission, boolean enforced) {
24925 // TODO: Now that we no longer change GID for storage, this should to away.
24926 mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
24927 "setPermissionEnforced");
24928 if (READ_EXTERNAL_STORAGE.equals(permission)) {
24929 synchronized (mPackages) {
24930 if (mSettings.mReadExternalStorageEnforced == null
24931 || mSettings.mReadExternalStorageEnforced != enforced) {
24932 mSettings.mReadExternalStorageEnforced = enforced;
24933 mSettings.writeLPr();
24936 // kill any non-foreground processes so we restart them and
24937 // grant/revoke the GID.
24938 final IActivityManager am = ActivityManager.getService();
24940 final long token = Binder.clearCallingIdentity();
24942 am.killProcessesBelowForeground("setPermissionEnforcement");
24943 } catch (RemoteException e) {
24945 Binder.restoreCallingIdentity(token);
24949 throw new IllegalArgumentException("No selective enforcement for " + permission);
24955 public boolean isPermissionEnforced(String permission) {
24956 // allow instant applications
24961 public boolean isStorageLow() {
24962 // allow instant applications
24963 final long token = Binder.clearCallingIdentity();
24965 final DeviceStorageMonitorInternal
24966 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
24968 return dsm.isMemoryLow();
24973 Binder.restoreCallingIdentity(token);
24978 public IPackageInstaller getPackageInstaller() {
24979 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24982 return mInstallerService;
24985 private boolean userNeedsBadging(int userId) {
24986 int index = mUserNeedsBadging.indexOfKey(userId);
24988 final UserInfo userInfo;
24989 final long token = Binder.clearCallingIdentity();
24991 userInfo = sUserManager.getUserInfo(userId);
24993 Binder.restoreCallingIdentity(token);
24996 if (userInfo != null && userInfo.isManagedProfile()) {
25001 mUserNeedsBadging.put(userId, b);
25004 return mUserNeedsBadging.valueAt(index);
25008 public KeySet getKeySetByAlias(String packageName, String alias) {
25009 if (packageName == null || alias == null) {
25012 synchronized(mPackages) {
25013 final PackageParser.Package pkg = mPackages.get(packageName);
25015 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
25016 throw new IllegalArgumentException("Unknown package: " + packageName);
25018 final PackageSetting ps = (PackageSetting) pkg.mExtras;
25019 if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
25020 Slog.w(TAG, "KeySet requested for filtered package: " + packageName);
25021 throw new IllegalArgumentException("Unknown package: " + packageName);
25023 KeySetManagerService ksms = mSettings.mKeySetManagerService;
25024 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
25029 public KeySet getSigningKeySet(String packageName) {
25030 if (packageName == null) {
25033 synchronized(mPackages) {
25034 final int callingUid = Binder.getCallingUid();
25035 final int callingUserId = UserHandle.getUserId(callingUid);
25036 final PackageParser.Package pkg = mPackages.get(packageName);
25038 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
25039 throw new IllegalArgumentException("Unknown package: " + packageName);
25041 final PackageSetting ps = (PackageSetting) pkg.mExtras;
25042 if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
25043 // filter and pretend the package doesn't exist
25044 Slog.w(TAG, "KeySet requested for filtered package: " + packageName
25045 + ", uid:" + callingUid);
25046 throw new IllegalArgumentException("Unknown package: " + packageName);
25048 if (pkg.applicationInfo.uid != callingUid
25049 && Process.SYSTEM_UID != callingUid) {
25050 throw new SecurityException("May not access signing KeySet of other apps.");
25052 KeySetManagerService ksms = mSettings.mKeySetManagerService;
25053 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
25058 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
25059 final int callingUid = Binder.getCallingUid();
25060 if (getInstantAppPackageName(callingUid) != null) {
25063 if (packageName == null || ks == null) {
25066 synchronized(mPackages) {
25067 final PackageParser.Package pkg = mPackages.get(packageName);
25069 || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
25070 UserHandle.getUserId(callingUid))) {
25071 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
25072 throw new IllegalArgumentException("Unknown package: " + packageName);
25074 IBinder ksh = ks.getToken();
25075 if (ksh instanceof KeySetHandle) {
25076 KeySetManagerService ksms = mSettings.mKeySetManagerService;
25077 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
25084 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
25085 final int callingUid = Binder.getCallingUid();
25086 if (getInstantAppPackageName(callingUid) != null) {
25089 if (packageName == null || ks == null) {
25092 synchronized(mPackages) {
25093 final PackageParser.Package pkg = mPackages.get(packageName);
25095 || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
25096 UserHandle.getUserId(callingUid))) {
25097 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
25098 throw new IllegalArgumentException("Unknown package: " + packageName);
25100 IBinder ksh = ks.getToken();
25101 if (ksh instanceof KeySetHandle) {
25102 KeySetManagerService ksms = mSettings.mKeySetManagerService;
25103 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
25109 private void deletePackageIfUnusedLPr(final String packageName) {
25110 PackageSetting ps = mSettings.mPackages.get(packageName);
25114 if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
25115 // TODO Implement atomic delete if package is unused
25116 // It is currently possible that the package will be deleted even if it is installed
25117 // after this method returns.
25118 mHandler.post(new Runnable() {
25119 public void run() {
25120 deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
25121 0, PackageManager.DELETE_ALL_USERS);
25128 * Check and throw if the given before/after packages would be considered a
25131 private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
25132 throws PackageManagerException {
25133 if (after.versionCode < before.mVersionCode) {
25134 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
25135 "Update version code " + after.versionCode + " is older than current "
25136 + before.mVersionCode);
25137 } else if (after.versionCode == before.mVersionCode) {
25138 if (after.baseRevisionCode < before.baseRevisionCode) {
25139 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
25140 "Update base revision code " + after.baseRevisionCode
25141 + " is older than current " + before.baseRevisionCode);
25144 if (!ArrayUtils.isEmpty(after.splitNames)) {
25145 for (int i = 0; i < after.splitNames.length; i++) {
25146 final String splitName = after.splitNames[i];
25147 final int j = ArrayUtils.indexOf(before.splitNames, splitName);
25149 if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
25150 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
25151 "Update split " + splitName + " revision code "
25152 + after.splitRevisionCodes[i] + " is older than current "
25153 + before.splitRevisionCodes[j]);
25161 private static class MoveCallbacks extends Handler {
25162 private static final int MSG_CREATED = 1;
25163 private static final int MSG_STATUS_CHANGED = 2;
25165 private final RemoteCallbackList<IPackageMoveObserver>
25166 mCallbacks = new RemoteCallbackList<>();
25168 private final SparseIntArray mLastStatus = new SparseIntArray();
25170 public MoveCallbacks(Looper looper) {
25174 public void register(IPackageMoveObserver callback) {
25175 mCallbacks.register(callback);
25178 public void unregister(IPackageMoveObserver callback) {
25179 mCallbacks.unregister(callback);
25183 public void handleMessage(Message msg) {
25184 final SomeArgs args = (SomeArgs) msg.obj;
25185 final int n = mCallbacks.beginBroadcast();
25186 for (int i = 0; i < n; i++) {
25187 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
25189 invokeCallback(callback, msg.what, args);
25190 } catch (RemoteException ignored) {
25193 mCallbacks.finishBroadcast();
25197 private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
25198 throws RemoteException {
25200 case MSG_CREATED: {
25201 callback.onCreated(args.argi1, (Bundle) args.arg2);
25204 case MSG_STATUS_CHANGED: {
25205 callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
25211 private void notifyCreated(int moveId, Bundle extras) {
25212 Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
25214 final SomeArgs args = SomeArgs.obtain();
25215 args.argi1 = moveId;
25216 args.arg2 = extras;
25217 obtainMessage(MSG_CREATED, args).sendToTarget();
25220 private void notifyStatusChanged(int moveId, int status) {
25221 notifyStatusChanged(moveId, status, -1);
25224 private void notifyStatusChanged(int moveId, int status, long estMillis) {
25225 Slog.v(TAG, "Move " + moveId + " status " + status);
25227 final SomeArgs args = SomeArgs.obtain();
25228 args.argi1 = moveId;
25229 args.argi2 = status;
25230 args.arg3 = estMillis;
25231 obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
25233 synchronized (mLastStatus) {
25234 mLastStatus.put(moveId, status);
25239 private final static class OnPermissionChangeListeners extends Handler {
25240 private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
25242 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
25243 new RemoteCallbackList<>();
25245 public OnPermissionChangeListeners(Looper looper) {
25250 public void handleMessage(Message msg) {
25251 switch (msg.what) {
25252 case MSG_ON_PERMISSIONS_CHANGED: {
25253 final int uid = msg.arg1;
25254 handleOnPermissionsChanged(uid);
25259 public void addListenerLocked(IOnPermissionsChangeListener listener) {
25260 mPermissionListeners.register(listener);
25264 public void removeListenerLocked(IOnPermissionsChangeListener listener) {
25265 mPermissionListeners.unregister(listener);
25268 public void onPermissionsChanged(int uid) {
25269 if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
25270 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
25274 private void handleOnPermissionsChanged(int uid) {
25275 final int count = mPermissionListeners.beginBroadcast();
25277 for (int i = 0; i < count; i++) {
25278 IOnPermissionsChangeListener callback = mPermissionListeners
25279 .getBroadcastItem(i);
25281 callback.onPermissionsChanged(uid);
25282 } catch (RemoteException e) {
25283 Log.e(TAG, "Permission listener is dead", e);
25287 mPermissionListeners.finishBroadcast();
25292 private class PackageManagerNative extends IPackageManagerNative.Stub {
25294 public String[] getNamesForUids(int[] uids) throws RemoteException {
25295 final String[] results = PackageManagerService.this.getNamesForUids(uids);
25296 // massage results so they can be parsed by the native binder
25297 for (int i = results.length - 1; i >= 0; --i) {
25298 if (results[i] == null) {
25305 // NB: this differentiates between preloads and sideloads
25307 public String getInstallerForPackage(String packageName) throws RemoteException {
25308 final String installerName = getInstallerPackageName(packageName);
25309 if (!TextUtils.isEmpty(installerName)) {
25310 return installerName;
25312 // differentiate between preload and sideload
25313 int callingUser = UserHandle.getUserId(Binder.getCallingUid());
25314 ApplicationInfo appInfo = getApplicationInfo(packageName,
25316 /*userId*/ callingUser);
25317 if (appInfo != null && (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
25324 public int getVersionCodeForPackage(String packageName) throws RemoteException {
25326 int callingUser = UserHandle.getUserId(Binder.getCallingUid());
25327 PackageInfo pInfo = getPackageInfo(packageName, 0, callingUser);
25328 if (pInfo != null) {
25329 return pInfo.versionCode;
25331 } catch (Exception e) {
25337 private class PackageManagerInternalImpl extends PackageManagerInternal {
25339 public void setLocationPackagesProvider(PackagesProvider provider) {
25340 synchronized (mPackages) {
25341 mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
25346 public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
25347 synchronized (mPackages) {
25348 mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
25353 public void setSmsAppPackagesProvider(PackagesProvider provider) {
25354 synchronized (mPackages) {
25355 mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
25360 public void setDialerAppPackagesProvider(PackagesProvider provider) {
25361 synchronized (mPackages) {
25362 mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
25367 public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
25368 synchronized (mPackages) {
25369 mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider);
25374 public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
25375 synchronized (mPackages) {
25376 mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider);
25381 public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
25382 synchronized (mPackages) {
25383 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
25384 packageName, userId);
25389 public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
25390 synchronized (mPackages) {
25391 mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
25392 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
25393 packageName, userId);
25398 public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
25399 synchronized (mPackages) {
25400 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr(
25401 packageName, userId);
25406 public void setKeepUninstalledPackages(final List<String> packageList) {
25407 Preconditions.checkNotNull(packageList);
25408 List<String> removedFromList = null;
25409 synchronized (mPackages) {
25410 if (mKeepUninstalledPackages != null) {
25411 final int packagesCount = mKeepUninstalledPackages.size();
25412 for (int i = 0; i < packagesCount; i++) {
25413 String oldPackage = mKeepUninstalledPackages.get(i);
25414 if (packageList != null && packageList.contains(oldPackage)) {
25417 if (removedFromList == null) {
25418 removedFromList = new ArrayList<>();
25420 removedFromList.add(oldPackage);
25423 mKeepUninstalledPackages = new ArrayList<>(packageList);
25424 if (removedFromList != null) {
25425 final int removedCount = removedFromList.size();
25426 for (int i = 0; i < removedCount; i++) {
25427 deletePackageIfUnusedLPr(removedFromList.get(i));
25434 public boolean isPermissionsReviewRequired(String packageName, int userId) {
25435 synchronized (mPackages) {
25436 // If we do not support permission review, done.
25437 if (!mPermissionReviewRequired) {
25441 PackageSetting packageSetting = mSettings.mPackages.get(packageName);
25442 if (packageSetting == null) {
25446 // Permission review applies only to apps not supporting the new permission model.
25447 if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
25451 // Legacy apps have the permission and get user consent on launch.
25452 PermissionsState permissionsState = packageSetting.getPermissionsState();
25453 return permissionsState.isPermissionReviewRequired(userId);
25458 public PackageInfo getPackageInfo(
25459 String packageName, int flags, int filterCallingUid, int userId) {
25460 return PackageManagerService.this
25461 .getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
25462 flags, filterCallingUid, userId);
25466 public ApplicationInfo getApplicationInfo(
25467 String packageName, int flags, int filterCallingUid, int userId) {
25468 return PackageManagerService.this
25469 .getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
25473 public ActivityInfo getActivityInfo(
25474 ComponentName component, int flags, int filterCallingUid, int userId) {
25475 return PackageManagerService.this
25476 .getActivityInfoInternal(component, flags, filterCallingUid, userId);
25480 public List<ResolveInfo> queryIntentActivities(
25481 Intent intent, int flags, int filterCallingUid, int userId) {
25482 final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
25483 return PackageManagerService.this
25484 .queryIntentActivitiesInternal(intent, resolvedType, flags, filterCallingUid,
25485 userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
25489 public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
25491 return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
25495 public void setDeviceAndProfileOwnerPackages(
25496 int deviceOwnerUserId, String deviceOwnerPackage,
25497 SparseArray<String> profileOwnerPackages) {
25498 mProtectedPackages.setDeviceAndProfileOwnerPackages(
25499 deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
25503 public boolean isPackageDataProtected(int userId, String packageName) {
25504 return mProtectedPackages.isPackageDataProtected(userId, packageName);
25508 public boolean isPackageEphemeral(int userId, String packageName) {
25509 synchronized (mPackages) {
25510 final PackageSetting ps = mSettings.mPackages.get(packageName);
25511 return ps != null ? ps.getInstantApp(userId) : false;
25516 public boolean wasPackageEverLaunched(String packageName, int userId) {
25517 synchronized (mPackages) {
25518 return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
25523 public void grantRuntimePermission(String packageName, String name, int userId,
25524 boolean overridePolicy) {
25525 PackageManagerService.this.grantRuntimePermission(packageName, name, userId,
25530 public void revokeRuntimePermission(String packageName, String name, int userId,
25531 boolean overridePolicy) {
25532 PackageManagerService.this.revokeRuntimePermission(packageName, name, userId,
25537 public String getNameForUid(int uid) {
25538 return PackageManagerService.this.getNameForUid(uid);
25542 public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
25543 Intent origIntent, String resolvedType, String callingPackage,
25544 Bundle verificationBundle, int userId) {
25545 PackageManagerService.this.requestInstantAppResolutionPhaseTwo(
25546 responseObj, origIntent, resolvedType, callingPackage, verificationBundle,
25551 public void grantEphemeralAccess(int userId, Intent intent,
25552 int targetAppId, int ephemeralAppId) {
25553 synchronized (mPackages) {
25554 mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
25555 targetAppId, ephemeralAppId);
25560 public boolean isInstantAppInstallerComponent(ComponentName component) {
25561 synchronized (mPackages) {
25562 return mInstantAppInstallerActivity != null
25563 && mInstantAppInstallerActivity.getComponentName().equals(component);
25568 public void pruneInstantApps() {
25569 mInstantAppRegistry.pruneInstantApps();
25573 public String getSetupWizardPackageName() {
25574 return mSetupWizardPackage;
25577 public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
25578 if (policy != null) {
25579 mExternalSourcesPolicy = policy;
25584 public boolean isPackagePersistent(String packageName) {
25585 synchronized (mPackages) {
25586 PackageParser.Package pkg = mPackages.get(packageName);
25588 ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM
25589 | ApplicationInfo.FLAG_PERSISTENT)) ==
25590 (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT))
25596 public List<PackageInfo> getOverlayPackages(int userId) {
25597 final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
25598 synchronized (mPackages) {
25599 for (PackageParser.Package p : mPackages.values()) {
25600 if (p.mOverlayTarget != null) {
25601 PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
25603 overlayPackages.add(pkg);
25608 return overlayPackages;
25612 public List<String> getTargetPackageNames(int userId) {
25613 List<String> targetPackages = new ArrayList<>();
25614 synchronized (mPackages) {
25615 for (PackageParser.Package p : mPackages.values()) {
25616 if (p.mOverlayTarget == null) {
25617 targetPackages.add(p.packageName);
25621 return targetPackages;
25625 public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
25626 @Nullable List<String> overlayPackageNames) {
25627 synchronized (mPackages) {
25628 if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
25629 Slog.e(TAG, "failed to find package " + targetPackageName);
25632 ArrayList<String> overlayPaths = null;
25633 if (overlayPackageNames != null && overlayPackageNames.size() > 0) {
25634 final int N = overlayPackageNames.size();
25635 overlayPaths = new ArrayList<>(N);
25636 for (int i = 0; i < N; i++) {
25637 final String packageName = overlayPackageNames.get(i);
25638 final PackageParser.Package pkg = mPackages.get(packageName);
25640 Slog.e(TAG, "failed to find package " + packageName);
25643 overlayPaths.add(pkg.baseCodePath);
25647 final PackageSetting ps = mSettings.mPackages.get(targetPackageName);
25648 ps.setOverlayPaths(overlayPaths, userId);
25654 public ResolveInfo resolveIntent(Intent intent, String resolvedType,
25655 int flags, int userId) {
25656 return resolveIntentInternal(
25657 intent, resolvedType, flags, userId, true /*resolveForStart*/);
25661 public ResolveInfo resolveService(Intent intent, String resolvedType,
25662 int flags, int userId, int callingUid) {
25663 return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
25667 public void addIsolatedUid(int isolatedUid, int ownerUid) {
25668 synchronized (mPackages) {
25669 mIsolatedOwners.put(isolatedUid, ownerUid);
25674 public void removeIsolatedUid(int isolatedUid) {
25675 synchronized (mPackages) {
25676 mIsolatedOwners.delete(isolatedUid);
25681 public int getUidTargetSdkVersion(int uid) {
25682 synchronized (mPackages) {
25683 return getUidTargetSdkVersionLockedLPr(uid);
25688 public boolean canAccessInstantApps(int callingUid, int userId) {
25689 return PackageManagerService.this.canViewInstantApps(callingUid, userId);
25693 public boolean hasInstantApplicationMetadata(String packageName, int userId) {
25694 synchronized (mPackages) {
25695 return mInstantAppRegistry.hasInstantApplicationMetadataLPr(packageName, userId);
25700 public void notifyPackageUse(String packageName, int reason) {
25701 synchronized (mPackages) {
25702 PackageManagerService.this.notifyPackageUseLocked(packageName, reason);
25708 public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
25709 enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
25710 synchronized (mPackages) {
25711 final long identity = Binder.clearCallingIdentity();
25713 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
25714 packageNames, userId);
25716 Binder.restoreCallingIdentity(identity);
25722 public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
25723 enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
25724 synchronized (mPackages) {
25725 final long identity = Binder.clearCallingIdentity();
25727 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServicesLPr(
25728 packageNames, userId);
25730 Binder.restoreCallingIdentity(identity);
25735 private static void enforceSystemOrPhoneCaller(String tag) {
25736 int callingUid = Binder.getCallingUid();
25737 if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
25738 throw new SecurityException(
25739 "Cannot call " + tag + " from UID " + callingUid);
25743 boolean isHistoricalPackageUsageAvailable() {
25744 return mPackageUsage.isHistoricalPackageUsageAvailable();
25748 * Return a <b>copy</b> of the collection of packages known to the package manager.
25749 * @return A copy of the values of mPackages.
25751 Collection<PackageParser.Package> getPackages() {
25752 synchronized (mPackages) {
25753 return new ArrayList<>(mPackages.values());
25758 * Logs process start information (including base APK hash) to the security log.
25762 public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
25763 String apkFile, int pid) {
25764 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
25767 if (!SecurityLog.isLoggingEnabled()) {
25770 Bundle data = new Bundle();
25771 data.putLong("startTimestamp", System.currentTimeMillis());
25772 data.putString("processName", processName);
25773 data.putInt("uid", uid);
25774 data.putString("seinfo", seinfo);
25775 data.putString("apkFile", apkFile);
25776 data.putInt("pid", pid);
25777 Message msg = mProcessLoggingHandler.obtainMessage(
25778 ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
25780 mProcessLoggingHandler.sendMessage(msg);
25783 public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
25784 return mCompilerStats.getPackageStats(pkgName);
25787 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
25788 return getOrCreateCompilerPackageStats(pkg.packageName);
25791 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
25792 return mCompilerStats.getOrCreatePackageStats(pkgName);
25795 public void deleteCompilerPackageStats(String pkgName) {
25796 mCompilerStats.deletePackageStats(pkgName);
25800 public int getInstallReason(String packageName, int userId) {
25801 final int callingUid = Binder.getCallingUid();
25802 enforceCrossUserPermission(callingUid, userId,
25803 true /* requireFullPermission */, false /* checkShell */,
25804 "get install reason");
25805 synchronized (mPackages) {
25806 final PackageSetting ps = mSettings.mPackages.get(packageName);
25807 if (filterAppAccessLPr(ps, callingUid, userId)) {
25808 return PackageManager.INSTALL_REASON_UNKNOWN;
25811 return ps.getInstallReason(userId);
25814 return PackageManager.INSTALL_REASON_UNKNOWN;
25818 public boolean canRequestPackageInstalls(String packageName, int userId) {
25819 return canRequestPackageInstallsInternal(packageName, 0, userId,
25820 true /* throwIfPermNotDeclared*/);
25823 private boolean canRequestPackageInstallsInternal(String packageName, int flags, int userId,
25824 boolean throwIfPermNotDeclared) {
25825 int callingUid = Binder.getCallingUid();
25826 int uid = getPackageUid(packageName, 0, userId);
25827 if (callingUid != uid && callingUid != Process.ROOT_UID
25828 && callingUid != Process.SYSTEM_UID) {
25829 throw new SecurityException(
25830 "Caller uid " + callingUid + " does not own package " + packageName);
25832 ApplicationInfo info = getApplicationInfo(packageName, flags, userId);
25833 if (info == null) {
25836 if (info.targetSdkVersion < Build.VERSION_CODES.O) {
25839 String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
25840 String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission);
25841 if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
25842 if (throwIfPermNotDeclared) {
25843 throw new SecurityException("Need to declare " + appOpPermission
25844 + " to call this api");
25846 Slog.e(TAG, "Need to declare " + appOpPermission + " to call this api");
25850 if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) {
25853 if (mExternalSourcesPolicy != null) {
25854 int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
25855 return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
25861 public ComponentName getInstantAppResolverSettingsComponent() {
25862 return mInstantAppResolverSettingsComponent;
25866 public ComponentName getInstantAppInstallerComponent() {
25867 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
25870 return mInstantAppInstallerActivity == null
25871 ? null : mInstantAppInstallerActivity.getComponentName();
25875 public String getInstantAppAndroidId(String packageName, int userId) {
25876 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
25877 "getInstantAppAndroidId");
25878 enforceCrossUserPermission(Binder.getCallingUid(), userId,
25879 true /* requireFullPermission */, false /* checkShell */,
25880 "getInstantAppAndroidId");
25881 // Make sure the target is an Instant App.
25882 if (!isInstantApp(packageName, userId)) {
25885 synchronized (mPackages) {
25886 return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
25890 boolean canHaveOatDir(String packageName) {
25891 synchronized (mPackages) {
25892 PackageParser.Package p = mPackages.get(packageName);
25896 return p.canHaveOatDir();
25900 private String getOatDir(PackageParser.Package pkg) {
25901 if (!pkg.canHaveOatDir()) {
25904 File codePath = new File(pkg.codePath);
25905 if (codePath.isDirectory()) {
25906 return PackageDexOptimizer.getOatDir(codePath).getAbsolutePath();
25911 void deleteOatArtifactsOfPackage(String packageName) {
25912 final String[] instructionSets;
25913 final List<String> codePaths;
25914 final String oatDir;
25915 final PackageParser.Package pkg;
25916 synchronized (mPackages) {
25917 pkg = mPackages.get(packageName);
25919 instructionSets = getAppDexInstructionSets(pkg.applicationInfo);
25920 codePaths = pkg.getAllCodePaths();
25921 oatDir = getOatDir(pkg);
25923 for (String codePath : codePaths) {
25924 for (String isa : instructionSets) {
25926 mInstaller.deleteOdex(codePath, isa, oatDir);
25927 } catch (InstallerException e) {
25928 Log.e(TAG, "Failed deleting oat files for " + codePath, e);
25934 Set<String> getUnusedPackages(long downgradeTimeThresholdMillis) {
25935 Set<String> unusedPackages = new HashSet<>();
25936 long currentTimeInMillis = System.currentTimeMillis();
25937 synchronized (mPackages) {
25938 for (PackageParser.Package pkg : mPackages.values()) {
25939 PackageSetting ps = mSettings.mPackages.get(pkg.packageName);
25943 PackageDexUsage.PackageUseInfo packageUseInfo =
25944 getDexManager().getPackageUseInfoOrDefault(pkg.packageName);
25945 if (PackageManagerServiceUtils
25946 .isUnusedSinceTimeInMillis(ps.firstInstallTime, currentTimeInMillis,
25947 downgradeTimeThresholdMillis, packageUseInfo,
25948 pkg.getLatestPackageUseTimeInMills(),
25949 pkg.getLatestForegroundPackageUseTimeInMills())) {
25950 unusedPackages.add(pkg.packageName);
25954 return unusedPackages;
25958 interface PackageSender {
25959 void sendPackageBroadcast(final String action, final String pkg,
25960 final Bundle extras, final int flags, final String targetPkg,
25961 final IIntentReceiver finishedReceiver, final int[] userIds);
25962 void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
25963 boolean includeStopped, int appId, int... userIds);