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.READ_EXTERNAL_STORAGE;
22 import static android.Manifest.permission.REQUEST_DELETE_PACKAGES;
23 import static android.Manifest.permission.REQUEST_INSTALL_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_SHARED_USER_INCOMPATIBLE;
53 import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
54 import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
55 import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
56 import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
57 import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK;
58 import static android.content.pm.PackageManager.INSTALL_INTERNAL;
59 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
60 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
61 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
62 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
63 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
64 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
65 import static android.content.pm.PackageManager.MATCH_ALL;
66 import static android.content.pm.PackageManager.MATCH_ANY_USER;
67 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
68 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
69 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
70 import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
71 import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
72 import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES;
73 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
74 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
75 import static android.content.pm.PackageManager.MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL;
76 import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN;
77 import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
78 import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
79 import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
80 import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
81 import static android.content.pm.PackageManager.PERMISSION_DENIED;
82 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
83 import static android.content.pm.PackageParser.PARSE_IS_PRIVILEGED;
84 import static android.content.pm.PackageParser.isApkFile;
85 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
86 import static android.system.OsConstants.O_CREAT;
87 import static android.system.OsConstants.O_RDWR;
88 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
89 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
90 import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
91 import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
92 import static com.android.internal.util.ArrayUtils.appendInt;
93 import static com.android.server.pm.Installer.DEXOPT_PUBLIC;
94 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
95 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
96 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
97 import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
98 import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
99 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
100 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getFullCompilerFilter;
101 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getNonProfileGuidedCompilerFilter;
102 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
103 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
104 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
106 import android.Manifest;
107 import android.annotation.NonNull;
108 import android.annotation.Nullable;
109 import android.app.ActivityManager;
110 import android.app.AppOpsManager;
111 import android.app.IActivityManager;
112 import android.app.ResourcesManager;
113 import android.app.admin.IDevicePolicyManager;
114 import android.app.admin.SecurityLog;
115 import android.app.backup.IBackupManager;
116 import android.content.BroadcastReceiver;
117 import android.content.ComponentName;
118 import android.content.ContentResolver;
119 import android.content.Context;
120 import android.content.IIntentReceiver;
121 import android.content.Intent;
122 import android.content.IntentFilter;
123 import android.content.IntentSender;
124 import android.content.IntentSender.SendIntentException;
125 import android.content.ServiceConnection;
126 import android.content.pm.ActivityInfo;
127 import android.content.pm.ApplicationInfo;
128 import android.content.pm.AppsQueryHelper;
129 import android.content.pm.ChangedPackages;
130 import android.content.pm.ComponentInfo;
131 import android.content.pm.InstantAppRequest;
132 import android.content.pm.AuxiliaryResolveInfo;
133 import android.content.pm.FallbackCategoryProvider;
134 import android.content.pm.FeatureInfo;
135 import android.content.pm.IOnPermissionsChangeListener;
136 import android.content.pm.IPackageDataObserver;
137 import android.content.pm.IPackageDeleteObserver;
138 import android.content.pm.IPackageDeleteObserver2;
139 import android.content.pm.IPackageInstallObserver2;
140 import android.content.pm.IPackageInstaller;
141 import android.content.pm.IPackageManager;
142 import android.content.pm.IPackageMoveObserver;
143 import android.content.pm.IPackageStatsObserver;
144 import android.content.pm.InstantAppInfo;
145 import android.content.pm.InstantAppResolveInfo;
146 import android.content.pm.InstrumentationInfo;
147 import android.content.pm.IntentFilterVerificationInfo;
148 import android.content.pm.KeySet;
149 import android.content.pm.PackageCleanItem;
150 import android.content.pm.PackageInfo;
151 import android.content.pm.PackageInfoLite;
152 import android.content.pm.PackageInstaller;
153 import android.content.pm.PackageManager;
154 import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
155 import android.content.pm.PackageManagerInternal;
156 import android.content.pm.PackageParser;
157 import android.content.pm.PackageParser.ActivityIntentInfo;
158 import android.content.pm.PackageParser.PackageLite;
159 import android.content.pm.PackageParser.PackageParserException;
160 import android.content.pm.PackageStats;
161 import android.content.pm.PackageUserState;
162 import android.content.pm.ParceledListSlice;
163 import android.content.pm.PermissionGroupInfo;
164 import android.content.pm.PermissionInfo;
165 import android.content.pm.ProviderInfo;
166 import android.content.pm.ResolveInfo;
167 import android.content.pm.SELinuxUtil;
168 import android.content.pm.ServiceInfo;
169 import android.content.pm.SharedLibraryInfo;
170 import android.content.pm.Signature;
171 import android.content.pm.UserInfo;
172 import android.content.pm.VerifierDeviceIdentity;
173 import android.content.pm.VerifierInfo;
174 import android.content.pm.VersionedPackage;
175 import android.content.res.Resources;
176 import android.graphics.Bitmap;
177 import android.hardware.display.DisplayManager;
178 import android.net.Uri;
179 import android.os.Binder;
180 import android.os.Build;
181 import android.os.Bundle;
182 import android.os.Debug;
183 import android.os.Environment;
184 import android.os.Environment.UserEnvironment;
185 import android.os.FileUtils;
186 import android.os.Handler;
187 import android.os.IBinder;
188 import android.os.Looper;
189 import android.os.Message;
190 import android.os.Parcel;
191 import android.os.ParcelFileDescriptor;
192 import android.os.PatternMatcher;
193 import android.os.Process;
194 import android.os.RemoteCallbackList;
195 import android.os.RemoteException;
196 import android.os.ResultReceiver;
197 import android.os.SELinux;
198 import android.os.ServiceManager;
199 import android.os.ShellCallback;
200 import android.os.SystemClock;
201 import android.os.SystemProperties;
202 import android.os.Trace;
203 import android.os.UserHandle;
204 import android.os.UserManager;
205 import android.os.UserManagerInternal;
206 import android.os.storage.IStorageManager;
207 import android.os.storage.StorageEventListener;
208 import android.os.storage.StorageManager;
209 import android.os.storage.StorageManagerInternal;
210 import android.os.storage.VolumeInfo;
211 import android.os.storage.VolumeRecord;
212 import android.provider.Settings.Global;
213 import android.provider.Settings.Secure;
214 import android.security.KeyStore;
215 import android.security.SystemKeyStore;
216 import android.service.pm.PackageServiceDumpProto;
217 import android.system.ErrnoException;
218 import android.system.Os;
219 import android.text.TextUtils;
220 import android.text.format.DateUtils;
221 import android.util.ArrayMap;
222 import android.util.ArraySet;
223 import android.util.Base64;
224 import android.util.DisplayMetrics;
225 import android.util.EventLog;
226 import android.util.ExceptionUtils;
227 import android.util.Log;
228 import android.util.LogPrinter;
229 import android.util.MathUtils;
230 import android.util.PackageUtils;
231 import android.util.Pair;
232 import android.util.PrintStreamPrinter;
233 import android.util.Slog;
234 import android.util.SparseArray;
235 import android.util.SparseBooleanArray;
236 import android.util.SparseIntArray;
237 import android.util.Xml;
238 import android.util.jar.StrictJarFile;
239 import android.util.proto.ProtoOutputStream;
240 import android.view.Display;
242 import com.android.internal.R;
243 import com.android.internal.annotations.GuardedBy;
244 import com.android.internal.app.IMediaContainerService;
245 import com.android.internal.app.ResolverActivity;
246 import com.android.internal.content.NativeLibraryHelper;
247 import com.android.internal.content.PackageHelper;
248 import com.android.internal.logging.MetricsLogger;
249 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
250 import com.android.internal.os.IParcelFileDescriptorFactory;
251 import com.android.internal.os.RoSystemProperties;
252 import com.android.internal.os.SomeArgs;
253 import com.android.internal.os.Zygote;
254 import com.android.internal.telephony.CarrierAppUtils;
255 import com.android.internal.util.ArrayUtils;
256 import com.android.internal.util.ConcurrentUtils;
257 import com.android.internal.util.FastPrintWriter;
258 import com.android.internal.util.FastXmlSerializer;
259 import com.android.internal.util.IndentingPrintWriter;
260 import com.android.internal.util.Preconditions;
261 import com.android.internal.util.XmlUtils;
262 import com.android.server.AttributeCache;
263 import com.android.server.DeviceIdleController;
264 import com.android.server.EventLogTags;
265 import com.android.server.FgThread;
266 import com.android.server.IntentResolver;
267 import com.android.server.LocalServices;
268 import com.android.server.LockGuard;
269 import com.android.server.ServiceThread;
270 import com.android.server.SystemConfig;
271 import com.android.server.SystemServerInitThreadPool;
272 import com.android.server.Watchdog;
273 import com.android.server.net.NetworkPolicyManagerInternal;
274 import com.android.server.pm.BackgroundDexOptService;
275 import com.android.server.pm.Installer.InstallerException;
276 import com.android.server.pm.PermissionsState.PermissionState;
277 import com.android.server.pm.Settings.DatabaseVersion;
278 import com.android.server.pm.Settings.VersionInfo;
279 import com.android.server.pm.dex.DexManager;
280 import com.android.server.storage.DeviceStorageMonitorInternal;
282 import dalvik.system.CloseGuard;
283 import dalvik.system.DexFile;
284 import dalvik.system.VMRuntime;
286 import libcore.io.IoUtils;
287 import libcore.util.EmptyArray;
289 import org.xmlpull.v1.XmlPullParser;
290 import org.xmlpull.v1.XmlPullParserException;
291 import org.xmlpull.v1.XmlSerializer;
293 import java.io.BufferedOutputStream;
294 import java.io.BufferedReader;
295 import java.io.ByteArrayInputStream;
296 import java.io.ByteArrayOutputStream;
298 import java.io.FileDescriptor;
299 import java.io.FileInputStream;
300 import java.io.FileNotFoundException;
301 import java.io.FileOutputStream;
302 import java.io.FileReader;
303 import java.io.FilenameFilter;
304 import java.io.IOException;
305 import java.io.PrintWriter;
306 import java.nio.charset.StandardCharsets;
307 import java.security.DigestInputStream;
308 import java.security.MessageDigest;
309 import java.security.NoSuchAlgorithmException;
310 import java.security.PublicKey;
311 import java.security.SecureRandom;
312 import java.security.cert.Certificate;
313 import java.security.cert.CertificateEncodingException;
314 import java.security.cert.CertificateException;
315 import java.text.SimpleDateFormat;
316 import java.util.ArrayList;
317 import java.util.Arrays;
318 import java.util.Collection;
319 import java.util.Collections;
320 import java.util.Comparator;
321 import java.util.Date;
322 import java.util.HashMap;
323 import java.util.HashSet;
324 import java.util.Iterator;
325 import java.util.List;
326 import java.util.Map;
327 import java.util.Objects;
328 import java.util.Set;
329 import java.util.concurrent.CountDownLatch;
330 import java.util.concurrent.Future;
331 import java.util.concurrent.TimeUnit;
332 import java.util.concurrent.atomic.AtomicBoolean;
333 import java.util.concurrent.atomic.AtomicInteger;
336 * Keep track of all those APKs everywhere.
338 * Internally there are two important locks:
340 * <li>{@link #mPackages} is used to guard all in-memory parsed package details
341 * and other related state. It is a fine-grained lock that should only be held
342 * momentarily, as it's one of the most contended locks in the system.
343 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
344 * operations typically involve heavy lifting of application data on disk. Since
345 * {@code installd} is single-threaded, and it's operations can often be slow,
346 * this lock should never be acquired while already holding {@link #mPackages}.
347 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
348 * holding {@link #mInstallLock}.
350 * Many internal methods rely on the caller to hold the appropriate locks, and
351 * this contract is expressed through method name suffixes:
353 * <li>fooLI(): the caller must hold {@link #mInstallLock}
354 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
355 * being modified must be frozen
356 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
357 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
360 * Because this class is very central to the platform's security; please run all
361 * CTS and unit tests whenever making modifications:
364 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
365 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
368 public class PackageManagerService extends IPackageManager.Stub {
369 static final String TAG = "PackageManager";
370 static final boolean DEBUG_SETTINGS = false;
371 static final boolean DEBUG_PREFERRED = false;
372 static final boolean DEBUG_UPGRADE = false;
373 static final boolean DEBUG_DOMAIN_VERIFICATION = false;
374 private static final boolean DEBUG_BACKUP = false;
375 private static final boolean DEBUG_INSTALL = false;
376 private static final boolean DEBUG_REMOVE = false;
377 private static final boolean DEBUG_BROADCASTS = false;
378 private static final boolean DEBUG_SHOW_INFO = false;
379 private static final boolean DEBUG_PACKAGE_INFO = false;
380 private static final boolean DEBUG_INTENT_MATCHING = false;
381 private static final boolean DEBUG_PACKAGE_SCANNING = false;
382 private static final boolean DEBUG_VERIFY = false;
383 private static final boolean DEBUG_FILTERS = false;
385 // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
386 // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
387 // user, but by default initialize to this.
388 public static final boolean DEBUG_DEXOPT = false;
390 private static final boolean DEBUG_ABI_SELECTION = false;
391 private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE;
392 private static final boolean DEBUG_TRIAGED_MISSING = false;
393 private static final boolean DEBUG_APP_DATA = false;
395 /** REMOVE. According to Svet, this was only used to reset permissions during development. */
396 static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
398 private static final boolean DISABLE_EPHEMERAL_APPS = false;
399 private static final boolean HIDE_EPHEMERAL_APIS = false;
401 private static final boolean ENABLE_FREE_CACHE_V2 =
402 SystemProperties.getBoolean("fw.free_cache_v2", true);
404 private static final int RADIO_UID = Process.PHONE_UID;
405 private static final int LOG_UID = Process.LOG_UID;
406 private static final int NFC_UID = Process.NFC_UID;
407 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
408 private static final int SHELL_UID = Process.SHELL_UID;
410 // Cap the size of permission trees that 3rd party apps can define
411 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768; // characters of text
413 // Suffix used during package installation when copying/moving
414 // package apks to install directory.
415 private static final String INSTALL_PACKAGE_SUFFIX = "-";
417 static final int SCAN_NO_DEX = 1<<1;
418 static final int SCAN_FORCE_DEX = 1<<2;
419 static final int SCAN_UPDATE_SIGNATURE = 1<<3;
420 static final int SCAN_NEW_INSTALL = 1<<4;
421 static final int SCAN_UPDATE_TIME = 1<<5;
422 static final int SCAN_BOOTING = 1<<6;
423 static final int SCAN_TRUSTED_OVERLAY = 1<<7;
424 static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<8;
425 static final int SCAN_REPLACING = 1<<9;
426 static final int SCAN_REQUIRE_KNOWN = 1<<10;
427 static final int SCAN_MOVE = 1<<11;
428 static final int SCAN_INITIAL = 1<<12;
429 static final int SCAN_CHECK_ONLY = 1<<13;
430 static final int SCAN_DONT_KILL_APP = 1<<14;
431 static final int SCAN_IGNORE_FROZEN = 1<<15;
432 static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<16;
433 static final int SCAN_AS_INSTANT_APP = 1<<17;
434 static final int SCAN_AS_FULL_APP = 1<<18;
435 /** Should not be with the scan flags */
436 static final int FLAGS_REMOVE_CHATTY = 1<<31;
438 private static final String STATIC_SHARED_LIB_DELIMITER = "_";
440 private static final int[] EMPTY_INT_ARRAY = new int[0];
443 * Timeout (in milliseconds) after which the watchdog should declare that
444 * our handler thread is wedged. The usual default for such things is one
445 * minute but we sometimes do very lengthy I/O operations on this thread,
446 * such as installing multi-gigabyte applications, so ours needs to be longer.
448 private static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes
451 * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
452 * be run on this device. We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
453 * settings entry if available, otherwise we use the hardcoded default. If it's been
454 * more than this long since the last fstrim, we force one during the boot sequence.
456 * This backstops other fstrim scheduling: if the device is alive at midnight+idle,
457 * one gets run at the next available charging+idle time. This final mandatory
458 * no-fstrim check kicks in only of the other scheduling criteria is never met.
460 private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
463 * Whether verification is enabled by default.
465 private static final boolean DEFAULT_VERIFY_ENABLE = true;
468 * The default maximum time to wait for the verification agent to return in
471 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
474 * The default response for package verification timeout.
476 * This can be either PackageManager.VERIFICATION_ALLOW or
477 * PackageManager.VERIFICATION_REJECT.
479 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
481 static final String PLATFORM_PACKAGE_NAME = "android";
483 static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
485 static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
486 DEFAULT_CONTAINER_PACKAGE,
487 "com.android.defcontainer.DefaultContainerService");
489 private static final String KILL_APP_REASON_GIDS_CHANGED =
490 "permission grant or revoke changed gids";
492 private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
493 "permissions revoked";
495 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
497 private static final String PACKAGE_SCHEME = "package";
499 private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
501 /** Permission grant: not grant the permission. */
502 private static final int GRANT_DENIED = 1;
504 /** Permission grant: grant the permission as an install permission. */
505 private static final int GRANT_INSTALL = 2;
507 /** Permission grant: grant the permission as a runtime one. */
508 private static final int GRANT_RUNTIME = 3;
510 /** Permission grant: grant as runtime a permission that was granted as an install time one. */
511 private static final int GRANT_UPGRADE = 4;
513 /** Canonical intent used to identify what counts as a "web browser" app */
514 private static final Intent sBrowserIntent;
516 sBrowserIntent = new Intent();
517 sBrowserIntent.setAction(Intent.ACTION_VIEW);
518 sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
519 sBrowserIntent.setData(Uri.parse("http:"));
523 * The set of all protected actions [i.e. those actions for which a high priority
524 * intent filter is disallowed].
526 private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
528 PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
529 PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
530 PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
531 PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
534 // Compilation reasons.
535 public static final int REASON_FIRST_BOOT = 0;
536 public static final int REASON_BOOT = 1;
537 public static final int REASON_INSTALL = 2;
538 public static final int REASON_BACKGROUND_DEXOPT = 3;
539 public static final int REASON_AB_OTA = 4;
540 public static final int REASON_FORCED_DEXOPT = 5;
542 public static final int REASON_LAST = REASON_FORCED_DEXOPT;
544 /** All dangerous permission names in the same order as the events in MetricsEvent */
545 private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList(
546 Manifest.permission.READ_CALENDAR,
547 Manifest.permission.WRITE_CALENDAR,
548 Manifest.permission.CAMERA,
549 Manifest.permission.READ_CONTACTS,
550 Manifest.permission.WRITE_CONTACTS,
551 Manifest.permission.GET_ACCOUNTS,
552 Manifest.permission.ACCESS_FINE_LOCATION,
553 Manifest.permission.ACCESS_COARSE_LOCATION,
554 Manifest.permission.RECORD_AUDIO,
555 Manifest.permission.READ_PHONE_STATE,
556 Manifest.permission.CALL_PHONE,
557 Manifest.permission.READ_CALL_LOG,
558 Manifest.permission.WRITE_CALL_LOG,
559 Manifest.permission.ADD_VOICEMAIL,
560 Manifest.permission.USE_SIP,
561 Manifest.permission.PROCESS_OUTGOING_CALLS,
562 Manifest.permission.READ_CELL_BROADCASTS,
563 Manifest.permission.BODY_SENSORS,
564 Manifest.permission.SEND_SMS,
565 Manifest.permission.RECEIVE_SMS,
566 Manifest.permission.READ_SMS,
567 Manifest.permission.RECEIVE_WAP_PUSH,
568 Manifest.permission.RECEIVE_MMS,
569 Manifest.permission.READ_EXTERNAL_STORAGE,
570 Manifest.permission.WRITE_EXTERNAL_STORAGE,
571 Manifest.permission.READ_PHONE_NUMBERS,
572 Manifest.permission.ANSWER_PHONE_CALLS);
576 * Version number for the package parser cache. Increment this whenever the format or
577 * extent of cached data changes. See {@code PackageParser#setCacheDir}.
579 private static final String PACKAGE_PARSER_CACHE_VERSION = "1";
582 * Whether the package parser cache is enabled.
584 private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
586 final ServiceThread mHandlerThread;
588 final PackageHandler mHandler;
590 private final ProcessLoggingHandler mProcessLoggingHandler;
593 * Messages for {@link #mHandler} that need to wait for system ready before
596 private ArrayList<Message> mPostSystemReadyMessages;
598 final int mSdkVersion = Build.VERSION.SDK_INT;
600 final Context mContext;
601 final boolean mFactoryTest;
602 final boolean mOnlyCore;
603 final DisplayMetrics mMetrics;
604 final int mDefParseFlags;
605 final String[] mSeparateProcesses;
606 final boolean mIsUpgrade;
607 final boolean mIsPreNUpgrade;
608 final boolean mIsPreNMR1Upgrade;
610 @GuardedBy("mPackages")
611 private boolean mDexOptDialogShown;
613 /** The location for ASEC container files on internal storage. */
614 final String mAsecInternalPath;
616 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
617 // LOCK HELD. Can be called with mInstallLock held.
618 @GuardedBy("mInstallLock")
619 final Installer mInstaller;
621 /** Directory where installed third-party apps stored */
622 final File mAppInstallDir;
625 * Directory to which applications installed internally have their
626 * 32 bit native libraries copied.
628 private File mAppLib32InstallDir;
630 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
632 final File mDrmAppPrivateInstallDir;
634 // ----------------------------------------------------------------
636 // Lock for state used when installing and doing other long running
637 // operations. Methods that must be called with this lock held have
639 final Object mInstallLock = new Object();
641 // ----------------------------------------------------------------
643 // Keys are String (package name), values are Package. This also serves
644 // as the lock for the global state. Methods that must be called with
645 // this lock held have the prefix "LP".
646 @GuardedBy("mPackages")
647 final ArrayMap<String, PackageParser.Package> mPackages =
648 new ArrayMap<String, PackageParser.Package>();
650 final ArrayMap<String, Set<String>> mKnownCodebase =
651 new ArrayMap<String, Set<String>>();
653 // Keys are isolated uids and values are the uid of the application
654 // that created the isolated proccess.
655 @GuardedBy("mPackages")
656 final SparseIntArray mIsolatedOwners = new SparseIntArray();
658 // List of APK paths to load for each user and package. This data is never
659 // persisted by the package manager. Instead, the overlay manager will
660 // ensure the data is up-to-date in runtime.
661 @GuardedBy("mPackages")
662 final SparseArray<ArrayMap<String, ArrayList<String>>> mEnabledOverlayPaths =
663 new SparseArray<ArrayMap<String, ArrayList<String>>>();
666 * Tracks new system packages [received in an OTA] that we expect to
667 * find updated user-installed versions. Keys are package name, values
668 * are package location.
670 final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
672 * Tracks high priority intent filters for protected actions. During boot, certain
673 * filter actions are protected and should never be allowed to have a high priority
674 * intent filter for them. However, there is one, and only one exception -- the
675 * setup wizard. It must be able to define a high priority intent filter for these
676 * actions to ensure there are no escapes from the wizard. We need to delay processing
677 * of these during boot as we need to look at all of the system packages in order
678 * to know which component is the setup wizard.
680 private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
682 * Whether or not processing protected filters should be deferred.
684 private boolean mDeferProtectedFilters = true;
687 * Tracks existing system packages prior to receiving an OTA. Keys are package name.
689 final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
691 * Whether or not system app permissions should be promoted from install to runtime.
693 boolean mPromoteSystemApps;
695 @GuardedBy("mPackages")
696 final Settings mSettings;
699 * Set of package names that are currently "frozen", which means active
700 * surgery is being done on the code/data for that package. The platform
701 * will refuse to launch frozen packages to avoid race conditions.
703 * @see PackageFreezer
705 @GuardedBy("mPackages")
706 final ArraySet<String> mFrozenPackages = new ArraySet<>();
708 final ProtectedPackages mProtectedPackages;
712 PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
714 // System configuration read by SystemConfig.
715 final int[] mGlobalGids;
716 final SparseArray<ArraySet<String>> mSystemPermissions;
717 @GuardedBy("mAvailableFeatures")
718 final ArrayMap<String, FeatureInfo> mAvailableFeatures;
720 // If mac_permissions.xml was found for seinfo labeling.
721 boolean mFoundPolicyFile;
723 private final InstantAppRegistry mInstantAppRegistry;
725 @GuardedBy("mPackages")
726 int mChangedPackagesSequenceNumber;
728 * List of changed [installed, removed or updated] packages.
729 * mapping from user id -> sequence number -> package name
731 @GuardedBy("mPackages")
732 final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>();
734 * The sequence number of the last change to a package.
735 * mapping from user id -> package name -> sequence number
737 @GuardedBy("mPackages")
738 final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
740 final PackageParser.Callback mPackageParserCallback = new PackageParser.Callback() {
741 @Override public boolean hasFeature(String feature) {
742 return PackageManagerService.this.hasSystemFeature(feature, 0);
746 public static final class SharedLibraryEntry {
747 public final String path;
748 public final String apk;
749 public final SharedLibraryInfo info;
751 SharedLibraryEntry(String _path, String _apk, String name, int version, int type,
752 String declaringPackageName, int declaringPackageVersionCode) {
755 info = new SharedLibraryInfo(name, version, type, new VersionedPackage(
756 declaringPackageName, declaringPackageVersionCode), null);
760 // Currently known shared libraries.
761 final ArrayMap<String, SparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>();
762 final ArrayMap<String, SparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage =
765 // All available activities, for your resolving pleasure.
766 final ActivityIntentResolver mActivities =
767 new ActivityIntentResolver();
769 // All available receivers, for your resolving pleasure.
770 final ActivityIntentResolver mReceivers =
771 new ActivityIntentResolver();
773 // All available services, for your resolving pleasure.
774 final ServiceIntentResolver mServices = new ServiceIntentResolver();
776 // All available providers, for your resolving pleasure.
777 final ProviderIntentResolver mProviders = new ProviderIntentResolver();
779 // Mapping from provider base names (first directory in content URI codePath)
780 // to the provider information.
781 final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
782 new ArrayMap<String, PackageParser.Provider>();
784 // Mapping from instrumentation class names to info about them.
785 final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
786 new ArrayMap<ComponentName, PackageParser.Instrumentation>();
788 // Mapping from permission names to info about them.
789 final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
790 new ArrayMap<String, PackageParser.PermissionGroup>();
792 // Packages whose data we have transfered into another package, thus
793 // should no longer exist.
794 final ArraySet<String> mTransferedPackages = new ArraySet<String>();
796 // Broadcast actions that are only available to the system.
797 final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>();
799 /** List of packages waiting for verification. */
800 final SparseArray<PackageVerificationState> mPendingVerification
801 = new SparseArray<PackageVerificationState>();
803 /** Set of packages associated with each app op permission. */
804 final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
806 final PackageInstallerService mInstallerService;
808 private final PackageDexOptimizer mPackageDexOptimizer;
809 // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
810 // is used by other apps).
811 private final DexManager mDexManager;
813 private AtomicInteger mNextMoveId = new AtomicInteger();
814 private final MoveCallbacks mMoveCallbacks;
816 private final OnPermissionChangeListeners mOnPermissionChangeListeners;
818 // Cache of users who need badging.
819 SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
821 /** Token for keys in mPendingVerification. */
822 private int mPendingVerificationToken = 0;
824 volatile boolean mSystemReady;
825 volatile boolean mSafeMode;
826 volatile boolean mHasSystemUidErrors;
828 ApplicationInfo mAndroidApplication;
829 final ActivityInfo mResolveActivity = new ActivityInfo();
830 final ResolveInfo mResolveInfo = new ResolveInfo();
831 ComponentName mResolveComponentName;
832 PackageParser.Package mPlatformPackage;
833 ComponentName mCustomResolverComponentName;
835 boolean mResolverReplaced = false;
837 private final @Nullable ComponentName mIntentFilterVerifierComponent;
838 private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
840 private int mIntentFilterVerificationToken = 0;
842 /** The service connection to the ephemeral resolver */
843 final EphemeralResolverConnection mInstantAppResolverConnection;
845 /** Component used to install ephemeral applications */
846 ComponentName mInstantAppInstallerComponent;
847 /** Component used to show resolver settings for Instant Apps */
848 ComponentName mInstantAppResolverSettingsComponent;
849 ActivityInfo mInstantAppInstallerActivity;
850 final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
852 final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
853 = new SparseArray<IntentFilterVerificationState>();
855 final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
857 // List of packages names to keep cached, even if they are uninstalled for all users
858 private List<String> mKeepUninstalledPackages;
860 private UserManagerInternal mUserManagerInternal;
862 private DeviceIdleController.LocalService mDeviceIdleController;
864 private File mCacheDir;
866 private ArraySet<String> mPrivappPermissionsViolations;
868 private Future<?> mPrepareAppDataFuture;
870 private static class IFVerificationParams {
871 PackageParser.Package pkg;
876 public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
877 int _userId, int _verifierUid) {
879 replacing = _replacing;
881 replacing = _replacing;
882 verifierUid = _verifierUid;
886 private interface IntentFilterVerifier<T extends IntentFilter> {
887 boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
888 T filter, String packageName);
889 void startVerifications(int userId);
890 void receiveVerificationResponse(int verificationId);
893 private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
894 private Context mContext;
895 private ComponentName mIntentFilterVerifierComponent;
896 private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
898 public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
900 mIntentFilterVerifierComponent = verifierComponent;
903 private String getDefaultScheme() {
904 return IntentFilter.SCHEME_HTTPS;
908 public void startVerifications(int userId) {
909 // Launch verifications requests
910 int count = mCurrentIntentFilterVerifications.size();
911 for (int n=0; n<count; n++) {
912 int verificationId = mCurrentIntentFilterVerifications.get(n);
913 final IntentFilterVerificationState ivs =
914 mIntentFilterVerificationStates.get(verificationId);
916 String packageName = ivs.getPackageName();
918 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
919 final int filterCount = filters.size();
920 ArraySet<String> domainsSet = new ArraySet<>();
921 for (int m=0; m<filterCount; m++) {
922 PackageParser.ActivityIntentInfo filter = filters.get(m);
923 domainsSet.addAll(filter.getHostsList());
925 synchronized (mPackages) {
926 if (mSettings.createIntentFilterVerificationIfNeededLPw(
927 packageName, domainsSet) != null) {
928 scheduleWriteSettingsLocked();
931 sendVerificationRequest(userId, verificationId, ivs);
933 mCurrentIntentFilterVerifications.clear();
936 private void sendVerificationRequest(int userId, int verificationId,
937 IntentFilterVerificationState ivs) {
939 Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
940 verificationIntent.putExtra(
941 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
943 verificationIntent.putExtra(
944 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
946 verificationIntent.putExtra(
947 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
948 ivs.getHostsString());
949 verificationIntent.putExtra(
950 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
951 ivs.getPackageName());
952 verificationIntent.setComponent(mIntentFilterVerifierComponent);
953 verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
955 UserHandle user = new UserHandle(userId);
956 mContext.sendBroadcastAsUser(verificationIntent, user);
957 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
958 "Sending IntentFilter verification broadcast");
961 public void receiveVerificationResponse(int verificationId) {
962 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
964 final boolean verified = ivs.isVerified();
966 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
967 final int count = filters.size();
968 if (DEBUG_DOMAIN_VERIFICATION) {
969 Slog.i(TAG, "Received verification response " + verificationId
970 + " for " + count + " filters, verified=" + verified);
972 for (int n=0; n<count; n++) {
973 PackageParser.ActivityIntentInfo filter = filters.get(n);
974 filter.setVerified(verified);
976 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
977 + " verified with result:" + verified + " and hosts:"
978 + ivs.getHostsString());
981 mIntentFilterVerificationStates.remove(verificationId);
983 final String packageName = ivs.getPackageName();
984 IntentFilterVerificationInfo ivi = null;
986 synchronized (mPackages) {
987 ivi = mSettings.getIntentFilterVerificationLPr(packageName);
990 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
991 + verificationId + " packageName:" + packageName);
994 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
995 "Updating IntentFilterVerificationInfo for package " + packageName
996 +" verificationId:" + verificationId);
998 synchronized (mPackages) {
1000 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
1002 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
1004 scheduleWriteSettingsLocked();
1006 final int userId = ivs.getUserId();
1007 if (userId != UserHandle.USER_ALL) {
1008 final int userStatus =
1009 mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
1011 int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1012 boolean needUpdate = false;
1014 // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
1015 // already been set by the User thru the Disambiguation dialog
1016 switch (userStatus) {
1017 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
1019 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1021 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
1026 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
1028 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1038 mSettings.updateIntentFilterVerificationStatusLPw(
1039 packageName, updatedStatus, userId);
1040 scheduleWritePackageRestrictionsLocked(userId);
1047 public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
1048 ActivityIntentInfo filter, String packageName) {
1049 if (!hasValidDomains(filter)) {
1052 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1054 ivs = createDomainVerificationState(verifierUid, userId, verificationId,
1057 if (DEBUG_DOMAIN_VERIFICATION) {
1058 Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
1060 ivs.addFilter(filter);
1064 private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
1065 int userId, int verificationId, String packageName) {
1066 IntentFilterVerificationState ivs = new IntentFilterVerificationState(
1067 verifierUid, userId, packageName);
1068 ivs.setPendingState();
1069 synchronized (mPackages) {
1070 mIntentFilterVerificationStates.append(verificationId, ivs);
1071 mCurrentIntentFilterVerifications.add(verificationId);
1077 private static boolean hasValidDomains(ActivityIntentInfo filter) {
1078 return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
1079 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
1080 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
1083 // Set of pending broadcasts for aggregating enable/disable of components.
1084 static class PendingPackageBroadcasts {
1085 // for each user id, a map of <package name -> components within that package>
1086 final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
1088 public PendingPackageBroadcasts() {
1089 mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
1092 public ArrayList<String> get(int userId, String packageName) {
1093 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1094 return packages.get(packageName);
1097 public void put(int userId, String packageName, ArrayList<String> components) {
1098 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1099 packages.put(packageName, components);
1102 public void remove(int userId, String packageName) {
1103 ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1104 if (packages != null) {
1105 packages.remove(packageName);
1109 public void remove(int userId) {
1110 mUidMap.remove(userId);
1113 public int userIdCount() {
1114 return mUidMap.size();
1117 public int userIdAt(int n) {
1118 return mUidMap.keyAt(n);
1121 public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1122 return mUidMap.get(userId);
1126 // total number of pending broadcast entries across all userIds
1128 for (int i = 0; i< mUidMap.size(); i++) {
1129 num += mUidMap.valueAt(i).size();
1134 public void clear() {
1138 private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1139 ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1141 map = new ArrayMap<String, ArrayList<String>>();
1142 mUidMap.put(userId, map);
1147 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1149 // Service Connection to remote media container service to copy
1150 // package uri's from external media onto secure containers
1151 // or internal storage.
1152 private IMediaContainerService mContainerService = null;
1154 static final int SEND_PENDING_BROADCAST = 1;
1155 static final int MCS_BOUND = 3;
1156 static final int END_COPY = 4;
1157 static final int INIT_COPY = 5;
1158 static final int MCS_UNBIND = 6;
1159 static final int START_CLEANING_PACKAGE = 7;
1160 static final int FIND_INSTALL_LOC = 8;
1161 static final int POST_INSTALL = 9;
1162 static final int MCS_RECONNECT = 10;
1163 static final int MCS_GIVE_UP = 11;
1164 static final int UPDATED_MEDIA_STATUS = 12;
1165 static final int WRITE_SETTINGS = 13;
1166 static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1167 static final int PACKAGE_VERIFIED = 15;
1168 static final int CHECK_PENDING_VERIFICATION = 16;
1169 static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1170 static final int INTENT_FILTER_VERIFIED = 18;
1171 static final int WRITE_PACKAGE_LIST = 19;
1172 static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
1174 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds
1176 // Delay time in millisecs
1177 static final int BROADCAST_DELAY = 10 * 1000;
1179 static UserManagerService sUserManager;
1181 // Stores a list of users whose package restrictions file needs to be updated
1182 private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1184 static final long DEFAULT_CONTAINER_WHITELIST_DURATION = 10 * 60 * 1000;
1185 final private DefaultContainerConnection mDefContainerConn =
1186 new DefaultContainerConnection();
1187 class DefaultContainerConnection implements ServiceConnection {
1188 public void onServiceConnected(ComponentName name, IBinder service) {
1189 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1190 final IMediaContainerService imcs = IMediaContainerService.Stub
1191 .asInterface(Binder.allowBlocking(service));
1192 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1195 public void onServiceDisconnected(ComponentName name) {
1196 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1200 // Recordkeeping of restore-after-install operations that are currently in flight
1201 // between the Package Manager and the Backup Manager
1202 static class PostInstallData {
1203 public InstallArgs args;
1204 public PackageInstalledInfo res;
1206 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1212 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1213 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows
1215 // XML tags for backup/restore of various bits of state
1216 private static final String TAG_PREFERRED_BACKUP = "pa";
1217 private static final String TAG_DEFAULT_APPS = "da";
1218 private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1220 private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1221 private static final String TAG_ALL_GRANTS = "rt-grants";
1222 private static final String TAG_GRANT = "grant";
1223 private static final String ATTR_PACKAGE_NAME = "pkg";
1225 private static final String TAG_PERMISSION = "perm";
1226 private static final String ATTR_PERMISSION_NAME = "name";
1227 private static final String ATTR_IS_GRANTED = "g";
1228 private static final String ATTR_USER_SET = "set";
1229 private static final String ATTR_USER_FIXED = "fixed";
1230 private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1232 // System/policy permission grants are not backed up
1233 private static final int SYSTEM_RUNTIME_GRANT_MASK =
1234 FLAG_PERMISSION_POLICY_FIXED
1235 | FLAG_PERMISSION_SYSTEM_FIXED
1236 | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1238 // And we back up these user-adjusted states
1239 private static final int USER_RUNTIME_GRANT_MASK =
1240 FLAG_PERMISSION_USER_SET
1241 | FLAG_PERMISSION_USER_FIXED
1242 | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1244 final @Nullable String mRequiredVerifierPackage;
1245 final @NonNull String mRequiredInstallerPackage;
1246 final @NonNull String mRequiredUninstallerPackage;
1247 final @Nullable String mSetupWizardPackage;
1248 final @Nullable String mStorageManagerPackage;
1249 final @NonNull String mServicesSystemSharedLibraryPackageName;
1250 final @NonNull String mSharedSystemSharedLibraryPackageName;
1252 final boolean mPermissionReviewRequired;
1254 private final PackageUsage mPackageUsage = new PackageUsage();
1255 private final CompilerStats mCompilerStats = new CompilerStats();
1257 class PackageHandler extends Handler {
1258 private boolean mBound = false;
1259 final ArrayList<HandlerParams> mPendingInstalls =
1260 new ArrayList<HandlerParams>();
1262 private boolean connectToService() {
1263 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1264 " DefaultContainerService");
1265 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1266 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1267 if (mContext.bindServiceAsUser(service, mDefContainerConn,
1268 Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1269 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1273 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1277 private void disconnectService() {
1278 mContainerService = null;
1280 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1281 mContext.unbindService(mDefContainerConn);
1282 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1285 PackageHandler(Looper looper) {
1289 public void handleMessage(Message msg) {
1291 doHandleMessage(msg);
1293 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1297 void doHandleMessage(Message msg) {
1300 HandlerParams params = (HandlerParams) msg.obj;
1301 int idx = mPendingInstalls.size();
1302 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1303 // If a bind was already initiated we dont really
1304 // need to do anything. The pending install
1305 // will be processed later on.
1307 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1308 System.identityHashCode(mHandler));
1309 // If this is the only one pending we might
1310 // have to bind to the service again.
1311 if (!connectToService()) {
1312 Slog.e(TAG, "Failed to bind to media container service");
1313 params.serviceError();
1314 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1315 System.identityHashCode(mHandler));
1316 if (params.traceMethod != null) {
1317 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1318 params.traceCookie);
1322 // Once we bind to the service, the first
1323 // pending request will be processed.
1324 mPendingInstalls.add(idx, params);
1327 mPendingInstalls.add(idx, params);
1328 // Already bound to the service. Just make
1329 // sure we trigger off processing the first request.
1331 mHandler.sendEmptyMessage(MCS_BOUND);
1337 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1338 if (msg.obj != null) {
1339 mContainerService = (IMediaContainerService) msg.obj;
1340 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1341 System.identityHashCode(mHandler));
1343 if (mContainerService == null) {
1345 // Something seriously wrong since we are not bound and we are not
1346 // waiting for connection. Bail out.
1347 Slog.e(TAG, "Cannot bind to media container service");
1348 for (HandlerParams params : mPendingInstalls) {
1349 // Indicate service bind error
1350 params.serviceError();
1351 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1352 System.identityHashCode(params));
1353 if (params.traceMethod != null) {
1354 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1355 params.traceMethod, params.traceCookie);
1359 mPendingInstalls.clear();
1361 Slog.w(TAG, "Waiting to connect to media container service");
1363 } else if (mPendingInstalls.size() > 0) {
1364 HandlerParams params = mPendingInstalls.get(0);
1365 if (params != null) {
1366 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1367 System.identityHashCode(params));
1368 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1369 if (params.startCopy()) {
1370 // We are done... look for more work or to
1372 if (DEBUG_SD_INSTALL) Log.i(TAG,
1373 "Checking for more work or unbind...");
1374 // Delete pending install
1375 if (mPendingInstalls.size() > 0) {
1376 mPendingInstalls.remove(0);
1378 if (mPendingInstalls.size() == 0) {
1380 if (DEBUG_SD_INSTALL) Log.i(TAG,
1381 "Posting delayed MCS_UNBIND");
1382 removeMessages(MCS_UNBIND);
1383 Message ubmsg = obtainMessage(MCS_UNBIND);
1384 // Unbind after a little delay, to avoid
1385 // continual thrashing.
1386 sendMessageDelayed(ubmsg, 10000);
1389 // There are more pending requests in queue.
1390 // Just post MCS_BOUND message to trigger processing
1391 // of next pending install.
1392 if (DEBUG_SD_INSTALL) Log.i(TAG,
1393 "Posting MCS_BOUND for next work");
1394 mHandler.sendEmptyMessage(MCS_BOUND);
1397 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1400 // Should never happen ideally.
1401 Slog.w(TAG, "Empty queue");
1405 case MCS_RECONNECT: {
1406 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1407 if (mPendingInstalls.size() > 0) {
1409 disconnectService();
1411 if (!connectToService()) {
1412 Slog.e(TAG, "Failed to bind to media container service");
1413 for (HandlerParams params : mPendingInstalls) {
1414 // Indicate service bind error
1415 params.serviceError();
1416 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1417 System.identityHashCode(params));
1419 mPendingInstalls.clear();
1425 // If there is no actual work left, then time to unbind.
1426 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1428 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1430 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1432 disconnectService();
1434 } else if (mPendingInstalls.size() > 0) {
1435 // There are more pending requests in queue.
1436 // Just post MCS_BOUND message to trigger processing
1437 // of next pending install.
1438 mHandler.sendEmptyMessage(MCS_BOUND);
1444 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1445 HandlerParams params = mPendingInstalls.remove(0);
1446 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1447 System.identityHashCode(params));
1450 case SEND_PENDING_BROADCAST: {
1452 ArrayList<String> components[];
1455 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1456 synchronized (mPackages) {
1457 if (mPendingBroadcasts == null) {
1460 size = mPendingBroadcasts.size();
1462 // Nothing to be done. Just return
1465 packages = new String[size];
1466 components = new ArrayList[size];
1467 uids = new int[size];
1468 int i = 0; // filling out the above arrays
1470 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1471 int packageUserId = mPendingBroadcasts.userIdAt(n);
1472 Iterator<Map.Entry<String, ArrayList<String>>> it
1473 = mPendingBroadcasts.packagesForUserId(packageUserId)
1474 .entrySet().iterator();
1475 while (it.hasNext() && i < size) {
1476 Map.Entry<String, ArrayList<String>> ent = it.next();
1477 packages[i] = ent.getKey();
1478 components[i] = ent.getValue();
1479 PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1480 uids[i] = (ps != null)
1481 ? UserHandle.getUid(packageUserId, ps.appId)
1487 mPendingBroadcasts.clear();
1490 for (int i = 0; i < size; i++) {
1491 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1493 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1496 case START_CLEANING_PACKAGE: {
1497 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1498 final String packageName = (String)msg.obj;
1499 final int userId = msg.arg1;
1500 final boolean andCode = msg.arg2 != 0;
1501 synchronized (mPackages) {
1502 if (userId == UserHandle.USER_ALL) {
1503 int[] users = sUserManager.getUserIds();
1504 for (int user : users) {
1505 mSettings.addPackageToCleanLPw(
1506 new PackageCleanItem(user, packageName, andCode));
1509 mSettings.addPackageToCleanLPw(
1510 new PackageCleanItem(userId, packageName, andCode));
1513 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1514 startCleaningPackages();
1516 case POST_INSTALL: {
1517 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1519 PostInstallData data = mRunningInstalls.get(msg.arg1);
1520 final boolean didRestore = (msg.arg2 != 0);
1521 mRunningInstalls.delete(msg.arg1);
1524 InstallArgs args = data.args;
1525 PackageInstalledInfo parentRes = data.res;
1527 final boolean grantPermissions = (args.installFlags
1528 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1529 final boolean killApp = (args.installFlags
1530 & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1531 final String[] grantedPermissions = args.installGrantPermissions;
1533 // Handle the parent package
1534 handlePackagePostInstall(parentRes, grantPermissions, killApp,
1535 grantedPermissions, didRestore, args.installerPackageName,
1538 // Handle the child packages
1539 final int childCount = (parentRes.addedChildPackages != null)
1540 ? parentRes.addedChildPackages.size() : 0;
1541 for (int i = 0; i < childCount; i++) {
1542 PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1543 handlePackagePostInstall(childRes, grantPermissions, killApp,
1544 grantedPermissions, false, args.installerPackageName,
1548 // Log tracing if needed
1549 if (args.traceMethod != null) {
1550 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1554 Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1557 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1559 case UPDATED_MEDIA_STATUS: {
1560 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1561 boolean reportStatus = msg.arg1 == 1;
1562 boolean doGc = msg.arg2 == 1;
1563 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1565 // Force a gc to clear up stale containers.
1566 Runtime.getRuntime().gc();
1568 if (msg.obj != null) {
1569 @SuppressWarnings("unchecked")
1570 Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1571 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1572 // Unload containers
1573 unloadAllContainers(args);
1577 if (DEBUG_SD_INSTALL) Log.i(TAG,
1578 "Invoking StorageManagerService call back");
1579 PackageHelper.getStorageManager().finishMediaUpdate();
1580 } catch (RemoteException e) {
1581 Log.e(TAG, "StorageManagerService not running?");
1585 case WRITE_SETTINGS: {
1586 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1587 synchronized (mPackages) {
1588 removeMessages(WRITE_SETTINGS);
1589 removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1590 mSettings.writeLPr();
1591 mDirtyUsers.clear();
1593 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1595 case WRITE_PACKAGE_RESTRICTIONS: {
1596 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1597 synchronized (mPackages) {
1598 removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1599 for (int userId : mDirtyUsers) {
1600 mSettings.writePackageRestrictionsLPr(userId);
1602 mDirtyUsers.clear();
1604 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1606 case WRITE_PACKAGE_LIST: {
1607 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1608 synchronized (mPackages) {
1609 removeMessages(WRITE_PACKAGE_LIST);
1610 mSettings.writePackageListLPr(msg.arg1);
1612 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1614 case CHECK_PENDING_VERIFICATION: {
1615 final int verificationId = msg.arg1;
1616 final PackageVerificationState state = mPendingVerification.get(verificationId);
1618 if ((state != null) && !state.timeoutExtended()) {
1619 final InstallArgs args = state.getInstallArgs();
1620 final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1622 Slog.i(TAG, "Verification timed out for " + originUri);
1623 mPendingVerification.remove(verificationId);
1625 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1627 if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
1628 Slog.i(TAG, "Continuing with installation of " + originUri);
1629 state.setVerifierResponse(Binder.getCallingUid(),
1630 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1631 broadcastPackageVerified(verificationId, originUri,
1632 PackageManager.VERIFICATION_ALLOW,
1633 state.getInstallArgs().getUser());
1635 ret = args.copyApk(mContainerService, true);
1636 } catch (RemoteException e) {
1637 Slog.e(TAG, "Could not contact the ContainerService");
1640 broadcastPackageVerified(verificationId, originUri,
1641 PackageManager.VERIFICATION_REJECT,
1642 state.getInstallArgs().getUser());
1645 Trace.asyncTraceEnd(
1646 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1648 processPendingInstall(args, ret);
1649 mHandler.sendEmptyMessage(MCS_UNBIND);
1653 case PACKAGE_VERIFIED: {
1654 final int verificationId = msg.arg1;
1656 final PackageVerificationState state = mPendingVerification.get(verificationId);
1657 if (state == null) {
1658 Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1662 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1664 state.setVerifierResponse(response.callerUid, response.code);
1666 if (state.isVerificationComplete()) {
1667 mPendingVerification.remove(verificationId);
1669 final InstallArgs args = state.getInstallArgs();
1670 final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1673 if (state.isInstallAllowed()) {
1674 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1675 broadcastPackageVerified(verificationId, originUri,
1676 response.code, state.getInstallArgs().getUser());
1678 ret = args.copyApk(mContainerService, true);
1679 } catch (RemoteException e) {
1680 Slog.e(TAG, "Could not contact the ContainerService");
1683 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1686 Trace.asyncTraceEnd(
1687 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1689 processPendingInstall(args, ret);
1690 mHandler.sendEmptyMessage(MCS_UNBIND);
1695 case START_INTENT_FILTER_VERIFICATIONS: {
1696 IFVerificationParams params = (IFVerificationParams) msg.obj;
1697 verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1698 params.replacing, params.pkg);
1701 case INTENT_FILTER_VERIFIED: {
1702 final int verificationId = msg.arg1;
1704 final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1706 if (state == null) {
1707 Slog.w(TAG, "Invalid IntentFilter verification token "
1708 + verificationId + " received");
1712 final int userId = state.getUserId();
1714 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1715 "Processing IntentFilter verification with token:"
1716 + verificationId + " and userId:" + userId);
1718 final IntentFilterVerificationResponse response =
1719 (IntentFilterVerificationResponse) msg.obj;
1721 state.setVerifierResponse(response.callerUid, response.code);
1723 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1724 "IntentFilter verification with token:" + verificationId
1725 + " and userId:" + userId
1726 + " is settings verifier response with response code:"
1729 if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1730 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1731 + response.getFailedDomainsString());
1734 if (state.isVerificationComplete()) {
1735 mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1737 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1738 "IntentFilter verification with token:" + verificationId
1739 + " was not said to be complete");
1744 case INSTANT_APP_RESOLUTION_PHASE_TWO: {
1745 InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
1746 mInstantAppResolverConnection,
1747 (InstantAppRequest) msg.obj,
1748 mInstantAppInstallerActivity,
1755 private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1756 boolean killApp, String[] grantedPermissions,
1757 boolean launchedForRestore, String installerPackage,
1758 IPackageInstallObserver2 installObserver) {
1759 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1760 // Send the removed broadcasts
1761 if (res.removedInfo != null) {
1762 res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1765 // Now that we successfully installed the package, grant runtime
1766 // permissions if requested before broadcasting the install. Also
1767 // for legacy apps in permission review mode we clear the permission
1768 // review flag which is used to emulate runtime permissions for
1770 if (grantPermissions) {
1771 grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions);
1774 final boolean update = res.removedInfo != null
1775 && res.removedInfo.removedPackage != null;
1777 // If this is the first time we have child packages for a disabled privileged
1778 // app that had no children, we grant requested runtime permissions to the new
1779 // children if the parent on the system image had them already granted.
1780 if (res.pkg.parentPackage != null) {
1781 synchronized (mPackages) {
1782 grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg);
1786 synchronized (mPackages) {
1787 mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
1790 final String packageName = res.pkg.applicationInfo.packageName;
1792 // Determine the set of users who are adding this package for
1793 // the first time vs. those who are seeing an update.
1794 int[] firstUsers = EMPTY_INT_ARRAY;
1795 int[] updateUsers = EMPTY_INT_ARRAY;
1796 final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
1797 final PackageSetting ps = (PackageSetting) res.pkg.mExtras;
1798 for (int newUser : res.newUsers) {
1799 if (ps.getInstantApp(newUser)) {
1803 firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1806 boolean isNew = true;
1807 for (int origUser : res.origUsers) {
1808 if (origUser == newUser) {
1814 firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1816 updateUsers = ArrayUtils.appendInt(updateUsers, newUser);
1820 // Send installed broadcasts if the package is not a static shared lib.
1821 if (res.pkg.staticSharedLibName == null) {
1822 mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
1824 // Send added for users that see the package for the first time
1825 // sendPackageAddedForNewUsers also deals with system apps
1826 int appId = UserHandle.getAppId(res.uid);
1827 boolean isSystem = res.pkg.applicationInfo.isSystemApp();
1828 sendPackageAddedForNewUsers(packageName, isSystem, appId, firstUsers);
1830 // Send added for users that don't see the package for the first time
1831 Bundle extras = new Bundle(1);
1832 extras.putInt(Intent.EXTRA_UID, res.uid);
1834 extras.putBoolean(Intent.EXTRA_REPLACING, true);
1836 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1837 extras, 0 /*flags*/, null /*targetPackage*/,
1838 null /*finishedReceiver*/, updateUsers);
1840 // Send replaced for users that don't see the package for the first time
1842 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
1843 packageName, extras, 0 /*flags*/,
1844 null /*targetPackage*/, null /*finishedReceiver*/,
1846 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
1847 null /*package*/, null /*extras*/, 0 /*flags*/,
1848 packageName /*targetPackage*/,
1849 null /*finishedReceiver*/, updateUsers);
1850 } else if (launchedForRestore && !isSystemApp(res.pkg)) {
1851 // First-install and we did a restore, so we're responsible for the
1852 // first-launch broadcast.
1854 Slog.i(TAG, "Post-restore of " + packageName
1855 + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers));
1857 sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers);
1860 // Send broadcast package appeared if forward locked/external for all users
1861 // treat asec-hosted packages like removable media on upgrade
1862 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
1863 if (DEBUG_INSTALL) {
1864 Slog.i(TAG, "upgrading pkg " + res.pkg
1865 + " is ASEC-hosted -> AVAILABLE");
1867 final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
1868 ArrayList<String> pkgList = new ArrayList<>(1);
1869 pkgList.add(packageName);
1870 sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
1874 // Work that needs to happen on first install within each user
1875 if (firstUsers != null && firstUsers.length > 0) {
1876 synchronized (mPackages) {
1877 for (int userId : firstUsers) {
1878 // If this app is a browser and it's newly-installed for some
1879 // users, clear any default-browser state in those users. The
1880 // app's nature doesn't depend on the user, so we can just check
1881 // its browser nature in any user and generalize.
1882 if (packageIsBrowser(packageName, userId)) {
1883 mSettings.setDefaultBrowserPackageNameLPw(null, userId);
1886 // We may also need to apply pending (restored) runtime
1887 // permission grants within these users.
1888 mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
1893 // Log current value of "unknown sources" setting
1894 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
1895 getUnknownSourcesSettings());
1897 // Force a gc to clear up things
1898 Runtime.getRuntime().gc();
1900 // Remove the replaced package's older resources safely now
1901 // We delete after a gc for applications on sdcard.
1902 if (res.removedInfo != null && res.removedInfo.args != null) {
1903 synchronized (mInstallLock) {
1904 res.removedInfo.args.doPostDeleteLI(true);
1908 // Notify DexManager that the package was installed for new users.
1909 // The updated users should already be indexed and the package code paths
1910 // should not change.
1911 // Don't notify the manager for ephemeral apps as they are not expected to
1912 // survive long enough to benefit of background optimizations.
1913 for (int userId : firstUsers) {
1914 PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
1915 mDexManager.notifyPackageInstalled(info, userId);
1919 // If someone is watching installs - notify them
1920 if (installObserver != null) {
1922 Bundle extras = extrasForInstallResult(res);
1923 installObserver.onPackageInstalled(res.name, res.returnCode,
1924 res.returnMsg, extras);
1925 } catch (RemoteException e) {
1926 Slog.i(TAG, "Observer no longer exists.");
1931 private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(
1932 PackageParser.Package pkg) {
1933 if (pkg.parentPackage == null) {
1936 if (pkg.requestedPermissions == null) {
1939 final PackageSetting disabledSysParentPs = mSettings
1940 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
1941 if (disabledSysParentPs == null || disabledSysParentPs.pkg == null
1942 || !disabledSysParentPs.isPrivileged()
1943 || (disabledSysParentPs.childPackageNames != null
1944 && !disabledSysParentPs.childPackageNames.isEmpty())) {
1947 final int[] allUserIds = sUserManager.getUserIds();
1948 final int permCount = pkg.requestedPermissions.size();
1949 for (int i = 0; i < permCount; i++) {
1950 String permission = pkg.requestedPermissions.get(i);
1951 BasePermission bp = mSettings.mPermissions.get(permission);
1952 if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
1955 for (int userId : allUserIds) {
1956 if (disabledSysParentPs.getPermissionsState().hasRuntimePermission(
1957 permission, userId)) {
1958 grantRuntimePermission(pkg.packageName, permission, userId);
1964 private StorageEventListener mStorageListener = new StorageEventListener() {
1966 public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
1967 if (vol.type == VolumeInfo.TYPE_PRIVATE) {
1968 if (vol.state == VolumeInfo.STATE_MOUNTED) {
1969 final String volumeUuid = vol.getFsUuid();
1971 // Clean up any users or apps that were removed or recreated
1972 // while this volume was missing
1973 sUserManager.reconcileUsers(volumeUuid);
1974 reconcileApps(volumeUuid);
1976 // Clean up any install sessions that expired or were
1977 // cancelled while this volume was missing
1978 mInstallerService.onPrivateVolumeMounted(volumeUuid);
1980 loadPrivatePackages(vol);
1982 } else if (vol.state == VolumeInfo.STATE_EJECTING) {
1983 unloadPrivatePackages(vol);
1987 if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) {
1988 if (vol.state == VolumeInfo.STATE_MOUNTED) {
1989 updateExternalMediaStatus(true, false);
1990 } else if (vol.state == VolumeInfo.STATE_EJECTING) {
1991 updateExternalMediaStatus(false, false);
1997 public void onVolumeForgotten(String fsUuid) {
1998 if (TextUtils.isEmpty(fsUuid)) {
1999 Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
2003 // Remove any apps installed on the forgotten volume
2004 synchronized (mPackages) {
2005 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
2006 for (PackageSetting ps : packages) {
2007 Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
2008 deletePackageVersioned(new VersionedPackage(ps.name,
2009 PackageManager.VERSION_CODE_HIGHEST),
2010 new LegacyPackageDeleteObserver(null).getBinder(),
2011 UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
2012 // Try very hard to release any references to this package
2013 // so we don't risk the system server being killed due to
2015 AttributeCache.instance().removePackage(ps.name);
2018 mSettings.onVolumeForgotten(fsUuid);
2019 mSettings.writeLPr();
2024 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
2025 String[] grantedPermissions) {
2026 for (int userId : userIds) {
2027 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions);
2031 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
2032 String[] grantedPermissions) {
2033 SettingBase sb = (SettingBase) pkg.mExtras;
2038 PermissionsState permissionsState = sb.getPermissionsState();
2040 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
2041 | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2043 final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
2044 >= Build.VERSION_CODES.M;
2046 final boolean instantApp = isInstantApp(pkg.packageName, userId);
2048 for (String permission : pkg.requestedPermissions) {
2049 final BasePermission bp;
2050 synchronized (mPackages) {
2051 bp = mSettings.mPermissions.get(permission);
2053 if (bp != null && (bp.isRuntime() || bp.isDevelopment())
2054 && (!instantApp || bp.isInstant())
2055 && (grantedPermissions == null
2056 || ArrayUtils.contains(grantedPermissions, permission))) {
2057 final int flags = permissionsState.getPermissionFlags(permission, userId);
2058 if (supportsRuntimePermissions) {
2059 // Installer cannot change immutable permissions.
2060 if ((flags & immutableFlags) == 0) {
2061 grantRuntimePermission(pkg.packageName, permission, userId);
2063 } else if (mPermissionReviewRequired) {
2064 // In permission review mode we clear the review flag when we
2065 // are asked to install the app with all permissions granted.
2066 if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2067 updatePermissionFlags(permission, pkg.packageName,
2068 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, userId);
2075 Bundle extrasForInstallResult(PackageInstalledInfo res) {
2076 Bundle extras = null;
2077 switch (res.returnCode) {
2078 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2079 extras = new Bundle();
2080 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2081 res.origPermission);
2082 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2086 case PackageManager.INSTALL_SUCCEEDED: {
2087 extras = new Bundle();
2088 extras.putBoolean(Intent.EXTRA_REPLACING,
2089 res.removedInfo != null && res.removedInfo.removedPackage != null);
2096 void scheduleWriteSettingsLocked() {
2097 if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2098 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2102 void scheduleWritePackageListLocked(int userId) {
2103 if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2104 Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2106 mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2110 void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2111 final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2112 scheduleWritePackageRestrictionsLocked(userId);
2115 void scheduleWritePackageRestrictionsLocked(int userId) {
2116 final int[] userIds = (userId == UserHandle.USER_ALL)
2117 ? sUserManager.getUserIds() : new int[]{userId};
2118 for (int nextUserId : userIds) {
2119 if (!sUserManager.exists(nextUserId)) return;
2120 mDirtyUsers.add(nextUserId);
2121 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2122 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2127 public static PackageManagerService main(Context context, Installer installer,
2128 boolean factoryTest, boolean onlyCore) {
2129 // Self-check for initial settings.
2130 PackageManagerServiceCompilerMapping.checkProperties();
2132 PackageManagerService m = new PackageManagerService(context, installer,
2133 factoryTest, onlyCore);
2134 m.enableSystemUserPackages();
2135 ServiceManager.addService("package", m);
2139 private void enableSystemUserPackages() {
2140 if (!UserManager.isSplitSystemUser()) {
2143 // For system user, enable apps based on the following conditions:
2144 // - app is whitelisted or belong to one of these groups:
2145 // -- system app which has no launcher icons
2146 // -- system app which has INTERACT_ACROSS_USERS permission
2147 // -- system IME app
2148 // - app is not in the blacklist
2149 AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2150 Set<String> enableApps = new ArraySet<>();
2151 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2152 | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2153 | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2154 ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2155 enableApps.addAll(wlApps);
2156 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2157 /* systemAppsOnly */ false, UserHandle.SYSTEM));
2158 ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2159 enableApps.removeAll(blApps);
2160 Log.i(TAG, "Applications installed for system user: " + enableApps);
2161 List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2163 final int allAppsSize = allAps.size();
2164 synchronized (mPackages) {
2165 for (int i = 0; i < allAppsSize; i++) {
2166 String pName = allAps.get(i);
2167 PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2168 // Should not happen, but we shouldn't be failing if it does
2169 if (pkgSetting == null) {
2172 boolean install = enableApps.contains(pName);
2173 if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2174 Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2175 + " for system user");
2176 pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2179 scheduleWritePackageRestrictionsLocked(UserHandle.USER_SYSTEM);
2183 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2184 DisplayManager displayManager = (DisplayManager) context.getSystemService(
2185 Context.DISPLAY_SERVICE);
2186 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2190 * Requests that files preopted on a secondary system partition be copied to the data partition
2191 * if possible. Note that the actual copying of the files is accomplished by init for security
2192 * reasons. This simply requests that the copy takes place and awaits confirmation of its
2193 * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2195 private static void requestCopyPreoptedFiles() {
2196 final int WAIT_TIME_MS = 100;
2197 final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2198 if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2199 SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2200 // We will wait for up to 100 seconds.
2201 final long timeStart = SystemClock.uptimeMillis();
2202 final long timeEnd = timeStart + 100 * 1000;
2203 long timeNow = timeStart;
2204 while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2206 Thread.sleep(WAIT_TIME_MS);
2207 } catch (InterruptedException e) {
2210 timeNow = SystemClock.uptimeMillis();
2211 if (timeNow > timeEnd) {
2212 SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2213 Slog.wtf(TAG, "cppreopt did not finish!");
2218 Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2222 public PackageManagerService(Context context, Installer installer,
2223 boolean factoryTest, boolean onlyCore) {
2224 LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
2225 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
2226 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2227 SystemClock.uptimeMillis());
2229 if (mSdkVersion <= 0) {
2230 Slog.w(TAG, "**** ro.build.version.sdk not set!");
2235 mPermissionReviewRequired = context.getResources().getBoolean(
2236 R.bool.config_permissionReviewRequired);
2238 mFactoryTest = factoryTest;
2239 mOnlyCore = onlyCore;
2240 mMetrics = new DisplayMetrics();
2241 mSettings = new Settings(mPackages);
2242 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2243 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2244 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2245 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2246 mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2247 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2248 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2249 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2250 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2251 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2252 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2253 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2255 String separateProcesses = SystemProperties.get("debug.separate_processes");
2256 if (separateProcesses != null && separateProcesses.length() > 0) {
2257 if ("*".equals(separateProcesses)) {
2258 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2259 mSeparateProcesses = null;
2260 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2263 mSeparateProcesses = separateProcesses.split(",");
2264 Slog.w(TAG, "Running with debug.separate_processes: "
2265 + separateProcesses);
2269 mSeparateProcesses = null;
2272 mInstaller = installer;
2273 mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2275 mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock);
2276 mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2278 mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2279 FgThread.get().getLooper());
2281 getDefaultDisplayMetrics(context, mMetrics);
2283 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
2284 SystemConfig systemConfig = SystemConfig.getInstance();
2285 mGlobalGids = systemConfig.getGlobalGids();
2286 mSystemPermissions = systemConfig.getSystemPermissions();
2287 mAvailableFeatures = systemConfig.getAvailableFeatures();
2288 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2290 mProtectedPackages = new ProtectedPackages(mContext);
2292 synchronized (mInstallLock) {
2294 synchronized (mPackages) {
2295 mHandlerThread = new ServiceThread(TAG,
2296 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2297 mHandlerThread.start();
2298 mHandler = new PackageHandler(mHandlerThread.getLooper());
2299 mProcessLoggingHandler = new ProcessLoggingHandler();
2300 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2302 mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this);
2303 mInstantAppRegistry = new InstantAppRegistry(this);
2305 File dataDir = Environment.getDataDirectory();
2306 mAppInstallDir = new File(dataDir, "app");
2307 mAppLib32InstallDir = new File(dataDir, "app-lib");
2308 mAsecInternalPath = new File(dataDir, "app-asec").getPath();
2309 mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
2310 sUserManager = new UserManagerService(context, this,
2311 new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
2313 // Propagate permission configuration in to package manager.
2314 ArrayMap<String, SystemConfig.PermissionEntry> permConfig
2315 = systemConfig.getPermissions();
2316 for (int i=0; i<permConfig.size(); i++) {
2317 SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
2318 BasePermission bp = mSettings.mPermissions.get(perm.name);
2320 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
2321 mSettings.mPermissions.put(perm.name, bp);
2323 if (perm.gids != null) {
2324 bp.setGids(perm.gids, perm.perUser);
2328 ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2329 final int builtInLibCount = libConfig.size();
2330 for (int i = 0; i < builtInLibCount; i++) {
2331 String name = libConfig.keyAt(i);
2332 String path = libConfig.valueAt(i);
2333 addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
2334 SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
2337 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
2339 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
2340 mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2341 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2343 // Clean up orphaned packages for which the code path doesn't exist
2344 // and they are an update to a system app - caused by bug/32321269
2345 final int packageSettingCount = mSettings.mPackages.size();
2346 for (int i = packageSettingCount - 1; i >= 0; i--) {
2347 PackageSetting ps = mSettings.mPackages.valueAt(i);
2348 if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2349 && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2350 mSettings.mPackages.removeAt(i);
2351 mSettings.enableSystemPackageLPw(ps.name);
2356 requestCopyPreoptedFiles();
2359 String customResolverActivity = Resources.getSystem().getString(
2360 R.string.config_customResolverActivity);
2361 if (TextUtils.isEmpty(customResolverActivity)) {
2362 customResolverActivity = null;
2364 mCustomResolverComponentName = ComponentName.unflattenFromString(
2365 customResolverActivity);
2368 long startTime = SystemClock.uptimeMillis();
2370 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2373 final String bootClassPath = System.getenv("BOOTCLASSPATH");
2374 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2376 if (bootClassPath == null) {
2377 Slog.w(TAG, "No BOOTCLASSPATH found!");
2380 if (systemServerClassPath == null) {
2381 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2384 File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2386 final VersionInfo ver = mSettings.getInternalVersion();
2387 mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2389 // when upgrading from pre-M, promote system app permissions from install to runtime
2390 mPromoteSystemApps =
2391 mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2393 // When upgrading from pre-N, we need to handle package extraction like first boot,
2394 // as there is no profiling data available.
2395 mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2397 mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2399 // save off the names of pre-existing system packages prior to scanning; we don't
2400 // want to automatically grant runtime permissions for new system apps
2401 if (mPromoteSystemApps) {
2402 Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2403 while (pkgSettingIter.hasNext()) {
2404 PackageSetting ps = pkgSettingIter.next();
2405 if (isSystemApp(ps)) {
2406 mExistingSystemPackages.add(ps.name);
2411 mCacheDir = preparePackageParserCache(mIsUpgrade);
2413 // Set flag to monitor and not change apk file paths when
2414 // scanning install directories.
2415 int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2417 if (mIsUpgrade || mFirstBoot) {
2418 scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2421 // Collect vendor overlay packages. (Do this before scanning any apps.)
2422 // For security and version matching reason, only consider
2423 // overlay packages if they reside in the right directory.
2424 scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags
2425 | PackageParser.PARSE_IS_SYSTEM
2426 | PackageParser.PARSE_IS_SYSTEM_DIR
2427 | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2429 // Find base frameworks (resource packages without code).
2430 scanDirTracedLI(frameworkDir, mDefParseFlags
2431 | PackageParser.PARSE_IS_SYSTEM
2432 | PackageParser.PARSE_IS_SYSTEM_DIR
2433 | PackageParser.PARSE_IS_PRIVILEGED,
2434 scanFlags | SCAN_NO_DEX, 0);
2436 // Collected privileged system packages.
2437 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2438 scanDirTracedLI(privilegedAppDir, mDefParseFlags
2439 | PackageParser.PARSE_IS_SYSTEM
2440 | PackageParser.PARSE_IS_SYSTEM_DIR
2441 | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
2443 // Collect ordinary system packages.
2444 final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2445 scanDirTracedLI(systemAppDir, mDefParseFlags
2446 | PackageParser.PARSE_IS_SYSTEM
2447 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2449 // Collect all vendor packages.
2450 File vendorAppDir = new File("/vendor/app");
2452 vendorAppDir = vendorAppDir.getCanonicalFile();
2453 } catch (IOException e) {
2454 // failed to look up canonical path, continue with original one
2456 scanDirTracedLI(vendorAppDir, mDefParseFlags
2457 | PackageParser.PARSE_IS_SYSTEM
2458 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2460 // Collect all OEM packages.
2461 final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2462 scanDirTracedLI(oemAppDir, mDefParseFlags
2463 | PackageParser.PARSE_IS_SYSTEM
2464 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2466 // Prune any system packages that no longer exist.
2467 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
2469 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2470 while (psit.hasNext()) {
2471 PackageSetting ps = psit.next();
2474 * If this is not a system app, it can't be a
2475 * disable system app.
2477 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2482 * If the package is scanned, it's not erased.
2484 final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2485 if (scannedPkg != null) {
2487 * If the system app is both scanned and in the
2488 * disabled packages list, then it must have been
2489 * added via OTA. Remove it from the currently
2490 * scanned package so the previously user-installed
2491 * application can be scanned.
2493 if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2494 logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2495 + ps.name + "; removing system app. Last known codePath="
2496 + ps.codePathString + ", installStatus=" + ps.installStatus
2497 + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2498 + scannedPkg.mVersionCode);
2499 removePackageLI(scannedPkg, true);
2500 mExpectingBetter.put(ps.name, ps.codePath);
2506 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2508 logCriticalInfo(Log.WARN, "System package " + ps.name
2509 + " no longer exists; it's data will be wiped");
2510 // Actual deletion of code and data will be handled by later
2511 // reconciliation step
2513 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
2514 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
2515 possiblyDeletedUpdatedSystemApps.add(ps.name);
2521 //look for any incomplete package installations
2522 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2523 for (int i = 0; i < deletePkgsList.size(); i++) {
2524 // Actual deletion of code and data will be handled by later
2525 // reconciliation step
2526 final String packageName = deletePkgsList.get(i).name;
2527 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
2528 synchronized (mPackages) {
2529 mSettings.removePackageLPw(packageName);
2534 deleteTempPackageFiles();
2536 // Remove any shared userIDs that have no associated packages
2537 mSettings.pruneSharedUsersLPw();
2540 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2541 SystemClock.uptimeMillis());
2542 scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2544 scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
2545 | PackageParser.PARSE_FORWARD_LOCK,
2546 scanFlags | SCAN_REQUIRE_KNOWN, 0);
2549 * Remove disable package settings for any updated system
2550 * apps that were removed via an OTA. If they're not a
2551 * previously-updated app, remove them completely.
2552 * Otherwise, just revoke their system-level permissions.
2554 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2555 PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2556 mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2559 if (deletedPkg == null) {
2560 msg = "Updated system package " + deletedAppName
2561 + " no longer exists; it's data will be wiped";
2562 // Actual deletion of code and data will be handled by later
2563 // reconciliation step
2565 msg = "Updated system app + " + deletedAppName
2566 + " no longer present; removing system privileges for "
2569 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2571 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2572 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2574 logCriticalInfo(Log.WARN, msg);
2578 * Make sure all system apps that we expected to appear on
2579 * the userdata partition actually showed up. If they never
2580 * appeared, crawl back and revive the system version.
2582 for (int i = 0; i < mExpectingBetter.size(); i++) {
2583 final String packageName = mExpectingBetter.keyAt(i);
2584 if (!mPackages.containsKey(packageName)) {
2585 final File scanFile = mExpectingBetter.valueAt(i);
2587 logCriticalInfo(Log.WARN, "Expected better " + packageName
2588 + " but never showed up; reverting to system");
2590 int reparseFlags = mDefParseFlags;
2591 if (FileUtils.contains(privilegedAppDir, scanFile)) {
2592 reparseFlags = PackageParser.PARSE_IS_SYSTEM
2593 | PackageParser.PARSE_IS_SYSTEM_DIR
2594 | PackageParser.PARSE_IS_PRIVILEGED;
2595 } else if (FileUtils.contains(systemAppDir, scanFile)) {
2596 reparseFlags = PackageParser.PARSE_IS_SYSTEM
2597 | PackageParser.PARSE_IS_SYSTEM_DIR;
2598 } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2599 reparseFlags = PackageParser.PARSE_IS_SYSTEM
2600 | PackageParser.PARSE_IS_SYSTEM_DIR;
2601 } else if (FileUtils.contains(oemAppDir, scanFile)) {
2602 reparseFlags = PackageParser.PARSE_IS_SYSTEM
2603 | PackageParser.PARSE_IS_SYSTEM_DIR;
2605 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2609 mSettings.enableSystemPackageLPw(packageName);
2612 scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
2613 } catch (PackageManagerException e) {
2614 Slog.e(TAG, "Failed to parse original system package: "
2620 mExpectingBetter.clear();
2622 // Resolve the storage manager.
2623 mStorageManagerPackage = getStorageManagerPackageName();
2625 // Resolve protected action filters. Only the setup wizard is allowed to
2626 // have a high priority filter for these actions.
2627 mSetupWizardPackage = getSetupWizardPackageName();
2628 if (mProtectedFilters.size() > 0) {
2629 if (DEBUG_FILTERS && mSetupWizardPackage == null) {
2630 Slog.i(TAG, "No setup wizard;"
2631 + " All protected intents capped to priority 0");
2633 for (ActivityIntentInfo filter : mProtectedFilters) {
2634 if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
2635 if (DEBUG_FILTERS) {
2636 Slog.i(TAG, "Found setup wizard;"
2637 + " allow priority " + filter.getPriority() + ";"
2638 + " package: " + filter.activity.info.packageName
2639 + " activity: " + filter.activity.className
2640 + " priority: " + filter.getPriority());
2642 // skip setup wizard; allow it to keep the high priority filter
2645 Slog.w(TAG, "Protected action; cap priority to 0;"
2646 + " package: " + filter.activity.info.packageName
2647 + " activity: " + filter.activity.className
2648 + " origPrio: " + filter.getPriority());
2649 filter.setPriority(0);
2652 mDeferProtectedFilters = false;
2653 mProtectedFilters.clear();
2655 // Now that we know all of the shared libraries, update all clients to have
2656 // the correct library paths.
2657 updateAllSharedLibrariesLPw(null);
2659 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2660 // NOTE: We ignore potential failures here during a system scan (like
2661 // the rest of the commands above) because there's precious little we
2662 // can do about it. A settings error is reported, though.
2663 adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
2666 // Now that we know all the packages we are keeping,
2667 // read and update their last usage times.
2668 mPackageUsage.read(mPackages);
2669 mCompilerStats.read();
2671 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2672 SystemClock.uptimeMillis());
2673 Slog.i(TAG, "Time to scan packages: "
2674 + ((SystemClock.uptimeMillis()-startTime)/1000f)
2677 // If the platform SDK has changed since the last time we booted,
2678 // we need to re-grant app permission to catch any new ones that
2679 // appear. This is really a hack, and means that apps can in some
2680 // cases get permissions that the user didn't initially explicitly
2681 // allow... it would be nice to have some better way to handle
2683 int updateFlags = UPDATE_PERMISSIONS_ALL;
2684 if (ver.sdkVersion != mSdkVersion) {
2685 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2686 + mSdkVersion + "; regranting permissions for internal storage");
2687 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
2689 updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
2690 ver.sdkVersion = mSdkVersion;
2692 // If this is the first boot or an update from pre-M, and it is a normal
2693 // boot, then we need to initialize the default preferred apps across
2694 // all defined users.
2695 if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
2696 for (UserInfo user : sUserManager.getUsers(true)) {
2697 mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2698 applyFactoryDefaultBrowserLPw(user.id);
2699 primeDomainVerificationsLPw(user.id);
2703 // Prepare storage for system user really early during boot,
2704 // since core system apps like SettingsProvider and SystemUI
2705 // can't wait for user to start
2706 final int storageFlags;
2707 if (StorageManager.isFileEncryptedNativeOrEmulated()) {
2708 storageFlags = StorageManager.FLAG_STORAGE_DE;
2710 storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
2712 List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
2713 UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
2714 true /* onlyCoreApps */);
2715 mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
2716 if (deferPackages == null || deferPackages.isEmpty()) {
2720 for (String pkgName : deferPackages) {
2721 PackageParser.Package pkg = null;
2722 synchronized (mPackages) {
2723 PackageSetting ps = mSettings.getPackageLPr(pkgName);
2724 if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
2729 synchronized (mInstallLock) {
2730 prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
2731 true /* maybeMigrateAppData */);
2736 Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
2737 }, "prepareAppData");
2739 // If this is first boot after an OTA, and a normal boot, then
2740 // we need to clear code cache directories.
2741 // Note that we do *not* clear the application profiles. These remain valid
2742 // across OTAs and are used to drive profile verification (post OTA) and
2743 // profile compilation (without waiting to collect a fresh set of profiles).
2744 if (mIsUpgrade && !onlyCore) {
2745 Slog.i(TAG, "Build fingerprint changed; clearing code caches");
2746 for (int i = 0; i < mSettings.mPackages.size(); i++) {
2747 final PackageSetting ps = mSettings.mPackages.valueAt(i);
2748 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
2749 // No apps are running this early, so no need to freeze
2750 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
2751 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
2752 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
2755 ver.fingerprint = Build.FINGERPRINT;
2758 checkDefaultBrowser();
2760 // clear only after permissions and other defaults have been updated
2761 mExistingSystemPackages.clear();
2762 mPromoteSystemApps = false;
2764 // All the changes are done during package scanning.
2765 ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
2767 // can downgrade to reader
2768 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
2769 mSettings.writeLPr();
2770 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2772 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
2773 SystemClock.uptimeMillis());
2776 mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
2777 mRequiredInstallerPackage = getRequiredInstallerLPr();
2778 mRequiredUninstallerPackage = getRequiredUninstallerLPr();
2779 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
2780 mIntentFilterVerifier = new IntentVerifierProxy(mContext,
2781 mIntentFilterVerifierComponent);
2782 mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2783 PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
2784 SharedLibraryInfo.VERSION_UNDEFINED);
2785 mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2786 PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
2787 SharedLibraryInfo.VERSION_UNDEFINED);
2789 mRequiredVerifierPackage = null;
2790 mRequiredInstallerPackage = null;
2791 mRequiredUninstallerPackage = null;
2792 mIntentFilterVerifierComponent = null;
2793 mIntentFilterVerifier = null;
2794 mServicesSystemSharedLibraryPackageName = null;
2795 mSharedSystemSharedLibraryPackageName = null;
2798 mInstallerService = new PackageInstallerService(context, this);
2799 final ComponentName ephemeralResolverComponent = getEphemeralResolverLPr();
2800 if (ephemeralResolverComponent != null) {
2801 if (DEBUG_EPHEMERAL) {
2802 Slog.d(TAG, "Set ephemeral resolver: " + ephemeralResolverComponent);
2804 mInstantAppResolverConnection =
2805 new EphemeralResolverConnection(mContext, ephemeralResolverComponent);
2807 mInstantAppResolverConnection = null;
2809 updateInstantAppInstallerLocked();
2810 mInstantAppResolverSettingsComponent = getEphemeralResolverSettingsLPr();
2812 // Read and update the usage of dex files.
2813 // Do this at the end of PM init so that all the packages have their
2814 // data directory reconciled.
2815 // At this point we know the code paths of the packages, so we can validate
2816 // the disk file and build the internal cache.
2817 // The usage file is expected to be small so loading and verifying it
2818 // should take a fairly small time compare to the other activities (e.g. package
2820 final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
2821 final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
2822 for (int userId : currentUserIds) {
2823 userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
2825 mDexManager.load(userPackages);
2826 } // synchronized (mPackages)
2827 } // synchronized (mInstallLock)
2829 // Now after opening every single application zip, make sure they
2830 // are all flushed. Not really needed, but keeps things nice and
2832 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
2833 Runtime.getRuntime().gc();
2834 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2836 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
2837 FallbackCategoryProvider.loadFallbacks();
2838 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2840 // The initial scanning above does many calls into installd while
2841 // holding the mPackages lock, but we're mostly interested in yelling
2842 // once we have a booted system.
2843 mInstaller.setWarnIfHeld(mPackages);
2845 // Expose private service for system components to use.
2846 LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
2847 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2850 private void updateInstantAppInstallerLocked() {
2851 final ComponentName oldInstantAppInstallerComponent = mInstantAppInstallerComponent;
2852 final ActivityInfo newInstantAppInstaller = getEphemeralInstallerLPr();
2853 ComponentName newInstantAppInstallerComponent = newInstantAppInstaller == null
2854 ? null : newInstantAppInstaller.getComponentName();
2856 if (newInstantAppInstallerComponent != null
2857 && !newInstantAppInstallerComponent.equals(oldInstantAppInstallerComponent)) {
2858 if (DEBUG_EPHEMERAL) {
2859 Slog.d(TAG, "Set ephemeral installer: " + newInstantAppInstallerComponent);
2861 setUpInstantAppInstallerActivityLP(newInstantAppInstaller);
2862 } else if (DEBUG_EPHEMERAL && newInstantAppInstallerComponent == null) {
2863 Slog.d(TAG, "Unset ephemeral installer; none available");
2865 mInstantAppInstallerComponent = newInstantAppInstallerComponent;
2868 private static File preparePackageParserCache(boolean isUpgrade) {
2869 if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
2873 // Disable package parsing on eng builds to allow for faster incremental development.
2874 if ("eng".equals(Build.TYPE)) {
2878 if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
2879 Slog.i(TAG, "Disabling package parser cache due to system property.");
2883 // The base directory for the package parser cache lives under /data/system/.
2884 final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(),
2886 if (cacheBaseDir == null) {
2890 // If this is a system upgrade scenario, delete the contents of the package cache dir.
2891 // This also serves to "GC" unused entries when the package cache version changes (which
2892 // can only happen during upgrades).
2894 FileUtils.deleteContents(cacheBaseDir);
2898 // Return the versioned package cache directory. This is something like
2899 // "/data/system/package_cache/1"
2900 File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
2902 // The following is a workaround to aid development on non-numbered userdebug
2903 // builds or cases where "adb sync" is used on userdebug builds. If we detect that
2904 // the system partition is newer.
2906 // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
2907 // that starts with "eng." to signify that this is an engineering build and not
2908 // destined for release.
2909 if ("userdebug".equals(Build.TYPE) && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
2910 Slog.w(TAG, "Wiping cache directory because the system partition changed.");
2912 // Heuristic: If the /system directory has been modified recently due to an "adb sync"
2913 // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
2914 // in general and should not be used for production changes. In this specific case,
2915 // we know that they will work.
2916 File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2917 if (cacheDir.lastModified() < frameworkDir.lastModified()) {
2918 FileUtils.deleteContents(cacheBaseDir);
2919 cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
2927 public boolean isFirstBoot() {
2932 public boolean isOnlyCoreApps() {
2937 public boolean isUpgrade() {
2941 private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
2942 final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
2944 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
2945 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2946 UserHandle.USER_SYSTEM);
2947 if (matches.size() == 1) {
2948 return matches.get(0).getComponentInfo().packageName;
2949 } else if (matches.size() == 0) {
2950 Log.e(TAG, "There should probably be a verifier, but, none were found");
2953 throw new RuntimeException("There must be exactly one verifier; found " + matches);
2956 private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
2957 synchronized (mPackages) {
2958 SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version);
2959 if (libraryEntry == null) {
2960 throw new IllegalStateException("Missing required shared library:" + name);
2962 return libraryEntry.apk;
2966 private @NonNull String getRequiredInstallerLPr() {
2967 final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
2968 intent.addCategory(Intent.CATEGORY_DEFAULT);
2969 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
2971 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
2972 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2973 UserHandle.USER_SYSTEM);
2974 if (matches.size() == 1) {
2975 ResolveInfo resolveInfo = matches.get(0);
2976 if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
2977 throw new RuntimeException("The installer must be a privileged app");
2979 return matches.get(0).getComponentInfo().packageName;
2981 throw new RuntimeException("There must be exactly one installer; found " + matches);
2985 private @NonNull String getRequiredUninstallerLPr() {
2986 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
2987 intent.addCategory(Intent.CATEGORY_DEFAULT);
2988 intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
2990 final ResolveInfo resolveInfo = resolveIntent(intent, null,
2991 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2992 UserHandle.USER_SYSTEM);
2993 if (resolveInfo == null ||
2994 mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
2995 throw new RuntimeException("There must be exactly one uninstaller; found "
2998 return resolveInfo.getComponentInfo().packageName;
3001 private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3002 final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3004 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3005 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3006 UserHandle.USER_SYSTEM);
3007 ResolveInfo best = null;
3008 final int N = matches.size();
3009 for (int i = 0; i < N; i++) {
3010 final ResolveInfo cur = matches.get(i);
3011 final String packageName = cur.getComponentInfo().packageName;
3012 if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3013 packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3017 if (best == null || cur.priority > best.priority) {
3023 return best.getComponentInfo().getComponentName();
3025 throw new RuntimeException("There must be at least one intent filter verifier");
3029 private @Nullable ComponentName getEphemeralResolverLPr() {
3030 final String[] packageArray =
3031 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3032 if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3033 if (DEBUG_EPHEMERAL) {
3034 Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3039 final int resolveFlags =
3040 MATCH_DIRECT_BOOT_AWARE
3041 | MATCH_DIRECT_BOOT_UNAWARE
3042 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3043 final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE);
3044 final List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3045 resolveFlags, UserHandle.USER_SYSTEM);
3047 final int N = resolvers.size();
3049 if (DEBUG_EPHEMERAL) {
3050 Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3055 final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3056 for (int i = 0; i < N; i++) {
3057 final ResolveInfo info = resolvers.get(i);
3059 if (info.serviceInfo == null) {
3063 final String packageName = info.serviceInfo.packageName;
3064 if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3065 if (DEBUG_EPHEMERAL) {
3066 Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3067 + " pkg: " + packageName + ", info:" + info);
3072 if (DEBUG_EPHEMERAL) {
3073 Slog.v(TAG, "Ephemeral resolver found;"
3074 + " pkg: " + packageName + ", info:" + info);
3076 return new ComponentName(packageName, info.serviceInfo.name);
3078 if (DEBUG_EPHEMERAL) {
3079 Slog.v(TAG, "Ephemeral resolver NOT found");
3084 private @Nullable ActivityInfo getEphemeralInstallerLPr() {
3085 final Intent intent = new Intent(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
3086 intent.addCategory(Intent.CATEGORY_DEFAULT);
3087 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3089 final int resolveFlags =
3090 MATCH_DIRECT_BOOT_AWARE
3091 | MATCH_DIRECT_BOOT_UNAWARE
3092 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3093 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3094 resolveFlags, UserHandle.USER_SYSTEM);
3095 Iterator<ResolveInfo> iter = matches.iterator();
3096 while (iter.hasNext()) {
3097 final ResolveInfo rInfo = iter.next();
3098 final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3100 final PermissionsState permissionsState = ps.getPermissionsState();
3101 if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)) {
3107 if (matches.size() == 0) {
3109 } else if (matches.size() == 1) {
3110 return (ActivityInfo) matches.get(0).getComponentInfo();
3112 throw new RuntimeException(
3113 "There must be at most one ephemeral installer; found " + matches);
3117 private @Nullable ComponentName getEphemeralResolverSettingsLPr() {
3118 final Intent intent = new Intent(Intent.ACTION_EPHEMERAL_RESOLVER_SETTINGS);
3119 intent.addCategory(Intent.CATEGORY_DEFAULT);
3120 final int resolveFlags =
3121 MATCH_DIRECT_BOOT_AWARE
3122 | MATCH_DIRECT_BOOT_UNAWARE
3123 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3124 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
3125 resolveFlags, UserHandle.USER_SYSTEM);
3126 Iterator<ResolveInfo> iter = matches.iterator();
3127 while (iter.hasNext()) {
3128 final ResolveInfo rInfo = iter.next();
3129 final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3131 final PermissionsState permissionsState = ps.getPermissionsState();
3132 if (permissionsState.hasPermission(Manifest.permission.ACCESS_INSTANT_APPS, 0)) {
3138 if (matches.size() == 0) {
3140 } else if (matches.size() == 1) {
3141 return matches.get(0).getComponentInfo().getComponentName();
3143 throw new RuntimeException(
3144 "There must be at most one ephemeral resolver settings; found " + matches);
3148 private void primeDomainVerificationsLPw(int userId) {
3149 if (DEBUG_DOMAIN_VERIFICATION) {
3150 Slog.d(TAG, "Priming domain verifications in user " + userId);
3153 SystemConfig systemConfig = SystemConfig.getInstance();
3154 ArraySet<String> packages = systemConfig.getLinkedApps();
3156 for (String packageName : packages) {
3157 PackageParser.Package pkg = mPackages.get(packageName);
3159 if (!pkg.isSystemApp()) {
3160 Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
3164 ArraySet<String> domains = null;
3165 for (PackageParser.Activity a : pkg.activities) {
3166 for (ActivityIntentInfo filter : a.intents) {
3167 if (hasValidDomains(filter)) {
3168 if (domains == null) {
3169 domains = new ArraySet<String>();
3171 domains.addAll(filter.getHostsList());
3176 if (domains != null && domains.size() > 0) {
3177 if (DEBUG_DOMAIN_VERIFICATION) {
3178 Slog.v(TAG, " + " + packageName);
3180 // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
3181 // state w.r.t. the formal app-linkage "no verification attempted" state;
3182 // and then 'always' in the per-user state actually used for intent resolution.
3183 final IntentFilterVerificationInfo ivi;
3184 ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
3185 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
3186 mSettings.updateIntentFilterVerificationStatusLPw(packageName,
3187 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
3189 Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
3190 + "' does not handle web links");
3193 Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
3197 scheduleWritePackageRestrictionsLocked(userId);
3198 scheduleWriteSettingsLocked();
3201 private void applyFactoryDefaultBrowserLPw(int userId) {
3202 // The default browser app's package name is stored in a string resource,
3203 // with a product-specific overlay used for vendor customization.
3204 String browserPkg = mContext.getResources().getString(
3205 com.android.internal.R.string.default_browser);
3206 if (!TextUtils.isEmpty(browserPkg)) {
3207 // non-empty string => required to be a known package
3208 PackageSetting ps = mSettings.mPackages.get(browserPkg);
3210 Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
3213 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3217 // Nothing valid explicitly set? Make the factory-installed browser the explicit
3218 // default. If there's more than one, just leave everything alone.
3219 if (browserPkg == null) {
3220 calculateDefaultBrowserLPw(userId);
3224 private void calculateDefaultBrowserLPw(int userId) {
3225 List<String> allBrowsers = resolveAllBrowserApps(userId);
3226 final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
3227 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3230 private List<String> resolveAllBrowserApps(int userId) {
3231 // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
3232 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3233 PackageManager.MATCH_ALL, userId);
3235 final int count = list.size();
3236 List<String> result = new ArrayList<String>(count);
3237 for (int i=0; i<count; i++) {
3238 ResolveInfo info = list.get(i);
3239 if (info.activityInfo == null
3240 || !info.handleAllWebDataURI
3241 || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
3242 || result.contains(info.activityInfo.packageName)) {
3245 result.add(info.activityInfo.packageName);
3251 private boolean packageIsBrowser(String packageName, int userId) {
3252 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3253 PackageManager.MATCH_ALL, userId);
3254 final int N = list.size();
3255 for (int i = 0; i < N; i++) {
3256 ResolveInfo info = list.get(i);
3257 if (packageName.equals(info.activityInfo.packageName)) {
3264 private void checkDefaultBrowser() {
3265 final int myUserId = UserHandle.myUserId();
3266 final String packageName = getDefaultBrowserPackageName(myUserId);
3267 if (packageName != null) {
3268 PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3270 Slog.w(TAG, "Default browser no longer installed: " + packageName);
3271 synchronized (mPackages) {
3272 applyFactoryDefaultBrowserLPw(myUserId); // leaves ambiguous when > 1
3279 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3280 throws RemoteException {
3282 return super.onTransact(code, data, reply, flags);
3283 } catch (RuntimeException e) {
3284 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3285 Slog.wtf(TAG, "Package Manager Crash", e);
3291 static int[] appendInts(int[] cur, int[] add) {
3292 if (add == null) return cur;
3293 if (cur == null) return add;
3294 final int N = add.length;
3295 for (int i=0; i<N; i++) {
3296 cur = appendInt(cur, add[i]);
3301 private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3302 if (!sUserManager.exists(userId)) return null;
3306 final PackageParser.Package p = ps.pkg;
3310 // Filter out ephemeral app metadata:
3311 // * The system/shell/root can see metadata for any app
3312 // * An installed app can see metadata for 1) other installed apps
3313 // and 2) ephemeral apps that have explicitly interacted with it
3314 // * Ephemeral apps can only see their own data and exposed installed apps
3315 // * Holding a signature permission allows seeing instant apps
3316 final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
3317 if (callingAppId != Process.SYSTEM_UID
3318 && callingAppId != Process.SHELL_UID
3319 && callingAppId != Process.ROOT_UID
3320 && checkUidPermission(Manifest.permission.ACCESS_INSTANT_APPS,
3321 Binder.getCallingUid()) != PackageManager.PERMISSION_GRANTED) {
3322 final String instantAppPackageName = getInstantAppPackageName(Binder.getCallingUid());
3323 if (instantAppPackageName != null) {
3324 // ephemeral apps can only get information on themselves or
3325 // installed apps that are exposed.
3326 if (!instantAppPackageName.equals(p.packageName)
3327 && (ps.getInstantApp(userId) || !p.visibleToInstantApps)) {
3331 if (ps.getInstantApp(userId)) {
3332 // only get access to the ephemeral app if we've been granted access
3333 if (!mInstantAppRegistry.isInstantAccessGranted(
3334 userId, callingAppId, ps.appId)) {
3341 final PermissionsState permissionsState = ps.getPermissionsState();
3343 // Compute GIDs only if requested
3344 final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3345 ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3346 // Compute granted permissions only if package has requested permissions
3347 final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3348 ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3349 final PackageUserState state = ps.readUserState(userId);
3351 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
3353 flags |= MATCH_ANY_USER;
3356 PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags,
3357 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3359 if (packageInfo == null) {
3363 rebaseEnabledOverlays(packageInfo.applicationInfo, userId);
3365 packageInfo.packageName = packageInfo.applicationInfo.packageName =
3366 resolveExternalPackageNameLPr(p);
3372 public void checkPackageStartable(String packageName, int userId) {
3373 final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3375 synchronized (mPackages) {
3376 final PackageSetting ps = mSettings.mPackages.get(packageName);
3378 throw new SecurityException("Package " + packageName + " was not found!");
3381 if (!ps.getInstalled(userId)) {
3382 throw new SecurityException(
3383 "Package " + packageName + " was not installed for user " + userId + "!");
3386 if (mSafeMode && !ps.isSystem()) {
3387 throw new SecurityException("Package " + packageName + " not a system app!");
3390 if (mFrozenPackages.contains(packageName)) {
3391 throw new SecurityException("Package " + packageName + " is currently frozen!");
3394 if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware()
3395 || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) {
3396 throw new SecurityException("Package " + packageName + " is not encryption aware!");
3402 public boolean isPackageAvailable(String packageName, int userId) {
3403 if (!sUserManager.exists(userId)) return false;
3404 enforceCrossUserPermission(Binder.getCallingUid(), userId,
3405 false /* requireFullPermission */, false /* checkShell */, "is package available");
3406 synchronized (mPackages) {
3407 PackageParser.Package p = mPackages.get(packageName);
3409 final PackageSetting ps = (PackageSetting) p.mExtras;
3411 final PackageUserState state = ps.readUserState(userId);
3412 if (state != null) {
3413 return PackageParser.isAvailable(state);
3422 public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3423 return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
3428 public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
3429 int flags, int userId) {
3430 return getPackageInfoInternal(versionedPackage.getPackageName(),
3431 // TODO: We will change version code to long, so in the new API it is long
3432 (int) versionedPackage.getVersionCode(), flags, userId);
3435 private PackageInfo getPackageInfoInternal(String packageName, int versionCode,
3436 int flags, int userId) {
3437 if (!sUserManager.exists(userId)) return null;
3438 flags = updateFlagsForPackage(flags, userId, packageName);
3439 enforceCrossUserPermission(Binder.getCallingUid(), userId,
3440 false /* requireFullPermission */, false /* checkShell */, "get package info");
3443 synchronized (mPackages) {
3444 // Normalize package name to handle renamed packages and static libs
3445 packageName = resolveInternalPackageNameLPr(packageName, versionCode);
3447 final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
3448 if (matchFactoryOnly) {
3449 final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
3451 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
3454 return generatePackageInfo(ps, flags, userId);
3458 PackageParser.Package p = mPackages.get(packageName);
3459 if (matchFactoryOnly && p != null && !isSystemApp(p)) {
3462 if (DEBUG_PACKAGE_INFO)
3463 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
3465 if (filterSharedLibPackageLPr((PackageSetting) p.mExtras,
3466 Binder.getCallingUid(), userId)) {
3469 return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
3471 if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
3472 final PackageSetting ps = mSettings.mPackages.get(packageName);
3473 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
3476 return generatePackageInfo(ps, flags, userId);
3483 private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId) {
3484 // System/shell/root get to see all static libs
3485 final int appId = UserHandle.getAppId(uid);
3486 if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
3487 || appId == Process.ROOT_UID) {
3491 // No package means no static lib as it is always on internal storage
3492 if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) {
3496 final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName,
3497 ps.pkg.staticSharedLibVersion);
3498 if (libEntry == null) {
3502 final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
3503 final String[] uidPackageNames = getPackagesForUid(resolvedUid);
3504 if (uidPackageNames == null) {
3508 for (String uidPackageName : uidPackageNames) {
3509 if (ps.name.equals(uidPackageName)) {
3512 PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
3513 if (uidPs != null) {
3514 final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
3515 libEntry.info.getName());
3519 if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getVersion()) {
3528 public String[] currentToCanonicalPackageNames(String[] names) {
3529 String[] out = new String[names.length];
3531 synchronized (mPackages) {
3532 for (int i=names.length-1; i>=0; i--) {
3533 PackageSetting ps = mSettings.mPackages.get(names[i]);
3534 out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
3541 public String[] canonicalToCurrentPackageNames(String[] names) {
3542 String[] out = new String[names.length];
3544 synchronized (mPackages) {
3545 for (int i=names.length-1; i>=0; i--) {
3546 String cur = mSettings.getRenamedPackageLPr(names[i]);
3547 out[i] = cur != null ? cur : names[i];
3554 public int getPackageUid(String packageName, int flags, int userId) {
3555 if (!sUserManager.exists(userId)) return -1;
3556 flags = updateFlagsForPackage(flags, userId, packageName);
3557 enforceCrossUserPermission(Binder.getCallingUid(), userId,
3558 false /* requireFullPermission */, false /* checkShell */, "get package uid");
3561 synchronized (mPackages) {
3562 final PackageParser.Package p = mPackages.get(packageName);
3563 if (p != null && p.isMatch(flags)) {
3564 return UserHandle.getUid(userId, p.applicationInfo.uid);
3566 if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
3567 final PackageSetting ps = mSettings.mPackages.get(packageName);
3568 if (ps != null && ps.isMatch(flags)) {
3569 return UserHandle.getUid(userId, ps.appId);
3578 public int[] getPackageGids(String packageName, int flags, int userId) {
3579 if (!sUserManager.exists(userId)) return null;
3580 flags = updateFlagsForPackage(flags, userId, packageName);
3581 enforceCrossUserPermission(Binder.getCallingUid(), userId,
3582 false /* requireFullPermission */, false /* checkShell */,
3586 synchronized (mPackages) {
3587 final PackageParser.Package p = mPackages.get(packageName);
3588 if (p != null && p.isMatch(flags)) {
3589 PackageSetting ps = (PackageSetting) p.mExtras;
3590 // TODO: Shouldn't this be checking for package installed state for userId and
3592 return ps.getPermissionsState().computeGids(userId);
3594 if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
3595 final PackageSetting ps = mSettings.mPackages.get(packageName);
3596 if (ps != null && ps.isMatch(flags)) {
3597 return ps.getPermissionsState().computeGids(userId);
3605 static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) {
3606 if (bp.perm != null) {
3607 return PackageParser.generatePermissionInfo(bp.perm, flags);
3609 PermissionInfo pi = new PermissionInfo();
3611 pi.packageName = bp.sourcePackage;
3612 pi.nonLocalizedLabel = bp.name;
3613 pi.protectionLevel = bp.protectionLevel;
3618 public PermissionInfo getPermissionInfo(String name, int flags) {
3620 synchronized (mPackages) {
3621 final BasePermission p = mSettings.mPermissions.get(name);
3623 return generatePermissionInfo(p, flags);
3630 public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group,
3633 synchronized (mPackages) {
3634 if (group != null && !mPermissionGroups.containsKey(group)) {
3635 // This is thrown as NameNotFoundException
3639 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
3640 for (BasePermission p : mSettings.mPermissions.values()) {
3641 if (group == null) {
3642 if (p.perm == null || p.perm.info.group == null) {
3643 out.add(generatePermissionInfo(p, flags));
3646 if (p.perm != null && group.equals(p.perm.info.group)) {
3647 out.add(PackageParser.generatePermissionInfo(p.perm, flags));
3651 return new ParceledListSlice<>(out);
3656 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
3658 synchronized (mPackages) {
3659 return PackageParser.generatePermissionGroupInfo(
3660 mPermissionGroups.get(name), flags);
3665 public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
3667 synchronized (mPackages) {
3668 final int N = mPermissionGroups.size();
3669 ArrayList<PermissionGroupInfo> out
3670 = new ArrayList<PermissionGroupInfo>(N);
3671 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
3672 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
3674 return new ParceledListSlice<>(out);
3678 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
3679 int uid, int userId) {
3680 if (!sUserManager.exists(userId)) return null;
3681 PackageSetting ps = mSettings.mPackages.get(packageName);
3683 if (filterSharedLibPackageLPr(ps, uid, userId)) {
3686 if (ps.pkg == null) {
3687 final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
3688 if (pInfo != null) {
3689 return pInfo.applicationInfo;
3693 ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
3694 ps.readUserState(userId), userId);
3696 rebaseEnabledOverlays(ai, userId);
3697 ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
3705 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
3706 if (!sUserManager.exists(userId)) return null;
3707 flags = updateFlagsForApplication(flags, userId, packageName);
3708 enforceCrossUserPermission(Binder.getCallingUid(), userId,
3709 false /* requireFullPermission */, false /* checkShell */, "get application info");
3712 synchronized (mPackages) {
3713 // Normalize package name to handle renamed packages and static libs
3714 packageName = resolveInternalPackageNameLPr(packageName,
3715 PackageManager.VERSION_CODE_HIGHEST);
3717 PackageParser.Package p = mPackages.get(packageName);
3718 if (DEBUG_PACKAGE_INFO) Log.v(
3719 TAG, "getApplicationInfo " + packageName
3722 PackageSetting ps = mSettings.mPackages.get(packageName);
3723 if (ps == null) return null;
3724 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
3727 // Note: isEnabledLP() does not apply here - always return info
3728 ApplicationInfo ai = PackageParser.generateApplicationInfo(
3729 p, flags, ps.readUserState(userId), userId);
3731 rebaseEnabledOverlays(ai, userId);
3732 ai.packageName = resolveExternalPackageNameLPr(p);
3736 if ("android".equals(packageName)||"system".equals(packageName)) {
3737 return mAndroidApplication;
3739 if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
3740 // Already generates the external package name
3741 return generateApplicationInfoFromSettingsLPw(packageName,
3742 Binder.getCallingUid(), flags, userId);
3748 private void rebaseEnabledOverlays(@NonNull ApplicationInfo ai, int userId) {
3749 List<String> paths = new ArrayList<>();
3750 ArrayMap<String, ArrayList<String>> userSpecificOverlays =
3751 mEnabledOverlayPaths.get(userId);
3752 if (userSpecificOverlays != null) {
3753 if (!"android".equals(ai.packageName)) {
3754 ArrayList<String> frameworkOverlays = userSpecificOverlays.get("android");
3755 if (frameworkOverlays != null) {
3756 paths.addAll(frameworkOverlays);
3760 ArrayList<String> appOverlays = userSpecificOverlays.get(ai.packageName);
3761 if (appOverlays != null) {
3762 paths.addAll(appOverlays);
3765 ai.resourceDirs = paths.size() > 0 ? paths.toArray(new String[paths.size()]) : null;
3768 private String normalizePackageNameLPr(String packageName) {
3769 String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
3770 return normalizedPackageName != null ? normalizedPackageName : packageName;
3774 public void deletePreloadsFileCache() {
3775 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
3776 throw new SecurityException("Only system or settings may call deletePreloadsFileCache");
3778 File dir = Environment.getDataPreloadsFileCacheDirectory();
3779 Slog.i(TAG, "Deleting preloaded file cache " + dir);
3780 FileUtils.deleteContents(dir);
3784 public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
3785 final IPackageDataObserver observer) {
3786 mContext.enforceCallingOrSelfPermission(
3787 android.Manifest.permission.CLEAR_APP_CACHE, null);
3788 mHandler.post(() -> {
3789 boolean success = false;
3791 freeStorage(volumeUuid, freeStorageSize, 0);
3793 } catch (IOException e) {
3796 if (observer != null) {
3798 observer.onRemoveCompleted(null, success);
3799 } catch (RemoteException e) {
3807 public void freeStorage(final String volumeUuid, final long freeStorageSize,
3808 final IntentSender pi) {
3809 mContext.enforceCallingOrSelfPermission(
3810 android.Manifest.permission.CLEAR_APP_CACHE, TAG);
3811 mHandler.post(() -> {
3812 boolean success = false;
3814 freeStorage(volumeUuid, freeStorageSize, 0);
3816 } catch (IOException e) {
3821 pi.sendIntent(null, success ? 1 : 0, null, null, null);
3822 } catch (SendIntentException e) {
3830 * Blocking call to clear various types of cached data across the system
3831 * until the requested bytes are available.
3833 public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
3834 final StorageManager storage = mContext.getSystemService(StorageManager.class);
3835 final File file = storage.findPathForUuid(volumeUuid);
3836 if (file.getUsableSpace() >= bytes) return;
3838 if (ENABLE_FREE_CACHE_V2) {
3839 final boolean aggressive = (storageFlags
3840 & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
3841 final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
3844 // 1. Pre-flight to determine if we have any chance to succeed
3845 // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
3846 if (internalVolume && (aggressive || SystemProperties
3847 .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
3848 deletePreloadsFileCache();
3849 if (file.getUsableSpace() >= bytes) return;
3852 // 3. Consider parsed APK data (aggressive only)
3853 if (internalVolume && aggressive) {
3854 FileUtils.deleteContents(mCacheDir);
3855 if (file.getUsableSpace() >= bytes) return;
3858 // 4. Consider cached app data (above quotas)
3860 mInstaller.freeCache(volumeUuid, bytes, Installer.FLAG_FREE_CACHE_V2);
3861 } catch (InstallerException ignored) {
3863 if (file.getUsableSpace() >= bytes) return;
3865 // 5. Consider shared libraries with refcount=0 and age>2h
3866 // 6. Consider dexopt output (aggressive only)
3867 // 7. Consider ephemeral apps not used in last week
3869 // 8. Consider cached app data (below quotas)
3871 mInstaller.freeCache(volumeUuid, bytes, Installer.FLAG_FREE_CACHE_V2
3872 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
3873 } catch (InstallerException ignored) {
3875 if (file.getUsableSpace() >= bytes) return;
3877 // 9. Consider DropBox entries
3878 // 10. Consider ephemeral cookies
3882 mInstaller.freeCache(volumeUuid, bytes, 0);
3883 } catch (InstallerException ignored) {
3885 if (file.getUsableSpace() >= bytes) return;
3888 throw new IOException("Failed to free " + bytes + " on storage device at " + file);
3892 * Update given flags based on encryption status of current user.
3894 private int updateFlags(int flags, int userId) {
3895 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
3896 | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
3897 // Caller expressed an explicit opinion about what encryption
3898 // aware/unaware components they want to see, so fall through and
3899 // give them what they want
3901 // Caller expressed no opinion, so match based on user state
3902 if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
3903 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3905 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
3911 private UserManagerInternal getUserManagerInternal() {
3912 if (mUserManagerInternal == null) {
3913 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
3915 return mUserManagerInternal;
3918 private DeviceIdleController.LocalService getDeviceIdleController() {
3919 if (mDeviceIdleController == null) {
3920 mDeviceIdleController =
3921 LocalServices.getService(DeviceIdleController.LocalService.class);
3923 return mDeviceIdleController;
3927 * Update given flags when being used to request {@link PackageInfo}.
3929 private int updateFlagsForPackage(int flags, int userId, Object cookie) {
3930 final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
3931 boolean triaged = true;
3932 if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
3933 | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
3934 // Caller is asking for component details, so they'd better be
3935 // asking for specific encryption matching behavior, or be triaged
3936 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
3937 | PackageManager.MATCH_DIRECT_BOOT_AWARE
3938 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3942 if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
3943 | PackageManager.MATCH_SYSTEM_ONLY
3944 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3947 if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
3948 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
3949 "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
3950 + Debug.getCallers(5));
3951 } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
3952 && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
3953 // If the caller wants all packages and has a restricted profile associated with it,
3954 // then match all users. This is to make sure that launchers that need to access work
3955 // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
3956 // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
3957 flags |= PackageManager.MATCH_ANY_USER;
3959 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
3960 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
3961 + " with flags 0x" + Integer.toHexString(flags), new Throwable());
3963 return updateFlags(flags, userId);
3967 * Update given flags when being used to request {@link ApplicationInfo}.
3969 private int updateFlagsForApplication(int flags, int userId, Object cookie) {
3970 return updateFlagsForPackage(flags, userId, cookie);
3974 * Update given flags when being used to request {@link ComponentInfo}.
3976 private int updateFlagsForComponent(int flags, int userId, Object cookie) {
3977 if (cookie instanceof Intent) {
3978 if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
3979 flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
3983 boolean triaged = true;
3984 // Caller is asking for component details, so they'd better be
3985 // asking for specific encryption matching behavior, or be triaged
3986 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
3987 | PackageManager.MATCH_DIRECT_BOOT_AWARE
3988 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3991 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
3992 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
3993 + " with flags 0x" + Integer.toHexString(flags), new Throwable());
3996 return updateFlags(flags, userId);
4000 * Update given intent when being used to request {@link ResolveInfo}.
4002 private Intent updateIntentForResolve(Intent intent) {
4003 if (intent.getSelector() != null) {
4004 intent = intent.getSelector();
4006 if (DEBUG_PREFERRED) {
4007 intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4013 * Update given flags when being used to request {@link ResolveInfo}.
4014 * <p>Instant apps are resolved specially, depending upon context. Minimally,
4015 * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
4016 * flag set. However, this flag is only honoured in three circumstances:
4018 * <li>when called from a system process</li>
4019 * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
4020 * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
4021 * action and a {@code android.intent.category.BROWSABLE} category</li>
4024 int updateFlagsForResolve(int flags, int userId, Intent intent, boolean includeInstantApp) {
4025 // Safe mode means we shouldn't match any third-party components
4027 flags |= PackageManager.MATCH_SYSTEM_ONLY;
4029 final int callingUid = Binder.getCallingUid();
4030 if (getInstantAppPackageName(callingUid) != null) {
4031 // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
4032 flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4033 flags |= PackageManager.MATCH_INSTANT;
4035 // Otherwise, prevent leaking ephemeral components
4036 final boolean isSpecialProcess =
4037 callingUid == Process.SYSTEM_UID
4038 || callingUid == Process.SHELL_UID
4040 final boolean allowMatchInstant =
4042 && Intent.ACTION_VIEW.equals(intent.getAction())
4043 && intent.hasCategory(Intent.CATEGORY_BROWSABLE)
4044 && hasWebURI(intent))
4046 || mContext.checkCallingOrSelfPermission(
4047 android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED;
4048 flags &= ~PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4049 if (!allowMatchInstant) {
4050 flags &= ~PackageManager.MATCH_INSTANT;
4053 return updateFlagsForComponent(flags, userId, intent /*cookie*/);
4057 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
4058 if (!sUserManager.exists(userId)) return null;
4059 flags = updateFlagsForComponent(flags, userId, component);
4060 enforceCrossUserPermission(Binder.getCallingUid(), userId,
4061 false /* requireFullPermission */, false /* checkShell */, "get activity info");
4062 synchronized (mPackages) {
4063 PackageParser.Activity a = mActivities.mActivities.get(component);
4065 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
4066 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4067 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4068 if (ps == null) return null;
4069 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
4072 if (mResolveComponentName.equals(component)) {
4073 return PackageParser.generateActivityInfo(mResolveActivity, flags,
4074 new PackageUserState(), userId);
4081 public boolean activitySupportsIntent(ComponentName component, Intent intent,
4082 String resolvedType) {
4083 synchronized (mPackages) {
4084 if (component.equals(mResolveComponentName)) {
4085 // The resolver supports EVERYTHING!
4088 PackageParser.Activity a = mActivities.mActivities.get(component);
4092 for (int i=0; i<a.intents.size(); i++) {
4093 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
4094 intent.getData(), intent.getCategories(), TAG) >= 0) {
4103 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
4104 if (!sUserManager.exists(userId)) return null;
4105 flags = updateFlagsForComponent(flags, userId, component);
4106 enforceCrossUserPermission(Binder.getCallingUid(), userId,
4107 false /* requireFullPermission */, false /* checkShell */, "get receiver info");
4108 synchronized (mPackages) {
4109 PackageParser.Activity a = mReceivers.mActivities.get(component);
4110 if (DEBUG_PACKAGE_INFO) Log.v(
4111 TAG, "getReceiverInfo " + component + ": " + a);
4112 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4113 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4114 if (ps == null) return null;
4115 ActivityInfo ri = PackageParser.generateActivityInfo(a, flags,
4116 ps.readUserState(userId), userId);
4118 rebaseEnabledOverlays(ri.applicationInfo, userId);
4127 public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(int flags, int userId) {
4128 if (!sUserManager.exists(userId)) return null;
4129 Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
4131 flags = updateFlagsForPackage(flags, userId, null);
4133 final boolean canSeeStaticLibraries =
4134 mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
4135 == PERMISSION_GRANTED
4136 || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
4137 == PERMISSION_GRANTED
4138 || mContext.checkCallingOrSelfPermission(REQUEST_INSTALL_PACKAGES)
4139 == PERMISSION_GRANTED
4140 || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
4141 == PERMISSION_GRANTED;
4143 synchronized (mPackages) {
4144 List<SharedLibraryInfo> result = null;
4146 final int libCount = mSharedLibraries.size();
4147 for (int i = 0; i < libCount; i++) {
4148 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4149 if (versionedLib == null) {
4153 final int versionCount = versionedLib.size();
4154 for (int j = 0; j < versionCount; j++) {
4155 SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4156 if (!canSeeStaticLibraries && libInfo.isStatic()) {
4159 final long identity = Binder.clearCallingIdentity();
4161 // TODO: We will change version code to long, so in the new API it is long
4162 PackageInfo packageInfo = getPackageInfoVersioned(
4163 libInfo.getDeclaringPackage(), flags, userId);
4164 if (packageInfo == null) {
4168 Binder.restoreCallingIdentity(identity);
4171 SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(),
4172 libInfo.getVersion(), libInfo.getType(), libInfo.getDeclaringPackage(),
4173 getPackagesUsingSharedLibraryLPr(libInfo, flags, userId));
4175 if (result == null) {
4176 result = new ArrayList<>();
4178 result.add(resLibInfo);
4182 return result != null ? new ParceledListSlice<>(result) : null;
4186 private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
4187 SharedLibraryInfo libInfo, int flags, int userId) {
4188 List<VersionedPackage> versionedPackages = null;
4189 final int packageCount = mSettings.mPackages.size();
4190 for (int i = 0; i < packageCount; i++) {
4191 PackageSetting ps = mSettings.mPackages.valueAt(i);
4197 if (!ps.getUserState().get(userId).isAvailable(flags)) {
4201 final String libName = libInfo.getName();
4202 if (libInfo.isStatic()) {
4203 final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
4207 if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getVersion()) {
4210 if (versionedPackages == null) {
4211 versionedPackages = new ArrayList<>();
4213 // If the dependent is a static shared lib, use the public package name
4214 String dependentPackageName = ps.name;
4215 if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4216 dependentPackageName = ps.pkg.manifestPackageName;
4218 versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
4219 } else if (ps.pkg != null) {
4220 if (ArrayUtils.contains(ps.pkg.usesLibraries, libName)
4221 || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) {
4222 if (versionedPackages == null) {
4223 versionedPackages = new ArrayList<>();
4225 versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
4230 return versionedPackages;
4234 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
4235 if (!sUserManager.exists(userId)) return null;
4236 flags = updateFlagsForComponent(flags, userId, component);
4237 enforceCrossUserPermission(Binder.getCallingUid(), userId,
4238 false /* requireFullPermission */, false /* checkShell */, "get service info");
4239 synchronized (mPackages) {
4240 PackageParser.Service s = mServices.mServices.get(component);
4241 if (DEBUG_PACKAGE_INFO) Log.v(
4242 TAG, "getServiceInfo " + component + ": " + s);
4243 if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
4244 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4245 if (ps == null) return null;
4246 ServiceInfo si = PackageParser.generateServiceInfo(s, flags,
4247 ps.readUserState(userId), userId);
4249 rebaseEnabledOverlays(si.applicationInfo, userId);
4258 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
4259 if (!sUserManager.exists(userId)) return null;
4260 flags = updateFlagsForComponent(flags, userId, component);
4261 enforceCrossUserPermission(Binder.getCallingUid(), userId,
4262 false /* requireFullPermission */, false /* checkShell */, "get provider info");
4263 synchronized (mPackages) {
4264 PackageParser.Provider p = mProviders.mProviders.get(component);
4265 if (DEBUG_PACKAGE_INFO) Log.v(
4266 TAG, "getProviderInfo " + component + ": " + p);
4267 if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
4268 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4269 if (ps == null) return null;
4270 ProviderInfo pi = PackageParser.generateProviderInfo(p, flags,
4271 ps.readUserState(userId), userId);
4273 rebaseEnabledOverlays(pi.applicationInfo, userId);
4282 public String[] getSystemSharedLibraryNames() {
4283 synchronized (mPackages) {
4284 Set<String> libs = null;
4285 final int libCount = mSharedLibraries.size();
4286 for (int i = 0; i < libCount; i++) {
4287 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4288 if (versionedLib == null) {
4291 final int versionCount = versionedLib.size();
4292 for (int j = 0; j < versionCount; j++) {
4293 SharedLibraryEntry libEntry = versionedLib.valueAt(j);
4294 if (!libEntry.info.isStatic()) {
4296 libs = new ArraySet<>();
4298 libs.add(libEntry.info.getName());
4301 PackageSetting ps = mSettings.getPackageLPr(libEntry.apk);
4302 if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
4303 UserHandle.getUserId(Binder.getCallingUid()))) {
4305 libs = new ArraySet<>();
4307 libs.add(libEntry.info.getName());
4314 String[] libsArray = new String[libs.size()];
4315 libs.toArray(libsArray);
4324 public @NonNull String getServicesSystemSharedLibraryPackageName() {
4325 synchronized (mPackages) {
4326 return mServicesSystemSharedLibraryPackageName;
4331 public @NonNull String getSharedSystemSharedLibraryPackageName() {
4332 synchronized (mPackages) {
4333 return mSharedSystemSharedLibraryPackageName;
4337 private void updateSequenceNumberLP(String packageName, int[] userList) {
4338 for (int i = userList.length - 1; i >= 0; --i) {
4339 final int userId = userList[i];
4340 SparseArray<String> changedPackages = mChangedPackages.get(userId);
4341 if (changedPackages == null) {
4342 changedPackages = new SparseArray<>();
4343 mChangedPackages.put(userId, changedPackages);
4345 Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
4346 if (sequenceNumbers == null) {
4347 sequenceNumbers = new HashMap<>();
4348 mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
4350 final Integer sequenceNumber = sequenceNumbers.get(packageName);
4351 if (sequenceNumber != null) {
4352 changedPackages.remove(sequenceNumber);
4354 changedPackages.put(mChangedPackagesSequenceNumber, packageName);
4355 sequenceNumbers.put(packageName, mChangedPackagesSequenceNumber);
4357 mChangedPackagesSequenceNumber++;
4361 public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
4362 synchronized (mPackages) {
4363 if (sequenceNumber >= mChangedPackagesSequenceNumber) {
4366 final SparseArray<String> changedPackages = mChangedPackages.get(userId);
4367 if (changedPackages == null) {
4370 final List<String> packageNames =
4371 new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
4372 for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
4373 final String packageName = changedPackages.get(i);
4374 if (packageName != null) {
4375 packageNames.add(packageName);
4378 return packageNames.isEmpty()
4379 ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
4384 public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
4385 ArrayList<FeatureInfo> res;
4386 synchronized (mAvailableFeatures) {
4387 res = new ArrayList<>(mAvailableFeatures.size() + 1);
4388 res.addAll(mAvailableFeatures.values());
4390 final FeatureInfo fi = new FeatureInfo();
4391 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
4392 FeatureInfo.GL_ES_VERSION_UNDEFINED);
4395 return new ParceledListSlice<>(res);
4399 public boolean hasSystemFeature(String name, int version) {
4400 synchronized (mAvailableFeatures) {
4401 final FeatureInfo feat = mAvailableFeatures.get(name);
4405 return feat.version >= version;
4411 public int checkPermission(String permName, String pkgName, int userId) {
4412 if (!sUserManager.exists(userId)) {
4413 return PackageManager.PERMISSION_DENIED;
4416 synchronized (mPackages) {
4417 final PackageParser.Package p = mPackages.get(pkgName);
4418 if (p != null && p.mExtras != null) {
4419 final PackageSetting ps = (PackageSetting) p.mExtras;
4420 final PermissionsState permissionsState = ps.getPermissionsState();
4421 if (permissionsState.hasPermission(permName, userId)) {
4422 return PackageManager.PERMISSION_GRANTED;
4424 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
4425 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
4426 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
4427 return PackageManager.PERMISSION_GRANTED;
4432 return PackageManager.PERMISSION_DENIED;
4436 public int checkUidPermission(String permName, int uid) {
4437 final int userId = UserHandle.getUserId(uid);
4439 if (!sUserManager.exists(userId)) {
4440 return PackageManager.PERMISSION_DENIED;
4443 synchronized (mPackages) {
4444 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4446 final SettingBase ps = (SettingBase) obj;
4447 final PermissionsState permissionsState = ps.getPermissionsState();
4448 if (permissionsState.hasPermission(permName, userId)) {
4449 return PackageManager.PERMISSION_GRANTED;
4451 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
4452 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
4453 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
4454 return PackageManager.PERMISSION_GRANTED;
4457 ArraySet<String> perms = mSystemPermissions.get(uid);
4458 if (perms != null) {
4459 if (perms.contains(permName)) {
4460 return PackageManager.PERMISSION_GRANTED;
4462 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
4463 .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
4464 return PackageManager.PERMISSION_GRANTED;
4470 return PackageManager.PERMISSION_DENIED;
4474 public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
4475 if (UserHandle.getCallingUserId() != userId) {
4476 mContext.enforceCallingPermission(
4477 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
4478 "isPermissionRevokedByPolicy for user " + userId);
4481 if (checkPermission(permission, packageName, userId)
4482 == PackageManager.PERMISSION_GRANTED) {
4486 final long identity = Binder.clearCallingIdentity();
4488 final int flags = getPermissionFlags(permission, packageName, userId);
4489 return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
4491 Binder.restoreCallingIdentity(identity);
4496 public String getPermissionControllerPackageName() {
4497 synchronized (mPackages) {
4498 return mRequiredInstallerPackage;
4503 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
4504 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
4505 * @param checkShell whether to prevent shell from access if there's a debugging restriction
4506 * @param message the message to log on security exception
4508 void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
4509 boolean checkShell, String message) {
4511 throw new IllegalArgumentException("Invalid userId " + userId);
4514 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
4516 if (userId == UserHandle.getUserId(callingUid)) return;
4517 if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
4518 if (requireFullPermission) {
4519 mContext.enforceCallingOrSelfPermission(
4520 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
4523 mContext.enforceCallingOrSelfPermission(
4524 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
4525 } catch (SecurityException se) {
4526 mContext.enforceCallingOrSelfPermission(
4527 android.Manifest.permission.INTERACT_ACROSS_USERS, message);
4533 void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
4534 if (callingUid == Process.SHELL_UID) {
4536 && sUserManager.hasUserRestriction(restriction, userHandle)) {
4537 throw new SecurityException("Shell does not have permission to access user "
4539 } else if (userHandle < 0) {
4540 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
4541 + Debug.getCallers(3));
4546 private BasePermission findPermissionTreeLP(String permName) {
4547 for(BasePermission bp : mSettings.mPermissionTrees.values()) {
4548 if (permName.startsWith(bp.name) &&
4549 permName.length() > bp.name.length() &&
4550 permName.charAt(bp.name.length()) == '.') {
4557 private BasePermission checkPermissionTreeLP(String permName) {
4558 if (permName != null) {
4559 BasePermission bp = findPermissionTreeLP(permName);
4561 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
4564 throw new SecurityException("Calling uid "
4565 + Binder.getCallingUid()
4566 + " is not allowed to add to permission tree "
4567 + bp.name + " owned by uid " + bp.uid);
4570 throw new SecurityException("No permission tree found for " + permName);
4573 static boolean compareStrings(CharSequence s1, CharSequence s2) {
4580 if (s1.getClass() != s2.getClass()) {
4583 return s1.equals(s2);
4586 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
4587 if (pi1.icon != pi2.icon) return false;
4588 if (pi1.logo != pi2.logo) return false;
4589 if (pi1.protectionLevel != pi2.protectionLevel) return false;
4590 if (!compareStrings(pi1.name, pi2.name)) return false;
4591 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
4592 // We'll take care of setting this one.
4593 if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
4594 // These are not currently stored in settings.
4595 //if (!compareStrings(pi1.group, pi2.group)) return false;
4596 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
4597 //if (pi1.labelRes != pi2.labelRes) return false;
4598 //if (pi1.descriptionRes != pi2.descriptionRes) return false;
4602 int permissionInfoFootprint(PermissionInfo info) {
4603 int size = info.name.length();
4604 if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
4605 if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
4609 int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
4611 for (BasePermission perm : mSettings.mPermissions.values()) {
4612 if (perm.uid == tree.uid) {
4613 size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
4619 void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
4620 // We calculate the max size of permissions defined by this uid and throw
4621 // if that plus the size of 'info' would exceed our stated maximum.
4622 if (tree.uid != Process.SYSTEM_UID) {
4623 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
4624 if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
4625 throw new SecurityException("Permission tree size cap exceeded");
4630 boolean addPermissionLocked(PermissionInfo info, boolean async) {
4631 if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
4632 throw new SecurityException("Label must be specified in permission");
4634 BasePermission tree = checkPermissionTreeLP(info.name);
4635 BasePermission bp = mSettings.mPermissions.get(info.name);
4636 boolean added = bp == null;
4637 boolean changed = true;
4638 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
4640 enforcePermissionCapLocked(info, tree);
4641 bp = new BasePermission(info.name, tree.sourcePackage,
4642 BasePermission.TYPE_DYNAMIC);
4643 } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
4644 throw new SecurityException(
4645 "Not allowed to modify non-dynamic permission "
4648 if (bp.protectionLevel == fixedLevel
4649 && bp.perm.owner.equals(tree.perm.owner)
4650 && bp.uid == tree.uid
4651 && comparePermissionInfos(bp.perm.info, info)) {
4655 bp.protectionLevel = fixedLevel;
4656 info = new PermissionInfo(info);
4657 info.protectionLevel = fixedLevel;
4658 bp.perm = new PackageParser.Permission(tree.perm.owner, info);
4659 bp.perm.info.packageName = tree.perm.info.packageName;
4662 mSettings.mPermissions.put(info.name, bp);
4666 mSettings.writeLPr();
4668 scheduleWriteSettingsLocked();
4675 public boolean addPermission(PermissionInfo info) {
4676 synchronized (mPackages) {
4677 return addPermissionLocked(info, false);
4682 public boolean addPermissionAsync(PermissionInfo info) {
4683 synchronized (mPackages) {
4684 return addPermissionLocked(info, true);
4689 public void removePermission(String name) {
4690 synchronized (mPackages) {
4691 checkPermissionTreeLP(name);
4692 BasePermission bp = mSettings.mPermissions.get(name);
4694 if (bp.type != BasePermission.TYPE_DYNAMIC) {
4695 throw new SecurityException(
4696 "Not allowed to modify non-dynamic permission "
4699 mSettings.mPermissions.remove(name);
4700 mSettings.writeLPr();
4705 private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg,
4706 BasePermission bp) {
4707 int index = pkg.requestedPermissions.indexOf(bp.name);
4709 throw new SecurityException("Package " + pkg.packageName
4710 + " has not requested permission " + bp.name);
4712 if (!bp.isRuntime() && !bp.isDevelopment()) {
4713 throw new SecurityException("Permission " + bp.name
4714 + " is not a changeable permission type");
4719 public void grantRuntimePermission(String packageName, String name, final int userId) {
4720 grantRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
4723 private void grantRuntimePermission(String packageName, String name, final int userId,
4724 boolean overridePolicy) {
4725 if (!sUserManager.exists(userId)) {
4726 Log.e(TAG, "No such user:" + userId);
4730 mContext.enforceCallingOrSelfPermission(
4731 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
4732 "grantRuntimePermission");
4734 enforceCrossUserPermission(Binder.getCallingUid(), userId,
4735 true /* requireFullPermission */, true /* checkShell */,
4736 "grantRuntimePermission");
4739 final SettingBase sb;
4741 synchronized (mPackages) {
4742 final PackageParser.Package pkg = mPackages.get(packageName);
4744 throw new IllegalArgumentException("Unknown package: " + packageName);
4747 final BasePermission bp = mSettings.mPermissions.get(name);
4749 throw new IllegalArgumentException("Unknown permission: " + name);
4752 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
4754 // If a permission review is required for legacy apps we represent
4755 // their permissions as always granted runtime ones since we need
4756 // to keep the review required permission flag per user while an
4757 // install permission's state is shared across all users.
4758 if (mPermissionReviewRequired
4759 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
4760 && bp.isRuntime()) {
4764 uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
4765 sb = (SettingBase) pkg.mExtras;
4767 throw new IllegalArgumentException("Unknown package: " + packageName);
4770 final PermissionsState permissionsState = sb.getPermissionsState();
4772 final int flags = permissionsState.getPermissionFlags(name, userId);
4773 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
4774 throw new SecurityException("Cannot grant system fixed permission "
4775 + name + " for package " + packageName);
4777 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
4778 throw new SecurityException("Cannot grant policy fixed permission "
4779 + name + " for package " + packageName);
4782 if (bp.isDevelopment()) {
4783 // Development permissions must be handled specially, since they are not
4784 // normal runtime permissions. For now they apply to all users.
4785 if (permissionsState.grantInstallPermission(bp) !=
4786 PermissionsState.PERMISSION_OPERATION_FAILURE) {
4787 scheduleWriteSettingsLocked();
4792 final PackageSetting ps = mSettings.mPackages.get(packageName);
4793 if (ps.getInstantApp(userId) && !bp.isInstant()) {
4794 throw new SecurityException("Cannot grant non-ephemeral permission"
4795 + name + " for package " + packageName);
4798 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
4799 Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
4803 final int result = permissionsState.grantRuntimePermission(bp, userId);
4805 case PermissionsState.PERMISSION_OPERATION_FAILURE: {
4809 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
4810 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
4811 mHandler.post(new Runnable() {
4814 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
4821 if (bp.isRuntime()) {
4822 logPermissionGranted(mContext, name, packageName);
4825 mOnPermissionChangeListeners.onPermissionsChanged(uid);
4827 // Not critical if that is lost - app has to request again.
4828 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
4831 // Only need to do this if user is initialized. Otherwise it's a new user
4832 // and there are no processes running as the user yet and there's no need
4833 // to make an expensive call to remount processes for the changed permissions.
4834 if (READ_EXTERNAL_STORAGE.equals(name)
4835 || WRITE_EXTERNAL_STORAGE.equals(name)) {
4836 final long token = Binder.clearCallingIdentity();
4838 if (sUserManager.isInitialized(userId)) {
4839 StorageManagerInternal storageManagerInternal = LocalServices.getService(
4840 StorageManagerInternal.class);
4841 storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
4844 Binder.restoreCallingIdentity(token);
4850 public void revokeRuntimePermission(String packageName, String name, int userId) {
4851 revokeRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
4854 private void revokeRuntimePermission(String packageName, String name, int userId,
4855 boolean overridePolicy) {
4856 if (!sUserManager.exists(userId)) {
4857 Log.e(TAG, "No such user:" + userId);
4861 mContext.enforceCallingOrSelfPermission(
4862 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
4863 "revokeRuntimePermission");
4865 enforceCrossUserPermission(Binder.getCallingUid(), userId,
4866 true /* requireFullPermission */, true /* checkShell */,
4867 "revokeRuntimePermission");
4871 synchronized (mPackages) {
4872 final PackageParser.Package pkg = mPackages.get(packageName);
4874 throw new IllegalArgumentException("Unknown package: " + packageName);
4877 final BasePermission bp = mSettings.mPermissions.get(name);
4879 throw new IllegalArgumentException("Unknown permission: " + name);
4882 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
4884 // If a permission review is required for legacy apps we represent
4885 // their permissions as always granted runtime ones since we need
4886 // to keep the review required permission flag per user while an
4887 // install permission's state is shared across all users.
4888 if (mPermissionReviewRequired
4889 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
4890 && bp.isRuntime()) {
4894 SettingBase sb = (SettingBase) pkg.mExtras;
4896 throw new IllegalArgumentException("Unknown package: " + packageName);
4899 final PermissionsState permissionsState = sb.getPermissionsState();
4901 final int flags = permissionsState.getPermissionFlags(name, userId);
4902 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
4903 throw new SecurityException("Cannot revoke system fixed permission "
4904 + name + " for package " + packageName);
4906 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
4907 throw new SecurityException("Cannot revoke policy fixed permission "
4908 + name + " for package " + packageName);
4911 if (bp.isDevelopment()) {
4912 // Development permissions must be handled specially, since they are not
4913 // normal runtime permissions. For now they apply to all users.
4914 if (permissionsState.revokeInstallPermission(bp) !=
4915 PermissionsState.PERMISSION_OPERATION_FAILURE) {
4916 scheduleWriteSettingsLocked();
4921 if (permissionsState.revokeRuntimePermission(bp, userId) ==
4922 PermissionsState.PERMISSION_OPERATION_FAILURE) {
4926 if (bp.isRuntime()) {
4927 logPermissionRevoked(mContext, name, packageName);
4930 mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
4932 // Critical, after this call app should never have the permission.
4933 mSettings.writeRuntimePermissionsForUserLPr(userId, true);
4935 appId = UserHandle.getAppId(pkg.applicationInfo.uid);
4938 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
4942 * Get the first event id for the permission.
4944 * <p>There are four events for each permission: <ul>
4945 * <li>Request permission: first id + 0</li>
4946 * <li>Grant permission: first id + 1</li>
4947 * <li>Request for permission denied: first id + 2</li>
4948 * <li>Revoke permission: first id + 3</li>
4951 * @param name name of the permission
4953 * @return The first event id for the permission
4955 private static int getBaseEventId(@NonNull String name) {
4956 int eventIdIndex = ALL_DANGEROUS_PERMISSIONS.indexOf(name);
4958 if (eventIdIndex == -1) {
4959 if (AppOpsManager.permissionToOpCode(name) == AppOpsManager.OP_NONE
4960 || "user".equals(Build.TYPE)) {
4961 Log.i(TAG, "Unknown permission " + name);
4963 return MetricsEvent.ACTION_PERMISSION_REQUEST_UNKNOWN;
4965 // Most likely #ALL_DANGEROUS_PERMISSIONS needs to be updated.
4968 // - EventLogger#ALL_DANGEROUS_PERMISSIONS
4969 // - metrics_constants.proto
4970 throw new IllegalStateException("Unknown permission " + name);
4974 return MetricsEvent.ACTION_PERMISSION_REQUEST_READ_CALENDAR + eventIdIndex * 4;
4978 * Log that a permission was revoked.
4980 * @param context Context of the caller
4981 * @param name name of the permission
4982 * @param packageName package permission if for
4984 private static void logPermissionRevoked(@NonNull Context context, @NonNull String name,
4985 @NonNull String packageName) {
4986 MetricsLogger.action(context, getBaseEventId(name) + 3, packageName);
4990 * Log that a permission request was granted.
4992 * @param context Context of the caller
4993 * @param name name of the permission
4994 * @param packageName package permission if for
4996 private static void logPermissionGranted(@NonNull Context context, @NonNull String name,
4997 @NonNull String packageName) {
4998 MetricsLogger.action(context, getBaseEventId(name) + 1, packageName);
5002 public void resetRuntimePermissions() {
5003 mContext.enforceCallingOrSelfPermission(
5004 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5005 "revokeRuntimePermission");
5007 int callingUid = Binder.getCallingUid();
5008 if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5009 mContext.enforceCallingOrSelfPermission(
5010 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5011 "resetRuntimePermissions");
5014 synchronized (mPackages) {
5015 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
5016 for (int userId : UserManagerService.getInstance().getUserIds()) {
5017 final int packageCount = mPackages.size();
5018 for (int i = 0; i < packageCount; i++) {
5019 PackageParser.Package pkg = mPackages.valueAt(i);
5020 if (!(pkg.mExtras instanceof PackageSetting)) {
5023 PackageSetting ps = (PackageSetting) pkg.mExtras;
5024 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
5031 public int getPermissionFlags(String name, String packageName, int userId) {
5032 if (!sUserManager.exists(userId)) {
5036 enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
5038 enforceCrossUserPermission(Binder.getCallingUid(), userId,
5039 true /* requireFullPermission */, false /* checkShell */,
5040 "getPermissionFlags");
5042 synchronized (mPackages) {
5043 final PackageParser.Package pkg = mPackages.get(packageName);
5048 final BasePermission bp = mSettings.mPermissions.get(name);
5053 SettingBase sb = (SettingBase) pkg.mExtras;
5058 PermissionsState permissionsState = sb.getPermissionsState();
5059 return permissionsState.getPermissionFlags(name, userId);
5064 public void updatePermissionFlags(String name, String packageName, int flagMask,
5065 int flagValues, int userId) {
5066 if (!sUserManager.exists(userId)) {
5070 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
5072 enforceCrossUserPermission(Binder.getCallingUid(), userId,
5073 true /* requireFullPermission */, true /* checkShell */,
5074 "updatePermissionFlags");
5076 // Only the system can change these flags and nothing else.
5077 if (getCallingUid() != Process.SYSTEM_UID) {
5078 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5079 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5080 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
5081 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
5082 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
5085 synchronized (mPackages) {
5086 final PackageParser.Package pkg = mPackages.get(packageName);
5088 throw new IllegalArgumentException("Unknown package: " + packageName);
5091 final BasePermission bp = mSettings.mPermissions.get(name);
5093 throw new IllegalArgumentException("Unknown permission: " + name);
5096 SettingBase sb = (SettingBase) pkg.mExtras;
5098 throw new IllegalArgumentException("Unknown package: " + packageName);
5101 PermissionsState permissionsState = sb.getPermissionsState();
5103 boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
5105 if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
5106 // Install and runtime permissions are stored in different places,
5107 // so figure out what permission changed and persist the change.
5108 if (permissionsState.getInstallPermissionState(name) != null) {
5109 scheduleWriteSettingsLocked();
5110 } else if (permissionsState.getRuntimePermissionState(name, userId) != null
5112 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5119 * Update the permission flags for all packages and runtime permissions of a user in order
5120 * to allow device or profile owner to remove POLICY_FIXED.
5123 public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
5124 if (!sUserManager.exists(userId)) {
5128 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps");
5130 enforceCrossUserPermission(Binder.getCallingUid(), userId,
5131 true /* requireFullPermission */, true /* checkShell */,
5132 "updatePermissionFlagsForAllApps");
5134 // Only the system can change system fixed flags.
5135 if (getCallingUid() != Process.SYSTEM_UID) {
5136 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5137 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5140 synchronized (mPackages) {
5141 boolean changed = false;
5142 final int packageCount = mPackages.size();
5143 for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
5144 final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
5145 SettingBase sb = (SettingBase) pkg.mExtras;
5149 PermissionsState permissionsState = sb.getPermissionsState();
5150 changed |= permissionsState.updatePermissionFlagsForAllPermissions(
5151 userId, flagMask, flagValues);
5154 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5159 private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
5160 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
5161 != PackageManager.PERMISSION_GRANTED
5162 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
5163 != PackageManager.PERMISSION_GRANTED) {
5164 throw new SecurityException(message + " requires "
5165 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
5166 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
5171 public boolean shouldShowRequestPermissionRationale(String permissionName,
5172 String packageName, int userId) {
5173 if (UserHandle.getCallingUserId() != userId) {
5174 mContext.enforceCallingPermission(
5175 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5176 "canShowRequestPermissionRationale for user " + userId);
5179 final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
5180 if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
5184 if (checkPermission(permissionName, packageName, userId)
5185 == PackageManager.PERMISSION_GRANTED) {
5191 final long identity = Binder.clearCallingIdentity();
5193 flags = getPermissionFlags(permissionName,
5194 packageName, userId);
5196 Binder.restoreCallingIdentity(identity);
5199 final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
5200 | PackageManager.FLAG_PERMISSION_POLICY_FIXED
5201 | PackageManager.FLAG_PERMISSION_USER_FIXED;
5203 if ((flags & fixedFlags) != 0) {
5207 return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
5211 public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5212 mContext.enforceCallingOrSelfPermission(
5213 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
5214 "addOnPermissionsChangeListener");
5216 synchronized (mPackages) {
5217 mOnPermissionChangeListeners.addListenerLocked(listener);
5222 public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5223 synchronized (mPackages) {
5224 mOnPermissionChangeListeners.removeListenerLocked(listener);
5229 public boolean isProtectedBroadcast(String actionName) {
5230 synchronized (mPackages) {
5231 if (mProtectedBroadcasts.contains(actionName)) {
5233 } else if (actionName != null) {
5234 // TODO: remove these terrible hacks
5235 if (actionName.startsWith("android.net.netmon.lingerExpired")
5236 || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
5237 || actionName.startsWith("com.android.internal.telephony.data-reconnect")
5238 || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
5247 public int checkSignatures(String pkg1, String pkg2) {
5248 synchronized (mPackages) {
5249 final PackageParser.Package p1 = mPackages.get(pkg1);
5250 final PackageParser.Package p2 = mPackages.get(pkg2);
5251 if (p1 == null || p1.mExtras == null
5252 || p2 == null || p2.mExtras == null) {
5253 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5255 return compareSignatures(p1.mSignatures, p2.mSignatures);
5260 public int checkUidSignatures(int uid1, int uid2) {
5261 // Map to base uids.
5262 uid1 = UserHandle.getAppId(uid1);
5263 uid2 = UserHandle.getAppId(uid2);
5265 synchronized (mPackages) {
5268 Object obj = mSettings.getUserIdLPr(uid1);
5270 if (obj instanceof SharedUserSetting) {
5271 s1 = ((SharedUserSetting)obj).signatures.mSignatures;
5272 } else if (obj instanceof PackageSetting) {
5273 s1 = ((PackageSetting)obj).signatures.mSignatures;
5275 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5278 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5280 obj = mSettings.getUserIdLPr(uid2);
5282 if (obj instanceof SharedUserSetting) {
5283 s2 = ((SharedUserSetting)obj).signatures.mSignatures;
5284 } else if (obj instanceof PackageSetting) {
5285 s2 = ((PackageSetting)obj).signatures.mSignatures;
5287 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5290 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5292 return compareSignatures(s1, s2);
5297 * This method should typically only be used when granting or revoking
5298 * permissions, since the app may immediately restart after this call.
5300 * If you're doing surgery on app code/data, use {@link PackageFreezer} to
5301 * guard your work against the app being relaunched.
5303 private void killUid(int appId, int userId, String reason) {
5304 final long identity = Binder.clearCallingIdentity();
5306 IActivityManager am = ActivityManager.getService();
5309 am.killUid(appId, userId, reason);
5310 } catch (RemoteException e) {
5311 /* ignore - same process */
5315 Binder.restoreCallingIdentity(identity);
5320 * Compares two sets of signatures. Returns:
5322 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
5324 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
5326 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
5328 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
5330 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
5332 static int compareSignatures(Signature[] s1, Signature[] s2) {
5335 ? PackageManager.SIGNATURE_NEITHER_SIGNED
5336 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
5340 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
5343 if (s1.length != s2.length) {
5344 return PackageManager.SIGNATURE_NO_MATCH;
5347 // Since both signature sets are of size 1, we can compare without HashSets.
5348 if (s1.length == 1) {
5349 return s1[0].equals(s2[0]) ?
5350 PackageManager.SIGNATURE_MATCH :
5351 PackageManager.SIGNATURE_NO_MATCH;
5354 ArraySet<Signature> set1 = new ArraySet<Signature>();
5355 for (Signature sig : s1) {
5358 ArraySet<Signature> set2 = new ArraySet<Signature>();
5359 for (Signature sig : s2) {
5362 // Make sure s2 contains all signatures in s1.
5363 if (set1.equals(set2)) {
5364 return PackageManager.SIGNATURE_MATCH;
5366 return PackageManager.SIGNATURE_NO_MATCH;
5370 * If the database version for this type of package (internal storage or
5371 * external storage) is less than the version where package signatures
5372 * were updated, return true.
5374 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5375 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5376 return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
5380 * Used for backward compatibility to make sure any packages with
5381 * certificate chains get upgraded to the new style. {@code existingSigs}
5382 * will be in the old format (since they were stored on disk from before the
5383 * system upgrade) and {@code scannedSigs} will be in the newer format.
5385 private int compareSignaturesCompat(PackageSignatures existingSigs,
5386 PackageParser.Package scannedPkg) {
5387 if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
5388 return PackageManager.SIGNATURE_NO_MATCH;
5391 ArraySet<Signature> existingSet = new ArraySet<Signature>();
5392 for (Signature sig : existingSigs.mSignatures) {
5393 existingSet.add(sig);
5395 ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
5396 for (Signature sig : scannedPkg.mSignatures) {
5398 Signature[] chainSignatures = sig.getChainSignatures();
5399 for (Signature chainSig : chainSignatures) {
5400 scannedCompatSet.add(chainSig);
5402 } catch (CertificateEncodingException e) {
5403 scannedCompatSet.add(sig);
5407 * Make sure the expanded scanned set contains all signatures in the
5410 if (scannedCompatSet.equals(existingSet)) {
5411 // Migrate the old signatures to the new scheme.
5412 existingSigs.assignSignatures(scannedPkg.mSignatures);
5413 // The new KeySets will be re-added later in the scanning process.
5414 synchronized (mPackages) {
5415 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
5417 return PackageManager.SIGNATURE_MATCH;
5419 return PackageManager.SIGNATURE_NO_MATCH;
5422 private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5423 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5424 return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
5427 private int compareSignaturesRecover(PackageSignatures existingSigs,
5428 PackageParser.Package scannedPkg) {
5429 if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
5430 return PackageManager.SIGNATURE_NO_MATCH;
5435 if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
5436 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
5437 + scannedPkg.packageName);
5438 return PackageManager.SIGNATURE_MATCH;
5440 } catch (CertificateException e) {
5441 msg = e.getMessage();
5444 logCriticalInfo(Log.INFO,
5445 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
5446 return PackageManager.SIGNATURE_NO_MATCH;
5450 public List<String> getAllPackages() {
5451 synchronized (mPackages) {
5452 return new ArrayList<String>(mPackages.keySet());
5457 public String[] getPackagesForUid(int uid) {
5458 final int userId = UserHandle.getUserId(uid);
5459 uid = UserHandle.getAppId(uid);
5461 synchronized (mPackages) {
5462 Object obj = mSettings.getUserIdLPr(uid);
5463 if (obj instanceof SharedUserSetting) {
5464 final SharedUserSetting sus = (SharedUserSetting) obj;
5465 final int N = sus.packages.size();
5466 String[] res = new String[N];
5467 final Iterator<PackageSetting> it = sus.packages.iterator();
5469 while (it.hasNext()) {
5470 PackageSetting ps = it.next();
5471 if (ps.getInstalled(userId)) {
5474 res = ArrayUtils.removeElement(String.class, res, res[i]);
5478 } else if (obj instanceof PackageSetting) {
5479 final PackageSetting ps = (PackageSetting) obj;
5480 if (ps.getInstalled(userId)) {
5481 return new String[]{ps.name};
5489 public String getNameForUid(int uid) {
5491 synchronized (mPackages) {
5492 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5493 if (obj instanceof SharedUserSetting) {
5494 final SharedUserSetting sus = (SharedUserSetting) obj;
5495 return sus.name + ":" + sus.userId;
5496 } else if (obj instanceof PackageSetting) {
5497 final PackageSetting ps = (PackageSetting) obj;
5505 public int getUidForSharedUser(String sharedUserName) {
5506 if(sharedUserName == null) {
5510 synchronized (mPackages) {
5511 SharedUserSetting suid;
5513 suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
5517 } catch (PackageManagerException ignore) {
5518 // can't happen, but, still need to catch it
5525 public int getFlagsForUid(int uid) {
5526 synchronized (mPackages) {
5527 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5528 if (obj instanceof SharedUserSetting) {
5529 final SharedUserSetting sus = (SharedUserSetting) obj;
5530 return sus.pkgFlags;
5531 } else if (obj instanceof PackageSetting) {
5532 final PackageSetting ps = (PackageSetting) obj;
5540 public int getPrivateFlagsForUid(int uid) {
5541 synchronized (mPackages) {
5542 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5543 if (obj instanceof SharedUserSetting) {
5544 final SharedUserSetting sus = (SharedUserSetting) obj;
5545 return sus.pkgPrivateFlags;
5546 } else if (obj instanceof PackageSetting) {
5547 final PackageSetting ps = (PackageSetting) obj;
5548 return ps.pkgPrivateFlags;
5555 public boolean isUidPrivileged(int uid) {
5556 uid = UserHandle.getAppId(uid);
5558 synchronized (mPackages) {
5559 Object obj = mSettings.getUserIdLPr(uid);
5560 if (obj instanceof SharedUserSetting) {
5561 final SharedUserSetting sus = (SharedUserSetting) obj;
5562 final Iterator<PackageSetting> it = sus.packages.iterator();
5563 while (it.hasNext()) {
5564 if (it.next().isPrivileged()) {
5568 } else if (obj instanceof PackageSetting) {
5569 final PackageSetting ps = (PackageSetting) obj;
5570 return ps.isPrivileged();
5577 public String[] getAppOpPermissionPackages(String permissionName) {
5578 synchronized (mPackages) {
5579 ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
5583 return pkgs.toArray(new String[pkgs.size()]);
5588 public ResolveInfo resolveIntent(Intent intent, String resolvedType,
5589 int flags, int userId) {
5590 return resolveIntentInternal(
5591 intent, resolvedType, flags, userId, false /*includeInstantApp*/);
5594 private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
5595 int flags, int userId, boolean includeInstantApp) {
5597 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
5599 if (!sUserManager.exists(userId)) return null;
5600 flags = updateFlagsForResolve(flags, userId, intent, includeInstantApp);
5601 enforceCrossUserPermission(Binder.getCallingUid(), userId,
5602 false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
5604 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
5605 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
5606 flags, userId, includeInstantApp);
5607 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5609 final ResolveInfo bestChoice =
5610 chooseBestActivity(intent, resolvedType, flags, query, userId);
5613 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5618 public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
5619 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
5620 throw new SecurityException(
5621 "findPersistentPreferredActivity can only be run by the system");
5623 if (!sUserManager.exists(userId)) {
5626 intent = updateIntentForResolve(intent);
5627 final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
5628 final int flags = updateFlagsForResolve(0, userId, intent, false);
5629 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5631 synchronized (mPackages) {
5632 return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
5638 public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
5639 IntentFilter filter, int match, ComponentName activity) {
5640 final int userId = UserHandle.getCallingUserId();
5641 if (DEBUG_PREFERRED) {
5642 Log.v(TAG, "setLastChosenActivity intent=" + intent
5643 + " resolvedType=" + resolvedType
5645 + " filter=" + filter
5647 + " activity=" + activity);
5648 filter.dump(new PrintStreamPrinter(System.out), " ");
5650 intent.setComponent(null);
5651 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5653 // Find any earlier preferred or last chosen entries and nuke them
5654 findPreferredActivity(intent, resolvedType,
5655 flags, query, 0, false, true, false, userId);
5656 // Add the new activity as the last chosen for this filter
5657 addPreferredActivityInternal(filter, match, null, activity, false, userId,
5658 "Setting last chosen");
5662 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
5663 final int userId = UserHandle.getCallingUserId();
5664 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
5665 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5667 return findPreferredActivity(intent, resolvedType, flags, query, 0,
5668 false, false, false, userId);
5672 * Returns whether or not instant apps have been disabled remotely.
5673 * <p><em>IMPORTANT</em> This should not be called with the package manager lock
5674 * held. Otherwise we run the risk of deadlock.
5676 private boolean isEphemeralDisabled() {
5677 // ephemeral apps have been disabled across the board
5678 if (DISABLE_EPHEMERAL_APPS) {
5681 // system isn't up yet; can't read settings, so, assume no ephemeral apps
5682 if (!mSystemReady) {
5685 // we can't get a content resolver until the system is ready; these checks must happen last
5686 final ContentResolver resolver = mContext.getContentResolver();
5687 if (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) {
5690 return Secure.getInt(resolver, Secure.WEB_ACTION_ENABLED, 1) == 0;
5693 private boolean isEphemeralAllowed(
5694 Intent intent, List<ResolveInfo> resolvedActivities, int userId,
5695 boolean skipPackageCheck) {
5696 final int callingUser = UserHandle.getCallingUserId();
5697 if (callingUser != UserHandle.USER_SYSTEM) {
5700 if (mInstantAppResolverConnection == null) {
5703 if (mInstantAppInstallerComponent == null) {
5706 if (intent.getComponent() != null) {
5709 if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
5712 if (!skipPackageCheck && intent.getPackage() != null) {
5715 final boolean isWebUri = hasWebURI(intent);
5716 if (!isWebUri || intent.getData().getHost() == null) {
5719 // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
5720 // Or if there's already an ephemeral app installed that handles the action
5721 synchronized (mPackages) {
5722 final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
5723 for (int n = 0; n < count; n++) {
5724 ResolveInfo info = resolvedActivities.get(n);
5725 String packageName = info.activityInfo.packageName;
5726 PackageSetting ps = mSettings.mPackages.get(packageName);
5728 // Try to get the status from User settings first
5729 long packedStatus = getDomainVerificationStatusLPr(ps, userId);
5730 int status = (int) (packedStatus >> 32);
5731 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
5732 || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
5733 if (DEBUG_EPHEMERAL) {
5734 Slog.v(TAG, "DENY ephemeral apps;"
5735 + " pkg: " + packageName + ", status: " + status);
5739 if (ps.getInstantApp(userId)) {
5740 if (DEBUG_EPHEMERAL) {
5741 Slog.v(TAG, "DENY instant app installed;"
5742 + " pkg: " + packageName);
5749 // We've exhausted all ways to deny ephemeral application; let the system look for them.
5753 private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
5754 Intent origIntent, String resolvedType, String callingPackage,
5756 final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
5757 new InstantAppRequest(responseObj, origIntent, resolvedType,
5758 callingPackage, userId));
5759 mHandler.sendMessage(msg);
5762 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
5763 int flags, List<ResolveInfo> query, int userId) {
5764 if (query != null) {
5765 final int N = query.size();
5767 return query.get(0);
5769 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
5770 // If there is more than one activity with the same priority,
5771 // then let the user decide between them.
5772 ResolveInfo r0 = query.get(0);
5773 ResolveInfo r1 = query.get(1);
5774 if (DEBUG_INTENT_MATCHING || debug) {
5775 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
5776 + r1.activityInfo.name + "=" + r1.priority);
5778 // If the first activity has a higher priority, or a different
5779 // default, then it is always desirable to pick it.
5780 if (r0.priority != r1.priority
5781 || r0.preferredOrder != r1.preferredOrder
5782 || r0.isDefault != r1.isDefault) {
5783 return query.get(0);
5785 // If we have saved a preference for a preferred activity for
5786 // this Intent, use that.
5787 ResolveInfo ri = findPreferredActivity(intent, resolvedType,
5788 flags, query, r0.priority, true, false, debug, userId);
5792 // If we have an ephemeral app, use it
5793 for (int i = 0; i < N; i++) {
5795 if (ri.activityInfo.applicationInfo.isInstantApp()) {
5799 ri = new ResolveInfo(mResolveInfo);
5800 ri.activityInfo = new ActivityInfo(ri.activityInfo);
5801 ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
5802 // If all of the options come from the same package, show the application's
5803 // label and icon instead of the generic resolver's.
5804 // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
5805 // and then throw away the ResolveInfo itself, meaning that the caller loses
5806 // the resolvePackageName. Therefore the activityInfo.labelRes above provides
5807 // a fallback for this case; we only set the target package's resources on
5808 // the ResolveInfo, not the ActivityInfo.
5809 final String intentPackage = intent.getPackage();
5810 if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
5811 final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
5812 ri.resolvePackageName = intentPackage;
5813 if (userNeedsBadging(userId)) {
5814 ri.noResourceId = true;
5816 ri.icon = appi.icon;
5818 ri.iconResourceId = appi.icon;
5819 ri.labelRes = appi.labelRes;
5821 ri.activityInfo.applicationInfo = new ApplicationInfo(
5822 ri.activityInfo.applicationInfo);
5824 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
5825 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
5827 // Make sure that the resolver is displayable in car mode
5828 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
5829 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
5837 * Return true if the given list is not empty and all of its contents have
5838 * an activityInfo with the given package name.
5840 private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
5841 if (ArrayUtils.isEmpty(list)) {
5844 for (int i = 0, N = list.size(); i < N; i++) {
5845 final ResolveInfo ri = list.get(i);
5846 final ActivityInfo ai = ri != null ? ri.activityInfo : null;
5847 if (ai == null || !packageName.equals(ai.packageName)) {
5854 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
5855 int flags, List<ResolveInfo> query, boolean debug, int userId) {
5856 final int N = query.size();
5857 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
5859 // Get the list of persistent preferred activities that handle the intent
5860 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
5861 List<PersistentPreferredActivity> pprefs = ppir != null
5862 ? ppir.queryIntent(intent, resolvedType,
5863 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
5866 if (pprefs != null && pprefs.size() > 0) {
5867 final int M = pprefs.size();
5868 for (int i=0; i<M; i++) {
5869 final PersistentPreferredActivity ppa = pprefs.get(i);
5870 if (DEBUG_PREFERRED || debug) {
5871 Slog.v(TAG, "Checking PersistentPreferredActivity ds="
5872 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
5873 + "\n component=" + ppa.mComponent);
5874 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
5876 final ActivityInfo ai = getActivityInfo(ppa.mComponent,
5877 flags | MATCH_DISABLED_COMPONENTS, userId);
5878 if (DEBUG_PREFERRED || debug) {
5879 Slog.v(TAG, "Found persistent preferred activity:");
5881 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
5883 Slog.v(TAG, " null");
5887 // This previously registered persistent preferred activity
5888 // component is no longer known. Ignore it and do NOT remove it.
5891 for (int j=0; j<N; j++) {
5892 final ResolveInfo ri = query.get(j);
5893 if (!ri.activityInfo.applicationInfo.packageName
5894 .equals(ai.applicationInfo.packageName)) {
5897 if (!ri.activityInfo.name.equals(ai.name)) {
5900 // Found a persistent preference that can handle the intent.
5901 if (DEBUG_PREFERRED || debug) {
5902 Slog.v(TAG, "Returning persistent preferred activity: " +
5903 ri.activityInfo.packageName + "/" + ri.activityInfo.name);
5912 // TODO: handle preferred activities missing while user has amnesia
5913 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
5914 List<ResolveInfo> query, int priority, boolean always,
5915 boolean removeMatches, boolean debug, int userId) {
5916 if (!sUserManager.exists(userId)) return null;
5917 flags = updateFlagsForResolve(flags, userId, intent, false);
5918 intent = updateIntentForResolve(intent);
5920 synchronized (mPackages) {
5921 // Try to find a matching persistent preferred activity.
5922 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
5925 // If a persistent preferred activity matched, use it.
5930 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
5931 // Get the list of preferred activities that handle the intent
5932 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
5933 List<PreferredActivity> prefs = pir != null
5934 ? pir.queryIntent(intent, resolvedType,
5935 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
5938 if (prefs != null && prefs.size() > 0) {
5939 boolean changed = false;
5941 // First figure out how good the original match set is.
5942 // We will only allow preferred activities that came
5943 // from the same match quality.
5946 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
5948 final int N = query.size();
5949 for (int j=0; j<N; j++) {
5950 final ResolveInfo ri = query.get(j);
5951 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
5952 + ": 0x" + Integer.toHexString(match));
5953 if (ri.match > match) {
5958 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
5959 + Integer.toHexString(match));
5961 match &= IntentFilter.MATCH_CATEGORY_MASK;
5962 final int M = prefs.size();
5963 for (int i=0; i<M; i++) {
5964 final PreferredActivity pa = prefs.get(i);
5965 if (DEBUG_PREFERRED || debug) {
5966 Slog.v(TAG, "Checking PreferredActivity ds="
5967 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
5968 + "\n component=" + pa.mPref.mComponent);
5969 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
5971 if (pa.mPref.mMatch != match) {
5972 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
5973 + Integer.toHexString(pa.mPref.mMatch));
5976 // If it's not an "always" type preferred activity and that's what we're
5977 // looking for, skip it.
5978 if (always && !pa.mPref.mAlways) {
5979 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
5982 final ActivityInfo ai = getActivityInfo(
5983 pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
5984 | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
5986 if (DEBUG_PREFERRED || debug) {
5987 Slog.v(TAG, "Found preferred activity:");
5989 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
5991 Slog.v(TAG, " null");
5995 // This previously registered preferred activity
5996 // component is no longer known. Most likely an update
5997 // to the app was installed and in the new version this
5998 // component no longer exists. Clean it up by removing
5999 // it from the preferred activities list, and skip it.
6000 Slog.w(TAG, "Removing dangling preferred activity: "
6001 + pa.mPref.mComponent);
6002 pir.removeFilter(pa);
6006 for (int j=0; j<N; j++) {
6007 final ResolveInfo ri = query.get(j);
6008 if (!ri.activityInfo.applicationInfo.packageName
6009 .equals(ai.applicationInfo.packageName)) {
6012 if (!ri.activityInfo.name.equals(ai.name)) {
6016 if (removeMatches) {
6017 pir.removeFilter(pa);
6019 if (DEBUG_PREFERRED) {
6020 Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
6025 // Okay we found a previously set preferred or last chosen app.
6026 // If the result set is different from when this
6027 // was created, we need to clear it and re-ask the
6028 // user their preference, if we're looking for an "always" type entry.
6029 if (always && !pa.mPref.sameSet(query)) {
6030 Slog.i(TAG, "Result set changed, dropping preferred activity for "
6031 + intent + " type " + resolvedType);
6032 if (DEBUG_PREFERRED) {
6033 Slog.v(TAG, "Removing preferred activity since set changed "
6034 + pa.mPref.mComponent);
6036 pir.removeFilter(pa);
6037 // Re-add the filter as a "last chosen" entry (!always)
6038 PreferredActivity lastChosen = new PreferredActivity(
6039 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
6040 pir.addFilter(lastChosen);
6045 // Yay! Either the set matched or we're looking for the last chosen
6046 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
6047 + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6053 if (DEBUG_PREFERRED) {
6054 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
6056 scheduleWritePackageRestrictionsLocked(userId);
6061 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
6066 * Returns if intent can be forwarded from the sourceUserId to the targetUserId
6069 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
6071 mContext.enforceCallingOrSelfPermission(
6072 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
6073 List<CrossProfileIntentFilter> matches =
6074 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
6075 if (matches != null) {
6076 int size = matches.size();
6077 for (int i = 0; i < size; i++) {
6078 if (matches.get(i).getTargetUserId() == targetUserId) return true;
6081 if (hasWebURI(intent)) {
6082 // cross-profile app linking works only towards the parent.
6083 final UserInfo parent = getProfileParent(sourceUserId);
6084 synchronized(mPackages) {
6085 int flags = updateFlagsForResolve(0, parent.id, intent, false);
6086 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
6087 intent, resolvedType, flags, sourceUserId, parent.id);
6088 return xpDomainInfo != null;
6094 private UserInfo getProfileParent(int userId) {
6095 final long identity = Binder.clearCallingIdentity();
6097 return sUserManager.getProfileParent(userId);
6099 Binder.restoreCallingIdentity(identity);
6103 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
6104 String resolvedType, int userId) {
6105 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
6106 if (resolver != null) {
6107 return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
6113 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
6114 String resolvedType, int flags, int userId) {
6116 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6118 return new ParceledListSlice<>(
6119 queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
6121 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6126 * Returns the package name of the calling Uid if it's an instant app. If it isn't
6127 * instant, returns {@code null}.
6129 private String getInstantAppPackageName(int callingUid) {
6130 // If the caller is an isolated app use the owner's uid for the lookup.
6131 if (Process.isIsolated(callingUid)) {
6132 callingUid = mIsolatedOwners.get(callingUid);
6134 final int appId = UserHandle.getAppId(callingUid);
6135 synchronized (mPackages) {
6136 final Object obj = mSettings.getUserIdLPr(appId);
6137 if (obj instanceof PackageSetting) {
6138 final PackageSetting ps = (PackageSetting) obj;
6139 final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
6140 return isInstantApp ? ps.pkg.packageName : null;
6146 private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6147 String resolvedType, int flags, int userId) {
6148 return queryIntentActivitiesInternal(intent, resolvedType, flags, userId, false);
6151 private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6152 String resolvedType, int flags, int userId, boolean includeInstantApp) {
6153 if (!sUserManager.exists(userId)) return Collections.emptyList();
6154 final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid());
6155 flags = updateFlagsForResolve(flags, userId, intent, includeInstantApp);
6156 enforceCrossUserPermission(Binder.getCallingUid(), userId,
6157 false /* requireFullPermission */, false /* checkShell */,
6158 "query intent activities");
6159 ComponentName comp = intent.getComponent();
6161 if (intent.getSelector() != null) {
6162 intent = intent.getSelector();
6163 comp = intent.getComponent();
6168 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6169 final ActivityInfo ai = getActivityInfo(comp, flags, userId);
6171 // When specifying an explicit component, we prevent the activity from being
6172 // used when either 1) the calling package is normal and the activity is within
6173 // an ephemeral application or 2) the calling package is ephemeral and the
6174 // activity is not visible to ephemeral applications.
6175 final boolean matchInstantApp =
6176 (flags & PackageManager.MATCH_INSTANT) != 0;
6177 final boolean matchVisibleToInstantAppOnly =
6178 (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
6179 final boolean isCallerInstantApp =
6180 instantAppPkgName != null;
6181 final boolean isTargetSameInstantApp =
6182 comp.getPackageName().equals(instantAppPkgName);
6183 final boolean isTargetInstantApp =
6184 (ai.applicationInfo.privateFlags
6185 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
6186 final boolean isTargetHiddenFromInstantApp =
6187 (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0;
6188 final boolean blockResolution =
6189 !isTargetSameInstantApp
6190 && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
6191 || (matchVisibleToInstantAppOnly && isCallerInstantApp
6192 && isTargetHiddenFromInstantApp));
6193 if (!blockResolution) {
6194 final ResolveInfo ri = new ResolveInfo();
6195 ri.activityInfo = ai;
6199 return applyPostResolutionFilter(list, instantAppPkgName);
6203 boolean sortResult = false;
6204 boolean addEphemeral = false;
6205 List<ResolveInfo> result;
6206 final String pkgName = intent.getPackage();
6207 final boolean ephemeralDisabled = isEphemeralDisabled();
6208 synchronized (mPackages) {
6209 if (pkgName == null) {
6210 List<CrossProfileIntentFilter> matchingFilters =
6211 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
6212 // Check for results that need to skip the current profile.
6213 ResolveInfo xpResolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent,
6214 resolvedType, flags, userId);
6215 if (xpResolveInfo != null) {
6216 List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
6217 xpResult.add(xpResolveInfo);
6218 return applyPostResolutionFilter(
6219 filterIfNotSystemUser(xpResult, userId), instantAppPkgName);
6222 // Check for results in the current profile.
6223 result = filterIfNotSystemUser(mActivities.queryIntent(
6224 intent, resolvedType, flags, userId), userId);
6225 addEphemeral = !ephemeralDisabled
6226 && isEphemeralAllowed(intent, result, userId, false /*skipPackageCheck*/);
6227 // Check for cross profile results.
6228 boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
6229 xpResolveInfo = queryCrossProfileIntents(
6230 matchingFilters, intent, resolvedType, flags, userId,
6231 hasNonNegativePriorityResult);
6232 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
6233 boolean isVisibleToUser = filterIfNotSystemUser(
6234 Collections.singletonList(xpResolveInfo), userId).size() > 0;
6235 if (isVisibleToUser) {
6236 result.add(xpResolveInfo);
6240 if (hasWebURI(intent)) {
6241 CrossProfileDomainInfo xpDomainInfo = null;
6242 final UserInfo parent = getProfileParent(userId);
6243 if (parent != null) {
6244 xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
6245 flags, userId, parent.id);
6247 if (xpDomainInfo != null) {
6248 if (xpResolveInfo != null) {
6249 // If we didn't remove it, the cross-profile ResolveInfo would be twice
6251 result.remove(xpResolveInfo);
6253 if (result.size() == 0 && !addEphemeral) {
6254 // No result in current profile, but found candidate in parent user.
6255 // And we are not going to add emphemeral app, so we can return the
6256 // result straight away.
6257 result.add(xpDomainInfo.resolveInfo);
6258 return applyPostResolutionFilter(result, instantAppPkgName);
6260 } else if (result.size() <= 1 && !addEphemeral) {
6261 // No result in parent user and <= 1 result in current profile, and we
6262 // are not going to add emphemeral app, so we can return the result without
6263 // further processing.
6264 return applyPostResolutionFilter(result, instantAppPkgName);
6266 // We have more than one candidate (combining results from current and parent
6267 // profile), so we need filtering and sorting.
6268 result = filterCandidatesWithDomainPreferredActivitiesLPr(
6269 intent, flags, result, xpDomainInfo, userId);
6273 final PackageParser.Package pkg = mPackages.get(pkgName);
6275 return applyPostResolutionFilter(filterIfNotSystemUser(
6276 mActivities.queryIntentForPackage(
6277 intent, resolvedType, flags, pkg.activities, userId),
6278 userId), instantAppPkgName);
6280 // the caller wants to resolve for a particular package; however, there
6281 // were no installed results, so, try to find an ephemeral result
6282 addEphemeral = !ephemeralDisabled
6283 && isEphemeralAllowed(
6284 intent, null /*result*/, userId, true /*skipPackageCheck*/);
6285 result = new ArrayList<ResolveInfo>();
6290 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
6291 final InstantAppRequest requestObject = new InstantAppRequest(
6292 null /*responseObj*/, intent /*origIntent*/, resolvedType,
6293 null /*callingPackage*/, userId);
6294 final AuxiliaryResolveInfo auxiliaryResponse =
6295 InstantAppResolver.doInstantAppResolutionPhaseOne(
6296 mContext, mInstantAppResolverConnection, requestObject);
6297 if (auxiliaryResponse != null) {
6298 if (DEBUG_EPHEMERAL) {
6299 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
6301 final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
6302 ephemeralInstaller.activityInfo = new ActivityInfo(mInstantAppInstallerActivity);
6303 ephemeralInstaller.activityInfo.launchToken = auxiliaryResponse.token;
6304 ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
6305 // make sure this resolver is the default
6306 ephemeralInstaller.isDefault = true;
6307 ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6308 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6309 // add a non-generic filter
6310 ephemeralInstaller.filter = new IntentFilter(intent.getAction());
6311 ephemeralInstaller.filter.addDataPath(
6312 intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
6313 ephemeralInstaller.instantAppAvailable = true;
6314 result.add(ephemeralInstaller);
6316 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6319 Collections.sort(result, mResolvePrioritySorter);
6321 return applyPostResolutionFilter(result, instantAppPkgName);
6324 private static class CrossProfileDomainInfo {
6325 /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
6326 ResolveInfo resolveInfo;
6327 /* Best domain verification status of the activities found in the other profile */
6328 int bestDomainVerificationStatus;
6331 private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
6332 String resolvedType, int flags, int sourceUserId, int parentUserId) {
6333 if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
6337 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
6338 resolvedType, flags, parentUserId);
6340 if (resultTargetUser == null || resultTargetUser.isEmpty()) {
6343 CrossProfileDomainInfo result = null;
6344 int size = resultTargetUser.size();
6345 for (int i = 0; i < size; i++) {
6346 ResolveInfo riTargetUser = resultTargetUser.get(i);
6347 // Intent filter verification is only for filters that specify a host. So don't return
6348 // those that handle all web uris.
6349 if (riTargetUser.handleAllWebDataURI) {
6352 String packageName = riTargetUser.activityInfo.packageName;
6353 PackageSetting ps = mSettings.mPackages.get(packageName);
6357 long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
6358 int status = (int)(verificationState >> 32);
6359 if (result == null) {
6360 result = new CrossProfileDomainInfo();
6361 result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
6362 sourceUserId, parentUserId);
6363 result.bestDomainVerificationStatus = status;
6365 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
6366 result.bestDomainVerificationStatus);
6369 // Don't consider matches with status NEVER across profiles.
6370 if (result != null && result.bestDomainVerificationStatus
6371 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6378 * Verification statuses are ordered from the worse to the best, except for
6379 * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
6381 private int bestDomainVerificationStatus(int status1, int status2) {
6382 if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6385 if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6388 return (int) MathUtils.max(status1, status2);
6391 private boolean isUserEnabled(int userId) {
6392 long callingId = Binder.clearCallingIdentity();
6394 UserInfo userInfo = sUserManager.getUserInfo(userId);
6395 return userInfo != null && userInfo.isEnabled();
6397 Binder.restoreCallingIdentity(callingId);
6402 * Filter out activities with systemUserOnly flag set, when current user is not System.
6404 * @return filtered list
6406 private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
6407 if (userId == UserHandle.USER_SYSTEM) {
6408 return resolveInfos;
6410 for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6411 ResolveInfo info = resolveInfos.get(i);
6412 if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
6413 resolveInfos.remove(i);
6416 return resolveInfos;
6420 * Filters out ephemeral activities.
6421 * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
6422 * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
6424 * @param resolveInfos The pre-filtered list of resolved activities
6425 * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
6427 * @return A filtered list of resolved activities.
6429 private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
6430 String ephemeralPkgName) {
6431 // TODO: When adding on-demand split support for non-instant apps, remove this check
6432 // and always apply post filtering
6433 if (ephemeralPkgName == null) {
6434 return resolveInfos;
6436 for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6437 final ResolveInfo info = resolveInfos.get(i);
6438 final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
6439 // allow activities that are defined in the provided package
6440 if (isEphemeralApp && ephemeralPkgName.equals(info.activityInfo.packageName)) {
6441 if (info.activityInfo.splitName != null
6442 && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
6443 info.activityInfo.splitName)) {
6444 // requested activity is defined in a split that hasn't been installed yet.
6445 // add the installer to the resolve list
6446 if (DEBUG_EPHEMERAL) {
6447 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
6449 final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
6450 installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
6451 info.activityInfo.packageName, info.activityInfo.splitName,
6452 info.activityInfo.applicationInfo.versionCode);
6453 // make sure this resolver is the default
6454 installerInfo.isDefault = true;
6455 installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6456 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6457 // add a non-generic filter
6458 installerInfo.filter = new IntentFilter();
6459 // load resources from the correct package
6460 installerInfo.resolvePackageName = info.getComponentInfo().packageName;
6461 resolveInfos.set(i, installerInfo);
6465 // allow activities that have been explicitly exposed to ephemeral apps
6467 && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0)) {
6470 resolveInfos.remove(i);
6472 return resolveInfos;
6476 * @param resolveInfos list of resolve infos in descending priority order
6477 * @return if the list contains a resolve info with non-negative priority
6479 private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
6480 return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
6483 private static boolean hasWebURI(Intent intent) {
6484 if (intent.getData() == null) {
6487 final String scheme = intent.getScheme();
6488 if (TextUtils.isEmpty(scheme)) {
6491 return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
6494 private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
6495 int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
6497 final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
6499 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
6500 Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
6504 ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
6505 ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
6506 ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
6507 ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
6508 ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
6509 ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
6511 synchronized (mPackages) {
6512 final int count = candidates.size();
6513 // First, try to use linked apps. Partition the candidates into four lists:
6514 // one for the final results, one for the "do not use ever", one for "undefined status"
6515 // and finally one for "browser app type".
6516 for (int n=0; n<count; n++) {
6517 ResolveInfo info = candidates.get(n);
6518 String packageName = info.activityInfo.packageName;
6519 PackageSetting ps = mSettings.mPackages.get(packageName);
6521 // Add to the special match all list (Browser use case)
6522 if (info.handleAllWebDataURI) {
6523 matchAllList.add(info);
6526 // Try to get the status from User settings first
6527 long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6528 int status = (int)(packedStatus >> 32);
6529 int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
6530 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
6531 if (DEBUG_DOMAIN_VERIFICATION || debug) {
6532 Slog.i(TAG, " + always: " + info.activityInfo.packageName
6533 + " : linkgen=" + linkGeneration);
6535 // Use link-enabled generation as preferredOrder, i.e.
6536 // prefer newly-enabled over earlier-enabled.
6537 info.preferredOrder = linkGeneration;
6538 alwaysList.add(info);
6539 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6540 if (DEBUG_DOMAIN_VERIFICATION || debug) {
6541 Slog.i(TAG, " + never: " + info.activityInfo.packageName);
6543 neverList.add(info);
6544 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6545 if (DEBUG_DOMAIN_VERIFICATION || debug) {
6546 Slog.i(TAG, " + always-ask: " + info.activityInfo.packageName);
6548 alwaysAskList.add(info);
6549 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
6550 status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
6551 if (DEBUG_DOMAIN_VERIFICATION || debug) {
6552 Slog.i(TAG, " + ask: " + info.activityInfo.packageName);
6554 undefinedList.add(info);
6559 // We'll want to include browser possibilities in a few cases
6560 boolean includeBrowser = false;
6562 // First try to add the "always" resolution(s) for the current user, if any
6563 if (alwaysList.size() > 0) {
6564 result.addAll(alwaysList);
6566 // Add all undefined apps as we want them to appear in the disambiguation dialog.
6567 result.addAll(undefinedList);
6568 // Maybe add one for the other profile.
6569 if (xpDomainInfo != null && (
6570 xpDomainInfo.bestDomainVerificationStatus
6571 != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
6572 result.add(xpDomainInfo.resolveInfo);
6574 includeBrowser = true;
6577 // The presence of any 'always ask' alternatives means we'll also offer browsers.
6578 // If there were 'always' entries their preferred order has been set, so we also
6579 // back that off to make the alternatives equivalent
6580 if (alwaysAskList.size() > 0) {
6581 for (ResolveInfo i : result) {
6582 i.preferredOrder = 0;
6584 result.addAll(alwaysAskList);
6585 includeBrowser = true;
6588 if (includeBrowser) {
6589 // Also add browsers (all of them or only the default one)
6590 if (DEBUG_DOMAIN_VERIFICATION) {
6591 Slog.v(TAG, " ...including browsers in candidate set");
6593 if ((matchFlags & MATCH_ALL) != 0) {
6594 result.addAll(matchAllList);
6596 // Browser/generic handling case. If there's a default browser, go straight
6597 // to that (but only if there is no other higher-priority match).
6598 final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
6599 int maxMatchPrio = 0;
6600 ResolveInfo defaultBrowserMatch = null;
6601 final int numCandidates = matchAllList.size();
6602 for (int n = 0; n < numCandidates; n++) {
6603 ResolveInfo info = matchAllList.get(n);
6604 // track the highest overall match priority...
6605 if (info.priority > maxMatchPrio) {
6606 maxMatchPrio = info.priority;
6608 // ...and the highest-priority default browser match
6609 if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
6610 if (defaultBrowserMatch == null
6611 || (defaultBrowserMatch.priority < info.priority)) {
6613 Slog.v(TAG, "Considering default browser match " + info);
6615 defaultBrowserMatch = info;
6619 if (defaultBrowserMatch != null
6620 && defaultBrowserMatch.priority >= maxMatchPrio
6621 && !TextUtils.isEmpty(defaultBrowserPackageName))
6624 Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
6626 result.add(defaultBrowserMatch);
6628 result.addAll(matchAllList);
6632 // If there is nothing selected, add all candidates and remove the ones that the user
6633 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
6634 if (result.size() == 0) {
6635 result.addAll(candidates);
6636 result.removeAll(neverList);
6640 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
6641 Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
6643 for (ResolveInfo info : result) {
6644 Slog.v(TAG, " + " + info.activityInfo);
6650 // Returns a packed value as a long:
6652 // high 'int'-sized word: link status: undefined/ask/never/always.
6653 // low 'int'-sized word: relative priority among 'always' results.
6654 private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
6655 long result = ps.getDomainVerificationStatusForUser(userId);
6656 // if none available, get the master status
6657 if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
6658 if (ps.getIntentFilterVerificationInfo() != null) {
6659 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
6665 private ResolveInfo querySkipCurrentProfileIntents(
6666 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
6667 int flags, int sourceUserId) {
6668 if (matchingFilters != null) {
6669 int size = matchingFilters.size();
6670 for (int i = 0; i < size; i ++) {
6671 CrossProfileIntentFilter filter = matchingFilters.get(i);
6672 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
6673 // Checking if there are activities in the target user that can handle the
6675 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
6676 resolvedType, flags, sourceUserId);
6677 if (resolveInfo != null) {
6686 // Return matching ResolveInfo in target user if any.
6687 private ResolveInfo queryCrossProfileIntents(
6688 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
6689 int flags, int sourceUserId, boolean matchInCurrentProfile) {
6690 if (matchingFilters != null) {
6691 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
6692 // match the same intent. For performance reasons, it is better not to
6693 // run queryIntent twice for the same userId
6694 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
6695 int size = matchingFilters.size();
6696 for (int i = 0; i < size; i++) {
6697 CrossProfileIntentFilter filter = matchingFilters.get(i);
6698 int targetUserId = filter.getTargetUserId();
6699 boolean skipCurrentProfile =
6700 (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
6701 boolean skipCurrentProfileIfNoMatchFound =
6702 (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
6703 if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
6704 && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
6705 // Checking if there are activities in the target user that can handle the
6707 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
6708 resolvedType, flags, sourceUserId);
6709 if (resolveInfo != null) return resolveInfo;
6710 alreadyTriedUserIds.put(targetUserId, true);
6718 * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
6719 * will forward the intent to the filter's target user.
6720 * Otherwise, returns null.
6722 private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
6723 String resolvedType, int flags, int sourceUserId) {
6724 int targetUserId = filter.getTargetUserId();
6725 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
6726 resolvedType, flags, targetUserId);
6727 if (resultTargetUser != null && isUserEnabled(targetUserId)) {
6728 // If all the matches in the target profile are suspended, return null.
6729 for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
6730 if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
6731 & ApplicationInfo.FLAG_SUSPENDED) == 0) {
6732 return createForwardingResolveInfoUnchecked(filter, sourceUserId,
6740 private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
6741 int sourceUserId, int targetUserId) {
6742 ResolveInfo forwardingResolveInfo = new ResolveInfo();
6743 long ident = Binder.clearCallingIdentity();
6744 boolean targetIsProfile;
6746 targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
6748 Binder.restoreCallingIdentity(ident);
6751 if (targetIsProfile) {
6752 className = FORWARD_INTENT_TO_MANAGED_PROFILE;
6754 className = FORWARD_INTENT_TO_PARENT;
6756 ComponentName forwardingActivityComponentName = new ComponentName(
6757 mAndroidApplication.packageName, className);
6758 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
6760 if (!targetIsProfile) {
6761 forwardingActivityInfo.showUserIcon = targetUserId;
6762 forwardingResolveInfo.noResourceId = true;
6764 forwardingResolveInfo.activityInfo = forwardingActivityInfo;
6765 forwardingResolveInfo.priority = 0;
6766 forwardingResolveInfo.preferredOrder = 0;
6767 forwardingResolveInfo.match = 0;
6768 forwardingResolveInfo.isDefault = true;
6769 forwardingResolveInfo.filter = filter;
6770 forwardingResolveInfo.targetUserId = targetUserId;
6771 return forwardingResolveInfo;
6775 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
6776 Intent[] specifics, String[] specificTypes, Intent intent,
6777 String resolvedType, int flags, int userId) {
6778 return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
6779 specificTypes, intent, resolvedType, flags, userId));
6782 private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
6783 Intent[] specifics, String[] specificTypes, Intent intent,
6784 String resolvedType, int flags, int userId) {
6785 if (!sUserManager.exists(userId)) return Collections.emptyList();
6786 flags = updateFlagsForResolve(flags, userId, intent, false);
6787 enforceCrossUserPermission(Binder.getCallingUid(), userId,
6788 false /* requireFullPermission */, false /* checkShell */,
6789 "query intent activity options");
6790 final String resultsAction = intent.getAction();
6792 final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
6793 | PackageManager.GET_RESOLVED_FILTER, userId);
6795 if (DEBUG_INTENT_MATCHING) {
6796 Log.v(TAG, "Query " + intent + ": " + results);
6799 int specificsPos = 0;
6802 // todo: note that the algorithm used here is O(N^2). This
6803 // isn't a problem in our current environment, but if we start running
6804 // into situations where we have more than 5 or 10 matches then this
6805 // should probably be changed to something smarter...
6807 // First we go through and resolve each of the specific items
6808 // that were supplied, taking care of removing any corresponding
6809 // duplicate items in the generic resolve list.
6810 if (specifics != null) {
6811 for (int i=0; i<specifics.length; i++) {
6812 final Intent sintent = specifics[i];
6813 if (sintent == null) {
6817 if (DEBUG_INTENT_MATCHING) {
6818 Log.v(TAG, "Specific #" + i + ": " + sintent);
6821 String action = sintent.getAction();
6822 if (resultsAction != null && resultsAction.equals(action)) {
6823 // If this action was explicitly requested, then don't
6824 // remove things that have it.
6828 ResolveInfo ri = null;
6829 ActivityInfo ai = null;
6831 ComponentName comp = sintent.getComponent();
6835 specificTypes != null ? specificTypes[i] : null,
6840 if (ri == mResolveInfo) {
6841 // ACK! Must do something better with this.
6843 ai = ri.activityInfo;
6844 comp = new ComponentName(ai.applicationInfo.packageName,
6847 ai = getActivityInfo(comp, flags, userId);
6853 // Look for any generic query activities that are duplicates
6854 // of this specific one, and remove them from the results.
6855 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
6858 for (j=specificsPos; j<N; j++) {
6859 ResolveInfo sri = results.get(j);
6860 if ((sri.activityInfo.name.equals(comp.getClassName())
6861 && sri.activityInfo.applicationInfo.packageName.equals(
6862 comp.getPackageName()))
6863 || (action != null && sri.filter.matchAction(action))) {
6865 if (DEBUG_INTENT_MATCHING) Log.v(
6866 TAG, "Removing duplicate item from " + j
6867 + " due to specific " + specificsPos);
6876 // Add this specific item to its proper place.
6878 ri = new ResolveInfo();
6879 ri.activityInfo = ai;
6881 results.add(specificsPos, ri);
6882 ri.specificIndex = i;
6887 // Now we go through the remaining generic results and remove any
6888 // duplicate actions that are found here.
6890 for (int i=specificsPos; i<N-1; i++) {
6891 final ResolveInfo rii = results.get(i);
6892 if (rii.filter == null) {
6896 // Iterate over all of the actions of this result's intent
6897 // filter... typically this should be just one.
6898 final Iterator<String> it = rii.filter.actionsIterator();
6902 while (it.hasNext()) {
6903 final String action = it.next();
6904 if (resultsAction != null && resultsAction.equals(action)) {
6905 // If this action was explicitly requested, then don't
6906 // remove things that have it.
6909 for (int j=i+1; j<N; j++) {
6910 final ResolveInfo rij = results.get(j);
6911 if (rij.filter != null && rij.filter.hasAction(action)) {
6913 if (DEBUG_INTENT_MATCHING) Log.v(
6914 TAG, "Removing duplicate item from " + j
6915 + " due to action " + action + " at " + i);
6922 // If the caller didn't request filter information, drop it now
6923 // so we don't have to marshall/unmarshall it.
6924 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
6929 // Filter out the caller activity if so requested.
6930 if (caller != null) {
6932 for (int i=0; i<N; i++) {
6933 ActivityInfo ainfo = results.get(i).activityInfo;
6934 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
6935 && caller.getClassName().equals(ainfo.name)) {
6942 // If the caller didn't request filter information,
6943 // drop them now so we don't have to
6944 // marshall/unmarshall it.
6945 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
6947 for (int i=0; i<N; i++) {
6948 results.get(i).filter = null;
6952 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
6957 public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
6958 String resolvedType, int flags, int userId) {
6959 return new ParceledListSlice<>(
6960 queryIntentReceiversInternal(intent, resolvedType, flags, userId));
6963 private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
6964 String resolvedType, int flags, int userId) {
6965 if (!sUserManager.exists(userId)) return Collections.emptyList();
6966 flags = updateFlagsForResolve(flags, userId, intent, false);
6967 ComponentName comp = intent.getComponent();
6969 if (intent.getSelector() != null) {
6970 intent = intent.getSelector();
6971 comp = intent.getComponent();
6975 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6976 ActivityInfo ai = getReceiverInfo(comp, flags, userId);
6978 ResolveInfo ri = new ResolveInfo();
6979 ri.activityInfo = ai;
6986 synchronized (mPackages) {
6987 String pkgName = intent.getPackage();
6988 if (pkgName == null) {
6989 return mReceivers.queryIntent(intent, resolvedType, flags, userId);
6991 final PackageParser.Package pkg = mPackages.get(pkgName);
6993 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
6996 return Collections.emptyList();
7001 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
7002 if (!sUserManager.exists(userId)) return null;
7003 flags = updateFlagsForResolve(flags, userId, intent, false);
7004 List<ResolveInfo> query = queryIntentServicesInternal(intent, resolvedType, flags, userId);
7005 if (query != null) {
7006 if (query.size() >= 1) {
7007 // If there is more than one service with the same priority,
7008 // just arbitrarily pick the first one.
7009 return query.get(0);
7016 public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
7017 String resolvedType, int flags, int userId) {
7018 return new ParceledListSlice<>(
7019 queryIntentServicesInternal(intent, resolvedType, flags, userId));
7022 private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
7023 String resolvedType, int flags, int userId) {
7024 if (!sUserManager.exists(userId)) return Collections.emptyList();
7025 flags = updateFlagsForResolve(flags, userId, intent, false);
7026 ComponentName comp = intent.getComponent();
7028 if (intent.getSelector() != null) {
7029 intent = intent.getSelector();
7030 comp = intent.getComponent();
7034 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7035 final ServiceInfo si = getServiceInfo(comp, flags, userId);
7037 final ResolveInfo ri = new ResolveInfo();
7038 ri.serviceInfo = si;
7045 synchronized (mPackages) {
7046 String pkgName = intent.getPackage();
7047 if (pkgName == null) {
7048 return mServices.queryIntent(intent, resolvedType, flags, userId);
7050 final PackageParser.Package pkg = mPackages.get(pkgName);
7052 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
7055 return Collections.emptyList();
7060 public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
7061 String resolvedType, int flags, int userId) {
7062 return new ParceledListSlice<>(
7063 queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
7066 private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
7067 Intent intent, String resolvedType, int flags, int userId) {
7068 if (!sUserManager.exists(userId)) return Collections.emptyList();
7069 flags = updateFlagsForResolve(flags, userId, intent, false);
7070 ComponentName comp = intent.getComponent();
7072 if (intent.getSelector() != null) {
7073 intent = intent.getSelector();
7074 comp = intent.getComponent();
7078 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7079 final ProviderInfo pi = getProviderInfo(comp, flags, userId);
7081 final ResolveInfo ri = new ResolveInfo();
7082 ri.providerInfo = pi;
7089 synchronized (mPackages) {
7090 String pkgName = intent.getPackage();
7091 if (pkgName == null) {
7092 return mProviders.queryIntent(intent, resolvedType, flags, userId);
7094 final PackageParser.Package pkg = mPackages.get(pkgName);
7096 return mProviders.queryIntentForPackage(
7097 intent, resolvedType, flags, pkg.providers, userId);
7099 return Collections.emptyList();
7104 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
7105 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7106 flags = updateFlagsForPackage(flags, userId, null);
7107 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7108 enforceCrossUserPermission(Binder.getCallingUid(), userId,
7109 true /* requireFullPermission */, false /* checkShell */,
7110 "get installed packages");
7113 synchronized (mPackages) {
7114 ArrayList<PackageInfo> list;
7115 if (listUninstalled) {
7116 list = new ArrayList<>(mSettings.mPackages.size());
7117 for (PackageSetting ps : mSettings.mPackages.values()) {
7118 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
7121 final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7127 list = new ArrayList<>(mPackages.size());
7128 for (PackageParser.Package p : mPackages.values()) {
7129 if (filterSharedLibPackageLPr((PackageSetting) p.mExtras,
7130 Binder.getCallingUid(), userId)) {
7133 final PackageInfo pi = generatePackageInfo((PackageSetting)
7134 p.mExtras, flags, userId);
7141 return new ParceledListSlice<>(list);
7145 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
7146 String[] permissions, boolean[] tmp, int flags, int userId) {
7148 final PermissionsState permissionsState = ps.getPermissionsState();
7149 for (int i=0; i<permissions.length; i++) {
7150 final String permission = permissions[i];
7151 if (permissionsState.hasPermission(permission, userId)) {
7158 if (numMatch == 0) {
7161 final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7163 // The above might return null in cases of uninstalled apps or install-state
7164 // skew across users/profiles.
7166 if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
7167 if (numMatch == permissions.length) {
7168 pi.requestedPermissions = permissions;
7170 pi.requestedPermissions = new String[numMatch];
7172 for (int i=0; i<permissions.length; i++) {
7174 pi.requestedPermissions[numMatch] = permissions[i];
7185 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
7186 String[] permissions, int flags, int userId) {
7187 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7188 flags = updateFlagsForPackage(flags, userId, permissions);
7189 enforceCrossUserPermission(Binder.getCallingUid(), userId,
7190 true /* requireFullPermission */, false /* checkShell */,
7191 "get packages holding permissions");
7192 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7195 synchronized (mPackages) {
7196 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
7197 boolean[] tmpBools = new boolean[permissions.length];
7198 if (listUninstalled) {
7199 for (PackageSetting ps : mSettings.mPackages.values()) {
7200 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7204 for (PackageParser.Package pkg : mPackages.values()) {
7205 PackageSetting ps = (PackageSetting)pkg.mExtras;
7207 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7213 return new ParceledListSlice<PackageInfo>(list);
7218 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
7219 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7220 flags = updateFlagsForApplication(flags, userId, null);
7221 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7224 synchronized (mPackages) {
7225 ArrayList<ApplicationInfo> list;
7226 if (listUninstalled) {
7227 list = new ArrayList<>(mSettings.mPackages.size());
7228 for (PackageSetting ps : mSettings.mPackages.values()) {
7230 int effectiveFlags = flags;
7231 if (ps.isSystem()) {
7232 effectiveFlags |= PackageManager.MATCH_ANY_USER;
7234 if (ps.pkg != null) {
7235 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
7238 ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
7239 ps.readUserState(userId), userId);
7241 rebaseEnabledOverlays(ai, userId);
7242 ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
7245 // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
7246 // and already converts to externally visible package name
7247 ai = generateApplicationInfoFromSettingsLPw(ps.name,
7248 Binder.getCallingUid(), effectiveFlags, userId);
7255 list = new ArrayList<>(mPackages.size());
7256 for (PackageParser.Package p : mPackages.values()) {
7257 if (p.mExtras != null) {
7258 PackageSetting ps = (PackageSetting) p.mExtras;
7259 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
7262 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
7263 ps.readUserState(userId), userId);
7265 rebaseEnabledOverlays(ai, userId);
7266 ai.packageName = resolveExternalPackageNameLPr(p);
7273 return new ParceledListSlice<>(list);
7278 public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
7279 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7283 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
7284 "getEphemeralApplications");
7285 enforceCrossUserPermission(Binder.getCallingUid(), userId,
7286 true /* requireFullPermission */, false /* checkShell */,
7287 "getEphemeralApplications");
7288 synchronized (mPackages) {
7289 List<InstantAppInfo> instantApps = mInstantAppRegistry
7290 .getInstantAppsLPr(userId);
7291 if (instantApps != null) {
7292 return new ParceledListSlice<>(instantApps);
7299 public boolean isInstantApp(String packageName, int userId) {
7300 enforceCrossUserPermission(Binder.getCallingUid(), userId,
7301 true /* requireFullPermission */, false /* checkShell */,
7303 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7306 int uid = Binder.getCallingUid();
7307 if (Process.isIsolated(uid)) {
7308 uid = mIsolatedOwners.get(uid);
7311 synchronized (mPackages) {
7312 final PackageSetting ps = mSettings.mPackages.get(packageName);
7313 PackageParser.Package pkg = mPackages.get(packageName);
7314 final boolean returnAllowed =
7316 && (isCallerSameApp(packageName, uid)
7317 || mContext.checkCallingOrSelfPermission(
7318 android.Manifest.permission.ACCESS_INSTANT_APPS)
7319 == PERMISSION_GRANTED
7320 || mInstantAppRegistry.isInstantAccessGranted(
7321 userId, UserHandle.getAppId(uid), ps.appId));
7322 if (returnAllowed) {
7323 return ps.getInstantApp(userId);
7330 public byte[] getInstantAppCookie(String packageName, int userId) {
7331 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7335 enforceCrossUserPermission(Binder.getCallingUid(), userId,
7336 true /* requireFullPermission */, false /* checkShell */,
7337 "getInstantAppCookie");
7338 if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
7341 synchronized (mPackages) {
7342 return mInstantAppRegistry.getInstantAppCookieLPw(
7343 packageName, userId);
7348 public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
7349 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7353 enforceCrossUserPermission(Binder.getCallingUid(), userId,
7354 true /* requireFullPermission */, true /* checkShell */,
7355 "setInstantAppCookie");
7356 if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
7359 synchronized (mPackages) {
7360 return mInstantAppRegistry.setInstantAppCookieLPw(
7361 packageName, cookie, userId);
7366 public Bitmap getInstantAppIcon(String packageName, int userId) {
7367 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7371 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
7372 "getInstantAppIcon");
7374 enforceCrossUserPermission(Binder.getCallingUid(), userId,
7375 true /* requireFullPermission */, false /* checkShell */,
7376 "getInstantAppIcon");
7378 synchronized (mPackages) {
7379 return mInstantAppRegistry.getInstantAppIconLPw(
7380 packageName, userId);
7384 private boolean isCallerSameApp(String packageName, int uid) {
7385 PackageParser.Package pkg = mPackages.get(packageName);
7387 && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
7391 public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
7392 return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
7395 private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
7396 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
7399 synchronized (mPackages) {
7400 final Iterator<PackageParser.Package> i = mPackages.values().iterator();
7401 final int userId = UserHandle.getCallingUserId();
7402 while (i.hasNext()) {
7403 final PackageParser.Package p = i.next();
7404 if (p.applicationInfo == null) continue;
7406 final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
7407 && !p.applicationInfo.isDirectBootAware();
7408 final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
7409 && p.applicationInfo.isDirectBootAware();
7411 if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
7412 && (!mSafeMode || isSystemApp(p))
7413 && (matchesUnaware || matchesAware)) {
7414 PackageSetting ps = mSettings.mPackages.get(p.packageName);
7416 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
7417 ps.readUserState(userId), userId);
7419 rebaseEnabledOverlays(ai, userId);
7431 public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
7432 if (!sUserManager.exists(userId)) return null;
7433 flags = updateFlagsForComponent(flags, userId, name);
7435 synchronized (mPackages) {
7436 final PackageParser.Provider provider = mProvidersByAuthority.get(name);
7437 PackageSetting ps = provider != null
7438 ? mSettings.mPackages.get(provider.owner.packageName)
7441 && mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)
7442 ? PackageParser.generateProviderInfo(provider, flags,
7443 ps.readUserState(userId), userId)
7452 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
7454 synchronized (mPackages) {
7455 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
7456 .entrySet().iterator();
7457 final int userId = UserHandle.getCallingUserId();
7458 while (i.hasNext()) {
7459 Map.Entry<String, PackageParser.Provider> entry = i.next();
7460 PackageParser.Provider p = entry.getValue();
7461 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
7463 if (ps != null && p.syncable
7464 && (!mSafeMode || (p.info.applicationInfo.flags
7465 &ApplicationInfo.FLAG_SYSTEM) != 0)) {
7466 ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
7467 ps.readUserState(userId), userId);
7469 outNames.add(entry.getKey());
7478 public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
7479 int uid, int flags, String metaDataKey) {
7480 final int userId = processName != null ? UserHandle.getUserId(uid)
7481 : UserHandle.getCallingUserId();
7482 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7483 flags = updateFlagsForComponent(flags, userId, processName);
7485 ArrayList<ProviderInfo> finalList = null;
7487 synchronized (mPackages) {
7488 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
7489 while (i.hasNext()) {
7490 final PackageParser.Provider p = i.next();
7491 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
7492 if (ps != null && p.info.authority != null
7493 && (processName == null
7494 || (p.info.processName.equals(processName)
7495 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
7496 && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
7498 // See PM.queryContentProviders()'s javadoc for why we have the metaData
7500 if (metaDataKey != null
7501 && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
7505 if (finalList == null) {
7506 finalList = new ArrayList<ProviderInfo>(3);
7508 ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
7509 ps.readUserState(userId), userId);
7511 finalList.add(info);
7517 if (finalList != null) {
7518 Collections.sort(finalList, mProviderInitOrderSorter);
7519 return new ParceledListSlice<ProviderInfo>(finalList);
7522 return ParceledListSlice.emptyList();
7526 public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) {
7528 synchronized (mPackages) {
7529 final PackageParser.Instrumentation i = mInstrumentation.get(name);
7530 return PackageParser.generateInstrumentationInfo(i, flags);
7535 public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
7536 String targetPackage, int flags) {
7537 return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
7540 private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
7542 ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
7545 synchronized (mPackages) {
7546 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
7547 while (i.hasNext()) {
7548 final PackageParser.Instrumentation p = i.next();
7549 if (targetPackage == null
7550 || targetPackage.equals(p.info.targetPackage)) {
7551 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
7563 private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
7564 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + dir.getAbsolutePath() + "]");
7566 scanDirLI(dir, parseFlags, scanFlags, currentTime);
7568 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7572 private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
7573 final File[] files = dir.listFiles();
7574 if (ArrayUtils.isEmpty(files)) {
7575 Log.d(TAG, "No files in app dir " + dir);
7579 if (DEBUG_PACKAGE_SCANNING) {
7580 Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
7581 + " flags=0x" + Integer.toHexString(parseFlags));
7583 ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
7584 mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir, mPackageParserCallback);
7586 // Submit files for parsing in parallel
7588 for (File file : files) {
7589 final boolean isPackage = (isApkFile(file) || file.isDirectory())
7590 && !PackageInstallerService.isStageName(file.getName());
7592 // Ignore entries which are not packages
7595 parallelPackageParser.submit(file, parseFlags);
7599 // Process results one by one
7600 for (; fileCount > 0; fileCount--) {
7601 ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
7602 Throwable throwable = parseResult.throwable;
7603 int errorCode = PackageManager.INSTALL_SUCCEEDED;
7605 if (throwable == null) {
7606 // Static shared libraries have synthetic package names
7607 if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
7608 renameStaticSharedLibraryPackage(parseResult.pkg);
7611 if (errorCode == PackageManager.INSTALL_SUCCEEDED) {
7612 scanPackageLI(parseResult.pkg, parseResult.scanFile, parseFlags, scanFlags,
7615 } catch (PackageManagerException e) {
7616 errorCode = e.error;
7617 Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
7619 } else if (throwable instanceof PackageParser.PackageParserException) {
7620 PackageParser.PackageParserException e = (PackageParser.PackageParserException)
7622 errorCode = e.error;
7623 Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
7625 throw new IllegalStateException("Unexpected exception occurred while parsing "
7626 + parseResult.scanFile, throwable);
7629 // Delete invalid userdata apps
7630 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
7631 errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) {
7632 logCriticalInfo(Log.WARN,
7633 "Deleting invalid package at " + parseResult.scanFile);
7634 removeCodePathLI(parseResult.scanFile);
7637 parallelPackageParser.close();
7640 private static File getSettingsProblemFile() {
7641 File dataDir = Environment.getDataDirectory();
7642 File systemDir = new File(dataDir, "system");
7643 File fname = new File(systemDir, "uiderrors.txt");
7647 static void reportSettingsProblem(int priority, String msg) {
7648 logCriticalInfo(priority, msg);
7651 public static void logCriticalInfo(int priority, String msg) {
7652 Slog.println(priority, TAG, msg);
7653 EventLogTags.writePmCriticalInfo(msg);
7655 File fname = getSettingsProblemFile();
7656 FileOutputStream out = new FileOutputStream(fname, true);
7657 PrintWriter pw = new FastPrintWriter(out);
7658 SimpleDateFormat formatter = new SimpleDateFormat();
7659 String dateString = formatter.format(new Date(System.currentTimeMillis()));
7660 pw.println(dateString + ": " + msg);
7662 FileUtils.setPermissions(
7664 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
7666 } catch (java.io.IOException e) {
7670 private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) {
7671 if (srcFile.isDirectory()) {
7672 final File baseFile = new File(pkg.baseCodePath);
7673 long maxModifiedTime = baseFile.lastModified();
7674 if (pkg.splitCodePaths != null) {
7675 for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) {
7676 final File splitFile = new File(pkg.splitCodePaths[i]);
7677 maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified());
7680 return maxModifiedTime;
7682 return srcFile.lastModified();
7685 private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile,
7686 final int policyFlags) throws PackageManagerException {
7687 // When upgrading from pre-N MR1, verify the package time stamp using the package
7688 // directory and not the APK file.
7689 final long lastModifiedTime = mIsPreNMR1Upgrade
7690 ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg, srcFile);
7692 && ps.codePath.equals(srcFile)
7693 && ps.timeStamp == lastModifiedTime
7694 && !isCompatSignatureUpdateNeeded(pkg)
7695 && !isRecoverSignatureUpdateNeeded(pkg)) {
7696 long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
7697 KeySetManagerService ksms = mSettings.mKeySetManagerService;
7698 ArraySet<PublicKey> signingKs;
7699 synchronized (mPackages) {
7700 signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
7702 if (ps.signatures.mSignatures != null
7703 && ps.signatures.mSignatures.length != 0
7704 && signingKs != null) {
7705 // Optimization: reuse the existing cached certificates
7706 // if the package appears to be unchanged.
7707 pkg.mSignatures = ps.signatures.mSignatures;
7708 pkg.mSigningKeys = signingKs;
7712 Slog.w(TAG, "PackageSetting for " + ps.name
7713 + " is missing signatures. Collecting certs again to recover them.");
7715 Slog.i(TAG, srcFile.toString() + " changed; collecting certs");
7719 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
7720 PackageParser.collectCertificates(pkg, policyFlags);
7721 } catch (PackageParserException e) {
7722 throw PackageManagerException.from(e);
7724 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7729 * Traces a package scan.
7730 * @see #scanPackageLI(File, int, int, long, UserHandle)
7732 private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
7733 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
7734 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
7736 return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
7738 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7743 * Scans a package and returns the newly parsed package.
7744 * Returns {@code null} in case of errors and the error code is stored in mLastScanError
7746 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
7747 long currentTime, UserHandle user) throws PackageManagerException {
7748 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
7749 PackageParser pp = new PackageParser();
7750 pp.setSeparateProcesses(mSeparateProcesses);
7751 pp.setOnlyCoreApps(mOnlyCore);
7752 pp.setDisplayMetrics(mMetrics);
7753 pp.setCallback(mPackageParserCallback);
7755 if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
7756 parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
7759 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
7760 final PackageParser.Package pkg;
7762 pkg = pp.parsePackage(scanFile, parseFlags);
7763 } catch (PackageParserException e) {
7764 throw PackageManagerException.from(e);
7766 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7769 // Static shared libraries have synthetic package names
7770 if (pkg.applicationInfo.isStaticSharedLibrary()) {
7771 renameStaticSharedLibraryPackage(pkg);
7774 return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
7778 * Scans a package and returns the newly parsed package.
7779 * @throws PackageManagerException on a parse error.
7781 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile,
7782 final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
7783 throws PackageManagerException {
7784 // If the package has children and this is the first dive in the function
7785 // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
7786 // packages (parent and children) would be successfully scanned before the
7787 // actual scan since scanning mutates internal state and we want to atomically
7788 // install the package and its children.
7789 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
7790 if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
7791 scanFlags |= SCAN_CHECK_ONLY;
7794 scanFlags &= ~SCAN_CHECK_ONLY;
7798 PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags,
7799 scanFlags, currentTime, user);
7801 // Scan the children
7802 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
7803 for (int i = 0; i < childCount; i++) {
7804 PackageParser.Package childPackage = pkg.childPackages.get(i);
7805 scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags,
7810 if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
7811 return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user);
7818 * Scans a package and returns the newly parsed package.
7819 * @throws PackageManagerException on a parse error.
7821 private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile,
7822 int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
7823 throws PackageManagerException {
7824 PackageSetting ps = null;
7825 PackageSetting updatedPkg;
7827 synchronized (mPackages) {
7828 // Look to see if we already know about this package.
7829 String oldName = mSettings.getRenamedPackageLPr(pkg.packageName);
7830 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
7831 // This package has been renamed to its original name. Let's
7833 ps = mSettings.getPackageLPr(oldName);
7835 // If there was no original package, see one for the real package name.
7837 ps = mSettings.getPackageLPr(pkg.packageName);
7839 // Check to see if this package could be hiding/updating a system
7840 // package. Must look for it either under the original or real
7841 // package name depending on our state.
7842 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
7843 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
7845 // If this is a package we don't know about on the system partition, we
7846 // may need to remove disabled child packages on the system partition
7847 // or may need to not add child packages if the parent apk is updated
7848 // on the data partition and no longer defines this child package.
7849 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
7850 // If this is a parent package for an updated system app and this system
7851 // app got an OTA update which no longer defines some of the child packages
7852 // we have to prune them from the disabled system packages.
7853 PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
7854 if (disabledPs != null) {
7855 final int scannedChildCount = (pkg.childPackages != null)
7856 ? pkg.childPackages.size() : 0;
7857 final int disabledChildCount = disabledPs.childPackageNames != null
7858 ? disabledPs.childPackageNames.size() : 0;
7859 for (int i = 0; i < disabledChildCount; i++) {
7860 String disabledChildPackageName = disabledPs.childPackageNames.get(i);
7861 boolean disabledPackageAvailable = false;
7862 for (int j = 0; j < scannedChildCount; j++) {
7863 PackageParser.Package childPkg = pkg.childPackages.get(j);
7864 if (childPkg.packageName.equals(disabledChildPackageName)) {
7865 disabledPackageAvailable = true;
7869 if (!disabledPackageAvailable) {
7870 mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
7877 boolean updatedPkgBetter = false;
7878 // First check if this is a system package that may involve an update
7879 if (updatedPkg != null && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
7880 // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
7881 // it needs to drop FLAG_PRIVILEGED.
7882 if (locationIsPrivileged(scanFile)) {
7883 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
7885 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
7888 if (ps != null && !ps.codePath.equals(scanFile)) {
7889 // The path has changed from what was last scanned... check the
7890 // version of the new path against what we have stored to determine
7892 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
7893 if (pkg.mVersionCode <= ps.versionCode) {
7894 // The system package has been updated and the code path does not match
7895 // Ignore entry. Skip it.
7896 if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile
7897 + " ignored: updated version " + ps.versionCode
7898 + " better than this " + pkg.mVersionCode);
7899 if (!updatedPkg.codePath.equals(scanFile)) {
7900 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
7901 + ps.name + " changing from " + updatedPkg.codePathString
7902 + " to " + scanFile);
7903 updatedPkg.codePath = scanFile;
7904 updatedPkg.codePathString = scanFile.toString();
7905 updatedPkg.resourcePath = scanFile;
7906 updatedPkg.resourcePathString = scanFile.toString();
7908 updatedPkg.pkg = pkg;
7909 updatedPkg.versionCode = pkg.mVersionCode;
7911 // Update the disabled system child packages to point to the package too.
7912 final int childCount = updatedPkg.childPackageNames != null
7913 ? updatedPkg.childPackageNames.size() : 0;
7914 for (int i = 0; i < childCount; i++) {
7915 String childPackageName = updatedPkg.childPackageNames.get(i);
7916 PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr(
7918 if (updatedChildPkg != null) {
7919 updatedChildPkg.pkg = pkg;
7920 updatedChildPkg.versionCode = pkg.mVersionCode;
7924 throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
7925 + scanFile + " ignored: updated version " + ps.versionCode
7926 + " better than this " + pkg.mVersionCode);
7928 // The current app on the system partition is better than
7929 // what we have updated to on the data partition; switch
7930 // back to the system partition version.
7931 // At this point, its safely assumed that package installation for
7932 // apps in system partition will go through. If not there won't be a working
7933 // version of the app
7935 synchronized (mPackages) {
7936 // Just remove the loaded entries from package lists.
7937 mPackages.remove(ps.name);
7940 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
7941 + " reverting from " + ps.codePathString
7942 + ": new version " + pkg.mVersionCode
7943 + " better than installed " + ps.versionCode);
7945 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
7946 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
7947 synchronized (mInstallLock) {
7948 args.cleanUpResourcesLI();
7950 synchronized (mPackages) {
7951 mSettings.enableSystemPackageLPw(ps.name);
7953 updatedPkgBetter = true;
7958 if (updatedPkg != null) {
7959 // An updated system app will not have the PARSE_IS_SYSTEM flag set
7961 policyFlags |= PackageParser.PARSE_IS_SYSTEM;
7963 // An updated privileged app will not have the PARSE_IS_PRIVILEGED
7964 // flag set initially
7965 if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
7966 policyFlags |= PackageParser.PARSE_IS_PRIVILEGED;
7970 // Verify certificates against what was last scanned
7971 collectCertificatesLI(ps, pkg, scanFile, policyFlags);
7974 * A new system app appeared, but we already had a non-system one of the
7975 * same name installed earlier.
7977 boolean shouldHideSystemApp = false;
7978 if (updatedPkg == null && ps != null
7979 && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
7981 * Check to make sure the signatures match first. If they don't,
7982 * wipe the installed application and its data.
7984 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
7985 != PackageManager.SIGNATURE_MATCH) {
7986 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
7987 + " signatures don't match existing userdata copy; removing");
7988 try (PackageFreezer freezer = freezePackage(pkg.packageName,
7989 "scanPackageInternalLI")) {
7990 deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
7995 * If the newly-added system app is an older version than the
7996 * already installed version, hide it. It will be scanned later
7997 * and re-added like an update.
7999 if (pkg.mVersionCode <= ps.versionCode) {
8000 shouldHideSystemApp = true;
8001 logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
8002 + " but new version " + pkg.mVersionCode + " better than installed "
8003 + ps.versionCode + "; hiding system");
8006 * The newly found system app is a newer version that the
8007 * one previously installed. Simply remove the
8008 * already-installed application and replace it with our own
8009 * while keeping the application data.
8011 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
8012 + " reverting from " + ps.codePathString + ": new version "
8013 + pkg.mVersionCode + " better than installed " + ps.versionCode);
8014 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
8015 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
8016 synchronized (mInstallLock) {
8017 args.cleanUpResourcesLI();
8023 // The apk is forward locked (not public) if its code and resources
8024 // are kept in different files. (except for app in either system or
8026 // TODO grab this value from PackageSettings
8027 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
8028 if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
8029 policyFlags |= PackageParser.PARSE_FORWARD_LOCK;
8033 // TODO: extend to support forward-locked splits
8034 String resourcePath = null;
8035 String baseResourcePath = null;
8036 if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
8037 if (ps != null && ps.resourcePathString != null) {
8038 resourcePath = ps.resourcePathString;
8039 baseResourcePath = ps.resourcePathString;
8041 // Should not happen at all. Just log an error.
8042 Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
8045 resourcePath = pkg.codePath;
8046 baseResourcePath = pkg.baseCodePath;
8049 // Set application objects path explicitly.
8050 pkg.setApplicationVolumeUuid(pkg.volumeUuid);
8051 pkg.setApplicationInfoCodePath(pkg.codePath);
8052 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
8053 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
8054 pkg.setApplicationInfoResourcePath(resourcePath);
8055 pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
8056 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
8058 final int userId = ((user == null) ? 0 : user.getIdentifier());
8059 if (ps != null && ps.getInstantApp(userId)) {
8060 scanFlags |= SCAN_AS_INSTANT_APP;
8063 // Note that we invoke the following method only if we are about to unpack an application
8064 PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags
8065 | SCAN_UPDATE_SIGNATURE, currentTime, user);
8068 * If the system app should be overridden by a previously installed
8069 * data, hide the system app now and let the /data/app scan pick it up
8072 if (shouldHideSystemApp) {
8073 synchronized (mPackages) {
8074 mSettings.disableSystemPackageLPw(pkg.packageName, true);
8081 private void renameStaticSharedLibraryPackage(PackageParser.Package pkg) {
8082 // Derive the new package synthetic package name
8083 pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER
8084 + pkg.staticSharedLibVersion);
8087 private static String fixProcessName(String defProcessName,
8088 String processName) {
8089 if (processName == null) {
8090 return defProcessName;
8095 private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
8096 throws PackageManagerException {
8097 if (pkgSetting.signatures.mSignatures != null) {
8098 // Already existing package. Make sure signatures match
8099 boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
8100 == PackageManager.SIGNATURE_MATCH;
8102 match = compareSignaturesCompat(pkgSetting.signatures, pkg)
8103 == PackageManager.SIGNATURE_MATCH;
8106 match = compareSignaturesRecover(pkgSetting.signatures, pkg)
8107 == PackageManager.SIGNATURE_MATCH;
8110 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
8111 + pkg.packageName + " signatures do not match the "
8112 + "previously installed version; ignoring!");
8116 // Check for shared user signatures
8117 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
8118 // Already existing package. Make sure signatures match
8119 boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
8120 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
8122 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
8123 == PackageManager.SIGNATURE_MATCH;
8126 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
8127 == PackageManager.SIGNATURE_MATCH;
8130 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
8131 "Package " + pkg.packageName
8132 + " has no signatures that match those in shared user "
8133 + pkgSetting.sharedUser.name + "; ignoring!");
8139 * Enforces that only the system UID or root's UID can call a method exposed
8142 * @param message used as message if SecurityException is thrown
8143 * @throws SecurityException if the caller is not system or root
8145 private static final void enforceSystemOrRoot(String message) {
8146 final int uid = Binder.getCallingUid();
8147 if (uid != Process.SYSTEM_UID && uid != 0) {
8148 throw new SecurityException(message);
8153 public void performFstrimIfNeeded() {
8154 enforceSystemOrRoot("Only the system can request fstrim");
8156 // Before everything else, see whether we need to fstrim.
8158 IStorageManager sm = PackageHelper.getStorageManager();
8160 boolean doTrim = false;
8161 final long interval = android.provider.Settings.Global.getLong(
8162 mContext.getContentResolver(),
8163 android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
8164 DEFAULT_MANDATORY_FSTRIM_INTERVAL);
8166 final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
8167 if (timeSinceLast > interval) {
8169 Slog.w(TAG, "No disk maintenance in " + timeSinceLast
8170 + "; running immediately");
8174 final boolean dexOptDialogShown;
8175 synchronized (mPackages) {
8176 dexOptDialogShown = mDexOptDialogShown;
8178 if (!isFirstBoot() && dexOptDialogShown) {
8180 ActivityManager.getService().showBootMessage(
8181 mContext.getResources().getString(
8182 R.string.android_upgrading_fstrim), true);
8183 } catch (RemoteException e) {
8186 sm.runMaintenance();
8189 Slog.e(TAG, "storageManager service unavailable!");
8191 } catch (RemoteException e) {
8192 // Can't happen; StorageManagerService is local
8197 public void updatePackagesIfNeeded() {
8198 enforceSystemOrRoot("Only the system can request package update");
8200 // We need to re-extract after an OTA.
8201 boolean causeUpgrade = isUpgrade();
8203 // First boot or factory reset.
8204 // Note: we also handle devices that are upgrading to N right now as if it is their
8205 // first boot, as they do not have profile data.
8206 boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
8208 // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
8209 boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
8211 if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
8215 List<PackageParser.Package> pkgs;
8216 synchronized (mPackages) {
8217 pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
8220 final long startTime = System.nanoTime();
8221 final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
8222 getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT));
8224 final int elapsedTimeSeconds =
8225 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
8227 MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
8228 MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
8229 MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
8230 MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
8231 MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
8235 * Performs dexopt on the set of packages in {@code packages} and returns an int array
8236 * containing statistics about the invocation. The array consists of three elements,
8237 * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
8238 * and {@code numberOfPackagesFailed}.
8240 private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
8241 String compilerFilter) {
8243 int numberOfPackagesVisited = 0;
8244 int numberOfPackagesOptimized = 0;
8245 int numberOfPackagesSkipped = 0;
8246 int numberOfPackagesFailed = 0;
8247 final int numberOfPackagesToDexopt = pkgs.size();
8249 for (PackageParser.Package pkg : pkgs) {
8250 numberOfPackagesVisited++;
8252 if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
8254 Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
8256 numberOfPackagesSkipped++;
8261 Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
8262 numberOfPackagesToDexopt + ": " + pkg.packageName);
8267 ActivityManager.getService().showBootMessage(
8268 mContext.getResources().getString(R.string.android_upgrading_apk,
8269 numberOfPackagesVisited, numberOfPackagesToDexopt), true);
8270 } catch (RemoteException e) {
8272 synchronized (mPackages) {
8273 mDexOptDialogShown = true;
8277 // If the OTA updates a system app which was previously preopted to a non-preopted state
8278 // the app might end up being verified at runtime. That's because by default the apps
8279 // are verify-profile but for preopted apps there's no profile.
8280 // Do a hacky check to ensure that if we have no profiles (a reasonable indication
8281 // that before the OTA the app was preopted) the app gets compiled with a non-profile
8282 // filter (by default interpret-only).
8283 // Note that at this stage unused apps are already filtered.
8284 if (isSystemApp(pkg) &&
8285 DexFile.isProfileGuidedCompilerFilter(compilerFilter) &&
8286 !Environment.getReferenceProfile(pkg.packageName).exists()) {
8287 compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter);
8290 // checkProfiles is false to avoid merging profiles during boot which
8291 // might interfere with background compilation (b/28612421).
8292 // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
8293 // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
8294 // trade-off worth doing to save boot time work.
8295 int dexOptStatus = performDexOptTraced(pkg.packageName,
8296 false /* checkProfiles */,
8299 switch (dexOptStatus) {
8300 case PackageDexOptimizer.DEX_OPT_PERFORMED:
8301 numberOfPackagesOptimized++;
8303 case PackageDexOptimizer.DEX_OPT_SKIPPED:
8304 numberOfPackagesSkipped++;
8306 case PackageDexOptimizer.DEX_OPT_FAILED:
8307 numberOfPackagesFailed++;
8310 Log.e(TAG, "Unexpected dexopt return code " + dexOptStatus);
8315 return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
8316 numberOfPackagesFailed };
8320 public void notifyPackageUse(String packageName, int reason) {
8321 synchronized (mPackages) {
8322 PackageParser.Package p = mPackages.get(packageName);
8326 p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
8331 public void notifyDexLoad(String loadingPackageName, List<String> dexPaths, String loaderIsa) {
8332 int userId = UserHandle.getCallingUserId();
8333 ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
8335 Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
8336 + loadingPackageName + ", user=" + userId);
8339 mDexManager.notifyDexLoad(ai, dexPaths, loaderIsa, userId);
8342 // TODO: this is not used nor needed. Delete it.
8344 public boolean performDexOptIfNeeded(String packageName) {
8345 int dexOptStatus = performDexOptTraced(packageName,
8346 false /* checkProfiles */, getFullCompilerFilter(), false /* force */);
8347 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
8351 public boolean performDexOpt(String packageName,
8352 boolean checkProfiles, int compileReason, boolean force) {
8353 int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
8354 getCompilerFilterForReason(compileReason), force);
8355 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
8359 public boolean performDexOptMode(String packageName,
8360 boolean checkProfiles, String targetCompilerFilter, boolean force) {
8361 int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
8362 targetCompilerFilter, force);
8363 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
8366 private int performDexOptTraced(String packageName,
8367 boolean checkProfiles, String targetCompilerFilter, boolean force) {
8368 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
8370 return performDexOptInternal(packageName, checkProfiles,
8371 targetCompilerFilter, force);
8373 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8377 // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
8378 // if the package can now be considered up to date for the given filter.
8379 private int performDexOptInternal(String packageName,
8380 boolean checkProfiles, String targetCompilerFilter, boolean force) {
8381 PackageParser.Package p;
8382 synchronized (mPackages) {
8383 p = mPackages.get(packageName);
8385 // Package could not be found. Report failure.
8386 return PackageDexOptimizer.DEX_OPT_FAILED;
8388 mPackageUsage.maybeWriteAsync(mPackages);
8389 mCompilerStats.maybeWriteAsync();
8391 long callingId = Binder.clearCallingIdentity();
8393 synchronized (mInstallLock) {
8394 return performDexOptInternalWithDependenciesLI(p, checkProfiles,
8395 targetCompilerFilter, force);
8398 Binder.restoreCallingIdentity(callingId);
8402 public ArraySet<String> getOptimizablePackages() {
8403 ArraySet<String> pkgs = new ArraySet<String>();
8404 synchronized (mPackages) {
8405 for (PackageParser.Package p : mPackages.values()) {
8406 if (PackageDexOptimizer.canOptimizePackage(p)) {
8407 pkgs.add(p.packageName);
8414 private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
8415 boolean checkProfiles, String targetCompilerFilter,
8417 // Select the dex optimizer based on the force parameter.
8418 // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
8419 // allocate an object here.
8420 PackageDexOptimizer pdo = force
8421 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
8422 : mPackageDexOptimizer;
8424 // Dexopt all dependencies first. Note: we ignore the return value and march on
8426 // Note that we are going to call performDexOpt on those libraries as many times as
8427 // they are referenced in packages. When we do a batch of performDexOpt (for example
8428 // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
8429 // and the first package that uses the library will dexopt it. The
8430 // others will see that the compiled code for the library is up to date.
8431 Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
8432 final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
8433 if (!deps.isEmpty()) {
8434 for (PackageParser.Package depPackage : deps) {
8435 // TODO: Analyze and investigate if we (should) profile libraries.
8436 pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
8437 false /* checkProfiles */,
8438 targetCompilerFilter,
8439 getOrCreateCompilerPackageStats(depPackage),
8440 true /* isUsedByOtherApps */);
8443 return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles,
8444 targetCompilerFilter, getOrCreateCompilerPackageStats(p),
8445 mDexManager.isUsedByOtherApps(p.packageName));
8448 // Performs dexopt on the used secondary dex files belonging to the given package.
8449 // Returns true if all dex files were process successfully (which could mean either dexopt or
8450 // skip). Returns false if any of the files caused errors.
8452 public boolean performDexOptSecondary(String packageName, String compilerFilter,
8454 return mDexManager.dexoptSecondaryDex(packageName, compilerFilter, force);
8457 public boolean performDexOptSecondary(String packageName, int compileReason,
8459 return mDexManager.dexoptSecondaryDex(packageName, compileReason, force);
8463 * Reconcile the information we have about the secondary dex files belonging to
8464 * {@code packagName} and the actual dex files. For all dex files that were
8465 * deleted, update the internal records and delete the generated oat files.
8468 public void reconcileSecondaryDexFiles(String packageName) {
8469 mDexManager.reconcileSecondaryDexFiles(packageName);
8472 // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
8473 // a reference there.
8474 /*package*/ DexManager getDexManager() {
8479 * Execute the background dexopt job immediately.
8482 public boolean runBackgroundDexoptJob() {
8483 return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext);
8486 List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
8487 if (p.usesLibraries != null || p.usesOptionalLibraries != null
8488 || p.usesStaticLibraries != null) {
8489 ArrayList<PackageParser.Package> retValue = new ArrayList<>();
8490 Set<String> collectedNames = new HashSet<>();
8491 findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
8497 return Collections.emptyList();
8501 private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
8502 ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
8503 if (!collectedNames.contains(p.packageName)) {
8504 collectedNames.add(p.packageName);
8507 if (p.usesLibraries != null) {
8508 findSharedNonSystemLibrariesRecursive(p.usesLibraries,
8509 null, collected, collectedNames);
8511 if (p.usesOptionalLibraries != null) {
8512 findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries,
8513 null, collected, collectedNames);
8515 if (p.usesStaticLibraries != null) {
8516 findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries,
8517 p.usesStaticLibrariesVersions, collected, collectedNames);
8522 private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, int[] versions,
8523 ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
8524 final int libNameCount = libs.size();
8525 for (int i = 0; i < libNameCount; i++) {
8526 String libName = libs.get(i);
8527 int version = (versions != null && versions.length == libNameCount)
8528 ? versions[i] : PackageManager.VERSION_CODE_HIGHEST;
8529 PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version);
8530 if (libPkg != null) {
8531 findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
8536 private PackageParser.Package findSharedNonSystemLibrary(String name, int version) {
8537 synchronized (mPackages) {
8538 SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version);
8539 if (libEntry != null) {
8540 return mPackages.get(libEntry.apk);
8546 private SharedLibraryEntry getSharedLibraryEntryLPr(String name, int version) {
8547 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
8548 if (versionedLib == null) {
8551 return versionedLib.get(version);
8554 private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
8555 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
8556 pkg.staticSharedLibName);
8557 if (versionedLib == null) {
8560 int previousLibVersion = -1;
8561 final int versionCount = versionedLib.size();
8562 for (int i = 0; i < versionCount; i++) {
8563 final int libVersion = versionedLib.keyAt(i);
8564 if (libVersion < pkg.staticSharedLibVersion) {
8565 previousLibVersion = Math.max(previousLibVersion, libVersion);
8568 if (previousLibVersion >= 0) {
8569 return versionedLib.get(previousLibVersion);
8574 public void shutdown() {
8575 mPackageUsage.writeNow(mPackages);
8576 mCompilerStats.writeNow();
8580 public void dumpProfiles(String packageName) {
8581 PackageParser.Package pkg;
8582 synchronized (mPackages) {
8583 pkg = mPackages.get(packageName);
8585 throw new IllegalArgumentException("Unknown package: " + packageName);
8588 /* Only the shell, root, or the app user should be able to dump profiles. */
8589 int callingUid = Binder.getCallingUid();
8590 if (callingUid != Process.SHELL_UID &&
8591 callingUid != Process.ROOT_UID &&
8592 callingUid != pkg.applicationInfo.uid) {
8593 throw new SecurityException("dumpProfiles");
8596 synchronized (mInstallLock) {
8597 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
8598 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
8600 List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
8601 String codePaths = TextUtils.join(";", allCodePaths);
8602 mInstaller.dumpProfiles(sharedGid, packageName, codePaths);
8603 } catch (InstallerException e) {
8604 Slog.w(TAG, "Failed to dump profiles", e);
8606 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8611 public void forceDexOpt(String packageName) {
8612 enforceSystemOrRoot("forceDexOpt");
8614 PackageParser.Package pkg;
8615 synchronized (mPackages) {
8616 pkg = mPackages.get(packageName);
8618 throw new IllegalArgumentException("Unknown package: " + packageName);
8622 synchronized (mInstallLock) {
8623 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
8625 // Whoever is calling forceDexOpt wants a fully compiled package.
8626 // Don't use profiles since that may cause compilation to be skipped.
8627 final int res = performDexOptInternalWithDependenciesLI(pkg,
8628 false /* checkProfiles */, getCompilerFilterForReason(REASON_FORCED_DEXOPT),
8631 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8632 if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
8633 throw new IllegalStateException("Failed to dexopt: " + res);
8638 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
8639 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8640 Slog.w(TAG, "Unable to update from " + oldPkg.name
8641 + " to " + newPkg.packageName
8642 + ": old package not in system partition");
8644 } else if (mPackages.get(oldPkg.name) != null) {
8645 Slog.w(TAG, "Unable to update from " + oldPkg.name
8646 + " to " + newPkg.packageName
8647 + ": old package still exists");
8653 void removeCodePathLI(File codePath) {
8654 if (codePath.isDirectory()) {
8656 mInstaller.rmPackageDir(codePath.getAbsolutePath());
8657 } catch (InstallerException e) {
8658 Slog.w(TAG, "Failed to remove code path", e);
8665 private int[] resolveUserIds(int userId) {
8666 return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
8669 private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
8671 Slog.wtf(TAG, "Package was null!", new Throwable());
8674 clearAppDataLeafLIF(pkg, userId, flags);
8675 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8676 for (int i = 0; i < childCount; i++) {
8677 clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
8681 private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
8682 final PackageSetting ps;
8683 synchronized (mPackages) {
8684 ps = mSettings.mPackages.get(pkg.packageName);
8686 for (int realUserId : resolveUserIds(userId)) {
8687 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
8689 mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
8691 } catch (InstallerException e) {
8692 Slog.w(TAG, String.valueOf(e));
8697 private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
8699 Slog.wtf(TAG, "Package was null!", new Throwable());
8702 destroyAppDataLeafLIF(pkg, userId, flags);
8703 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8704 for (int i = 0; i < childCount; i++) {
8705 destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
8709 private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
8710 final PackageSetting ps;
8711 synchronized (mPackages) {
8712 ps = mSettings.mPackages.get(pkg.packageName);
8714 for (int realUserId : resolveUserIds(userId)) {
8715 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
8717 mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
8719 } catch (InstallerException e) {
8720 Slog.w(TAG, String.valueOf(e));
8722 mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
8726 private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
8728 Slog.wtf(TAG, "Package was null!", new Throwable());
8731 destroyAppProfilesLeafLIF(pkg);
8732 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8733 for (int i = 0; i < childCount; i++) {
8734 destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
8738 private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
8740 mInstaller.destroyAppProfiles(pkg.packageName);
8741 } catch (InstallerException e) {
8742 Slog.w(TAG, String.valueOf(e));
8746 private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
8748 Slog.wtf(TAG, "Package was null!", new Throwable());
8751 clearAppProfilesLeafLIF(pkg);
8752 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8753 for (int i = 0; i < childCount; i++) {
8754 clearAppProfilesLeafLIF(pkg.childPackages.get(i));
8758 private void clearAppProfilesLeafLIF(PackageParser.Package pkg) {
8760 mInstaller.clearAppProfiles(pkg.packageName);
8761 } catch (InstallerException e) {
8762 Slog.w(TAG, String.valueOf(e));
8766 private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
8767 long lastUpdateTime) {
8768 // Set parent install/update time
8769 PackageSetting ps = (PackageSetting) pkg.mExtras;
8771 ps.firstInstallTime = firstInstallTime;
8772 ps.lastUpdateTime = lastUpdateTime;
8774 // Set children install/update time
8775 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8776 for (int i = 0; i < childCount; i++) {
8777 PackageParser.Package childPkg = pkg.childPackages.get(i);
8778 ps = (PackageSetting) childPkg.mExtras;
8780 ps.firstInstallTime = firstInstallTime;
8781 ps.lastUpdateTime = lastUpdateTime;
8786 private void addSharedLibraryLPr(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
8787 PackageParser.Package changingLib) {
8788 if (file.path != null) {
8789 usesLibraryFiles.add(file.path);
8792 PackageParser.Package p = mPackages.get(file.apk);
8793 if (changingLib != null && changingLib.packageName.equals(file.apk)) {
8794 // If we are doing this while in the middle of updating a library apk,
8795 // then we need to make sure to use that new apk for determining the
8796 // dependencies here. (We haven't yet finished committing the new apk
8797 // to the package manager state.)
8798 if (p == null || p.packageName.equals(changingLib.packageName)) {
8803 usesLibraryFiles.addAll(p.getAllCodePaths());
8807 private void updateSharedLibrariesLPr(PackageParser.Package pkg,
8808 PackageParser.Package changingLib) throws PackageManagerException {
8812 ArraySet<String> usesLibraryFiles = null;
8813 if (pkg.usesLibraries != null) {
8814 usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries,
8815 null, null, pkg.packageName, changingLib, true, null);
8817 if (pkg.usesStaticLibraries != null) {
8818 usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries,
8819 pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests,
8820 pkg.packageName, changingLib, true, usesLibraryFiles);
8822 if (pkg.usesOptionalLibraries != null) {
8823 usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries,
8824 null, null, pkg.packageName, changingLib, false, usesLibraryFiles);
8826 if (!ArrayUtils.isEmpty(usesLibraryFiles)) {
8827 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
8829 pkg.usesLibraryFiles = null;
8833 private ArraySet<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
8834 @Nullable int[] requiredVersions, @Nullable String[] requiredCertDigests,
8835 @NonNull String packageName, @Nullable PackageParser.Package changingLib,
8836 boolean required, @Nullable ArraySet<String> outUsedLibraries)
8837 throws PackageManagerException {
8838 final int libCount = requestedLibraries.size();
8839 for (int i = 0; i < libCount; i++) {
8840 final String libName = requestedLibraries.get(i);
8841 final int libVersion = requiredVersions != null ? requiredVersions[i]
8842 : SharedLibraryInfo.VERSION_UNDEFINED;
8843 final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion);
8844 if (libEntry == null) {
8846 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
8847 "Package " + packageName + " requires unavailable shared library "
8848 + libName + "; failing!");
8850 Slog.w(TAG, "Package " + packageName
8851 + " desires unavailable shared library "
8852 + libName + "; ignoring!");
8855 if (requiredVersions != null && requiredCertDigests != null) {
8856 if (libEntry.info.getVersion() != requiredVersions[i]) {
8857 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
8858 "Package " + packageName + " requires unavailable static shared"
8859 + " library " + libName + " version "
8860 + libEntry.info.getVersion() + "; failing!");
8863 PackageParser.Package libPkg = mPackages.get(libEntry.apk);
8864 if (libPkg == null) {
8865 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
8866 "Package " + packageName + " requires unavailable static shared"
8867 + " library; failing!");
8870 String expectedCertDigest = requiredCertDigests[i];
8871 String libCertDigest = PackageUtils.computeCertSha256Digest(
8872 libPkg.mSignatures[0]);
8873 if (!libCertDigest.equalsIgnoreCase(expectedCertDigest)) {
8874 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
8875 "Package " + packageName + " requires differently signed" +
8876 " static shared library; failing!");
8880 if (outUsedLibraries == null) {
8881 outUsedLibraries = new ArraySet<>();
8883 addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib);
8886 return outUsedLibraries;
8889 private static boolean hasString(List<String> list, List<String> which) {
8893 for (int i=list.size()-1; i>=0; i--) {
8894 for (int j=which.size()-1; j>=0; j--) {
8895 if (which.get(j).equals(list.get(i))) {
8903 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
8904 PackageParser.Package changingPkg) {
8905 ArrayList<PackageParser.Package> res = null;
8906 for (PackageParser.Package pkg : mPackages.values()) {
8907 if (changingPkg != null
8908 && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
8909 && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
8910 && !ArrayUtils.contains(pkg.usesStaticLibraries,
8911 changingPkg.staticSharedLibName)) {
8915 res = new ArrayList<>();
8919 updateSharedLibrariesLPr(pkg, changingPkg);
8920 } catch (PackageManagerException e) {
8921 // If a system app update or an app and a required lib missing we
8922 // delete the package and for updated system apps keep the data as
8923 // it is better for the user to reinstall than to be in an limbo
8924 // state. Also libs disappearing under an app should never happen
8926 if (!pkg.isSystemApp() || pkg.isUpdatedSystemApp()) {
8927 final int flags = pkg.isUpdatedSystemApp()
8928 ? PackageManager.DELETE_KEEP_DATA : 0;
8929 deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
8930 flags , null, true, null);
8932 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
8939 * Derive the value of the {@code cpuAbiOverride} based on the provided
8940 * value and an optional stored value from the package settings.
8942 private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
8943 String cpuAbiOverride = null;
8945 if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
8946 cpuAbiOverride = null;
8947 } else if (abiOverride != null) {
8948 cpuAbiOverride = abiOverride;
8949 } else if (settings != null) {
8950 cpuAbiOverride = settings.cpuAbiOverrideString;
8953 return cpuAbiOverride;
8956 private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
8957 final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
8958 throws PackageManagerException {
8959 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
8960 // If the package has children and this is the first dive in the function
8961 // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
8962 // whether all packages (parent and children) would be successfully scanned
8963 // before the actual scan since scanning mutates internal state and we want
8964 // to atomically install the package and its children.
8965 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
8966 if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
8967 scanFlags |= SCAN_CHECK_ONLY;
8970 scanFlags &= ~SCAN_CHECK_ONLY;
8973 final PackageParser.Package scannedPkg;
8976 scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user);
8977 // Scan the children
8978 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8979 for (int i = 0; i < childCount; i++) {
8980 PackageParser.Package childPkg = pkg.childPackages.get(i);
8981 scanPackageLI(childPkg, policyFlags,
8982 scanFlags, currentTime, user);
8985 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8988 if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8989 return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user);
8995 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags,
8996 int scanFlags, long currentTime, @Nullable UserHandle user)
8997 throws PackageManagerException {
8998 boolean success = false;
9000 final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags,
9005 if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
9006 // DELETE_DATA_ON_FAILURES is only used by frozen paths
9007 destroyAppDataLIF(pkg, UserHandle.USER_ALL,
9008 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
9009 destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
9015 * Returns {@code true} if the given file contains code. Otherwise {@code false}.
9017 private static boolean apkHasCode(String fileName) {
9018 StrictJarFile jarFile = null;
9020 jarFile = new StrictJarFile(fileName,
9021 false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
9022 return jarFile.findEntry("classes.dex") != null;
9023 } catch (IOException ignore) {
9026 if (jarFile != null) {
9029 } catch (IOException ignore) {}
9035 * Enforces code policy for the package. This ensures that if an APK has
9036 * declared hasCode="true" in its manifest that the APK actually contains
9039 * @throws PackageManagerException If bytecode could not be found when it should exist
9041 private static void assertCodePolicy(PackageParser.Package pkg)
9042 throws PackageManagerException {
9043 final boolean shouldHaveCode =
9044 (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
9045 if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
9046 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
9047 "Package " + pkg.baseCodePath + " code is missing");
9050 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
9051 for (int i = 0; i < pkg.splitCodePaths.length; i++) {
9052 final boolean splitShouldHaveCode =
9053 (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
9054 if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
9055 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
9056 "Package " + pkg.splitCodePaths[i] + " code is missing");
9062 private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,
9063 final int policyFlags, final int scanFlags, long currentTime, @Nullable UserHandle user)
9064 throws PackageManagerException {
9065 if (DEBUG_PACKAGE_SCANNING) {
9066 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
9067 Log.d(TAG, "Scanning package " + pkg.packageName);
9070 applyPolicy(pkg, policyFlags);
9072 assertPackageIsValid(pkg, policyFlags, scanFlags);
9074 // Initialize package source and resource directories
9075 final File scanFile = new File(pkg.codePath);
9076 final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
9077 final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
9079 SharedUserSetting suid = null;
9080 PackageSetting pkgSetting = null;
9082 // Getting the package setting may have a side-effect, so if we
9083 // are only checking if scan would succeed, stash a copy of the
9084 // old setting to restore at the end.
9085 PackageSetting nonMutatedPs = null;
9087 // We keep references to the derived CPU Abis from settings in oder to reuse
9088 // them in the case where we're not upgrading or booting for the first time.
9089 String primaryCpuAbiFromSettings = null;
9090 String secondaryCpuAbiFromSettings = null;
9093 synchronized (mPackages) {
9094 if (pkg.mSharedUserId != null) {
9095 // SIDE EFFECTS; may potentially allocate a new shared user
9096 suid = mSettings.getSharedUserLPw(
9097 pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
9098 if (DEBUG_PACKAGE_SCANNING) {
9099 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
9100 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
9101 + "): packages=" + suid.packages);
9105 // Check if we are renaming from an original package name.
9106 PackageSetting origPackage = null;
9107 String realName = null;
9108 if (pkg.mOriginalPackages != null) {
9109 // This package may need to be renamed to a previously
9110 // installed name. Let's check on that...
9111 final String renamed = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
9112 if (pkg.mOriginalPackages.contains(renamed)) {
9113 // This package had originally been installed as the
9114 // original name, and we have already taken care of
9115 // transitioning to the new one. Just update the new
9116 // one to continue using the old name.
9117 realName = pkg.mRealPackage;
9118 if (!pkg.packageName.equals(renamed)) {
9119 // Callers into this function may have already taken
9120 // care of renaming the package; only do it here if
9121 // it is not already done.
9122 pkg.setPackageName(renamed);
9125 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
9126 if ((origPackage = mSettings.getPackageLPr(
9127 pkg.mOriginalPackages.get(i))) != null) {
9128 // We do have the package already installed under its
9129 // original name... should we use it?
9130 if (!verifyPackageUpdateLPr(origPackage, pkg)) {
9131 // New package is not compatible with original.
9134 } else if (origPackage.sharedUser != null) {
9135 // Make sure uid is compatible between packages.
9136 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
9137 Slog.w(TAG, "Unable to migrate data from " + origPackage.name
9138 + " to " + pkg.packageName + ": old uid "
9139 + origPackage.sharedUser.name
9140 + " differs from " + pkg.mSharedUserId);
9144 // TODO: Add case when shared user id is added [b/28144775]
9146 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
9147 + pkg.packageName + " to old name " + origPackage.name);
9155 if (mTransferedPackages.contains(pkg.packageName)) {
9156 Slog.w(TAG, "Package " + pkg.packageName
9157 + " was transferred to another, but its .apk remains");
9160 // See comments in nonMutatedPs declaration
9161 if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9162 PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
9163 if (foundPs != null) {
9164 nonMutatedPs = new PackageSetting(foundPs);
9168 if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) == 0) {
9169 PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
9170 if (foundPs != null) {
9171 primaryCpuAbiFromSettings = foundPs.primaryCpuAbiString;
9172 secondaryCpuAbiFromSettings = foundPs.secondaryCpuAbiString;
9176 pkgSetting = mSettings.getPackageLPr(pkg.packageName);
9177 if (pkgSetting != null && pkgSetting.sharedUser != suid) {
9178 PackageManagerService.reportSettingsProblem(Log.WARN,
9179 "Package " + pkg.packageName + " shared user changed from "
9180 + (pkgSetting.sharedUser != null
9181 ? pkgSetting.sharedUser.name : "<nothing>")
9183 + (suid != null ? suid.name : "<nothing>")
9184 + "; replacing with new");
9187 final PackageSetting oldPkgSetting =
9188 pkgSetting == null ? null : new PackageSetting(pkgSetting);
9189 final PackageSetting disabledPkgSetting =
9190 mSettings.getDisabledSystemPkgLPr(pkg.packageName);
9192 String[] usesStaticLibraries = null;
9193 if (pkg.usesStaticLibraries != null) {
9194 usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
9195 pkg.usesStaticLibraries.toArray(usesStaticLibraries);
9198 if (pkgSetting == null) {
9199 final String parentPackageName = (pkg.parentPackage != null)
9200 ? pkg.parentPackage.packageName : null;
9201 final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
9202 // REMOVE SharedUserSetting from method; update in a separate call
9203 pkgSetting = Settings.createNewSetting(pkg.packageName, origPackage,
9204 disabledPkgSetting, realName, suid, destCodeFile, destResourceFile,
9205 pkg.applicationInfo.nativeLibraryRootDir, pkg.applicationInfo.primaryCpuAbi,
9206 pkg.applicationInfo.secondaryCpuAbi, pkg.mVersionCode,
9207 pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, user,
9208 true /*allowInstall*/, instantApp, parentPackageName,
9209 pkg.getChildPackageNames(), UserManagerService.getInstance(),
9210 usesStaticLibraries, pkg.usesStaticLibrariesVersions);
9211 // SIDE EFFECTS; updates system state; move elsewhere
9212 if (origPackage != null) {
9213 mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name);
9215 mSettings.addUserToSettingLPw(pkgSetting);
9217 // REMOVE SharedUserSetting from method; update in a separate call.
9219 // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
9220 // secondaryCpuAbi are not known at this point so we always update them
9221 // to null here, only to reset them at a later point.
9222 Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, suid, destCodeFile,
9223 pkg.applicationInfo.nativeLibraryDir, pkg.applicationInfo.primaryCpuAbi,
9224 pkg.applicationInfo.secondaryCpuAbi, pkg.applicationInfo.flags,
9225 pkg.applicationInfo.privateFlags, pkg.getChildPackageNames(),
9226 UserManagerService.getInstance(), usesStaticLibraries,
9227 pkg.usesStaticLibrariesVersions);
9229 // SIDE EFFECTS; persists system state to files on disk; move elsewhere
9230 mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
9232 // SIDE EFFECTS; modifies system state; move elsewhere
9233 if (pkgSetting.origPackage != null) {
9234 // If we are first transitioning from an original package,
9235 // fix up the new package's name now. We need to do this after
9236 // looking up the package under its new name, so getPackageLP
9237 // can take care of fiddling things correctly.
9238 pkg.setPackageName(origPackage.name);
9240 // File a report about this.
9241 String msg = "New package " + pkgSetting.realName
9242 + " renamed to replace old package " + pkgSetting.name;
9243 reportSettingsProblem(Log.WARN, msg);
9245 // Make a note of it.
9246 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9247 mTransferedPackages.add(origPackage.name);
9250 // No longer need to retain this.
9251 pkgSetting.origPackage = null;
9254 // SIDE EFFECTS; modifies system state; move elsewhere
9255 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) {
9256 // Make a note of it.
9257 mTransferedPackages.add(pkg.packageName);
9260 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
9261 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
9264 if ((scanFlags & SCAN_BOOTING) == 0
9265 && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9266 // Check all shared libraries and map to their actual file path.
9267 // We only do this here for apps not on a system dir, because those
9268 // are the only ones that can fail an install due to this. We
9269 // will take care of the system apps by updating all of their
9270 // library paths after the scan is done. Also during the initial
9271 // scan don't update any libs as we do this wholesale after all
9272 // apps are scanned to avoid dependency based scanning.
9273 updateSharedLibrariesLPr(pkg, null);
9276 if (mFoundPolicyFile) {
9277 SELinuxMMAC.assignSeInfoValue(pkg);
9279 pkg.applicationInfo.uid = pkgSetting.appId;
9280 pkg.mExtras = pkgSetting;
9283 // Static shared libs have same package with different versions where
9284 // we internally use a synthetic package name to allow multiple versions
9285 // of the same package, therefore we need to compare signatures against
9286 // the package setting for the latest library version.
9287 PackageSetting signatureCheckPs = pkgSetting;
9288 if (pkg.applicationInfo.isStaticSharedLibrary()) {
9289 SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
9290 if (libraryEntry != null) {
9291 signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
9295 if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
9296 if (checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
9297 // We just determined the app is signed correctly, so bring
9298 // over the latest parsed certs.
9299 pkgSetting.signatures.mSignatures = pkg.mSignatures;
9301 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9302 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
9303 "Package " + pkg.packageName + " upgrade keys do not match the "
9304 + "previously installed version");
9306 pkgSetting.signatures.mSignatures = pkg.mSignatures;
9307 String msg = "System package " + pkg.packageName
9308 + " signature changed; retaining data.";
9309 reportSettingsProblem(Log.WARN, msg);
9314 // SIDE EFFECTS; compareSignaturesCompat() changes KeysetManagerService
9315 verifySignaturesLP(signatureCheckPs, pkg);
9316 // We just determined the app is signed correctly, so bring
9317 // over the latest parsed certs.
9318 pkgSetting.signatures.mSignatures = pkg.mSignatures;
9319 } catch (PackageManagerException e) {
9320 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9323 // The signature has changed, but this package is in the system
9324 // image... let's recover!
9325 pkgSetting.signatures.mSignatures = pkg.mSignatures;
9326 // However... if this package is part of a shared user, but it
9327 // doesn't match the signature of the shared user, let's fail.
9328 // What this means is that you can't change the signatures
9329 // associated with an overall shared user, which doesn't seem all
9330 // that unreasonable.
9331 if (signatureCheckPs.sharedUser != null) {
9332 if (compareSignatures(signatureCheckPs.sharedUser.signatures.mSignatures,
9333 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
9334 throw new PackageManagerException(
9335 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
9336 "Signature mismatch for shared user: "
9337 + pkgSetting.sharedUser);
9340 // File a report about this.
9341 String msg = "System package " + pkg.packageName
9342 + " signature changed; retaining data.";
9343 reportSettingsProblem(Log.WARN, msg);
9347 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
9348 // This package wants to adopt ownership of permissions from
9350 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
9351 final String origName = pkg.mAdoptPermissions.get(i);
9352 final PackageSetting orig = mSettings.getPackageLPr(origName);
9354 if (verifyPackageUpdateLPr(orig, pkg)) {
9355 Slog.i(TAG, "Adopting permissions from " + origName + " to "
9357 // SIDE EFFECTS; updates permissions system state; move elsewhere
9358 mSettings.transferPermissionsLPw(origName, pkg.packageName);
9365 pkg.applicationInfo.processName = fixProcessName(
9366 pkg.applicationInfo.packageName,
9367 pkg.applicationInfo.processName);
9369 if (pkg != mPlatformPackage) {
9370 // Get all of our default paths setup
9371 pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
9374 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
9376 if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
9377 if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) {
9378 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
9380 pkg, scanFile, cpuAbiOverride, true /*extractLibs*/, mAppLib32InstallDir);
9381 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9383 // Some system apps still use directory structure for native libraries
9384 // in which case we might end up not detecting abi solely based on apk
9385 // structure. Try to detect abi based on directory structure.
9386 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
9387 pkg.applicationInfo.primaryCpuAbi == null) {
9388 setBundledAppAbisAndRoots(pkg, pkgSetting);
9389 setNativeLibraryPaths(pkg, mAppLib32InstallDir);
9392 // This is not a first boot or an upgrade, don't bother deriving the
9393 // ABI during the scan. Instead, trust the value that was stored in the
9395 pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
9396 pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
9398 setNativeLibraryPaths(pkg, mAppLib32InstallDir);
9400 if (DEBUG_ABI_SELECTION) {
9401 Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
9402 pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
9403 pkg.applicationInfo.secondaryCpuAbi);
9407 if ((scanFlags & SCAN_MOVE) != 0) {
9408 // We haven't run dex-opt for this move (since we've moved the compiled output too)
9409 // but we already have this packages package info in the PackageSetting. We just
9410 // use that and derive the native library path based on the new codepath.
9411 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
9412 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
9415 // Set native library paths again. For moves, the path will be updated based on the
9416 // ABIs we've determined above. For non-moves, the path will be updated based on the
9417 // ABIs we determined during compilation, but the path will depend on the final
9418 // package path (after the rename away from the stage path).
9419 setNativeLibraryPaths(pkg, mAppLib32InstallDir);
9422 // This is a special case for the "system" package, where the ABI is
9423 // dictated by the zygote configuration (and init.rc). We should keep track
9424 // of this ABI so that we can deal with "normal" applications that run under
9425 // the same UID correctly.
9426 if (mPlatformPackage == pkg) {
9427 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
9428 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
9431 // If there's a mismatch between the abi-override in the package setting
9432 // and the abiOverride specified for the install. Warn about this because we
9433 // would've already compiled the app without taking the package setting into
9435 if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
9436 if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
9437 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
9438 " for package " + pkg.packageName);
9442 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
9443 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
9444 pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
9446 // Copy the derived override back to the parsed package, so that we can
9447 // update the package settings accordingly.
9448 pkg.cpuAbiOverride = cpuAbiOverride;
9450 if (DEBUG_ABI_SELECTION) {
9451 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
9452 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
9453 + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
9456 // Push the derived path down into PackageSettings so we know what to
9457 // clean up at uninstall time.
9458 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
9460 if (DEBUG_ABI_SELECTION) {
9461 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
9462 " primary=" + pkg.applicationInfo.primaryCpuAbi +
9463 " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
9466 // SIDE EFFECTS; removes DEX files from disk; move elsewhere
9467 if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
9468 // We don't do this here during boot because we can do it all
9469 // at once after scanning all existing packages.
9471 // We also do this *before* we perform dexopt on this package, so that
9472 // we can avoid redundant dexopts, and also to make sure we've got the
9473 // code and package path correct.
9474 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
9477 if (mFactoryTest && pkg.requestedPermissions.contains(
9478 android.Manifest.permission.FACTORY_TEST)) {
9479 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
9482 if (isSystemApp(pkg)) {
9483 pkgSetting.isOrphaned = true;
9486 // Take care of first install / last update times.
9487 final long scanFileTime = getLastModifiedTime(pkg, scanFile);
9488 if (currentTime != 0) {
9489 if (pkgSetting.firstInstallTime == 0) {
9490 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
9491 } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
9492 pkgSetting.lastUpdateTime = currentTime;
9494 } else if (pkgSetting.firstInstallTime == 0) {
9495 // We need *something*. Take time time stamp of the file.
9496 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
9497 } else if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
9498 if (scanFileTime != pkgSetting.timeStamp) {
9499 // A package on the system image has changed; consider this
9501 pkgSetting.lastUpdateTime = scanFileTime;
9504 pkgSetting.setTimeStamp(scanFileTime);
9506 if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9507 if (nonMutatedPs != null) {
9508 synchronized (mPackages) {
9509 mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs);
9513 final int userId = user == null ? 0 : user.getIdentifier();
9514 // Modify state for the given package setting
9515 commitPackageSettings(pkg, pkgSetting, user, scanFlags,
9516 (policyFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
9517 if (pkgSetting.getInstantApp(userId)) {
9518 mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
9525 * Applies policy to the parsed package based upon the given policy flags.
9526 * Ensures the package is in a good state.
9528 * Implementation detail: This method must NOT have any side effect. It would
9529 * ideally be static, but, it requires locks to read system state.
9531 private void applyPolicy(PackageParser.Package pkg, int policyFlags) {
9532 if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
9533 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
9534 if (pkg.applicationInfo.isDirectBootAware()) {
9535 // we're direct boot aware; set for all components
9536 for (PackageParser.Service s : pkg.services) {
9537 s.info.encryptionAware = s.info.directBootAware = true;
9539 for (PackageParser.Provider p : pkg.providers) {
9540 p.info.encryptionAware = p.info.directBootAware = true;
9542 for (PackageParser.Activity a : pkg.activities) {
9543 a.info.encryptionAware = a.info.directBootAware = true;
9545 for (PackageParser.Activity r : pkg.receivers) {
9546 r.info.encryptionAware = r.info.directBootAware = true;
9550 // Only allow system apps to be flagged as core apps.
9551 pkg.coreApp = false;
9552 // clear flags not applicable to regular apps
9553 pkg.applicationInfo.privateFlags &=
9554 ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
9555 pkg.applicationInfo.privateFlags &=
9556 ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
9558 pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0;
9560 if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
9561 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
9564 if (!isSystemApp(pkg)) {
9565 // Only system apps can use these features.
9566 pkg.mOriginalPackages = null;
9567 pkg.mRealPackage = null;
9568 pkg.mAdoptPermissions = null;
9573 * Asserts the parsed package is valid according to the given policy. If the
9574 * package is invalid, for whatever reason, throws {@link PackageManagerException}.
9576 * Implementation detail: This method must NOT have any side effects. It would
9577 * ideally be static, but, it requires locks to read system state.
9579 * @throws PackageManagerException If the package fails any of the validation checks
9581 private void assertPackageIsValid(PackageParser.Package pkg, int policyFlags, int scanFlags)
9582 throws PackageManagerException {
9583 if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
9584 assertCodePolicy(pkg);
9587 if (pkg.applicationInfo.getCodePath() == null ||
9588 pkg.applicationInfo.getResourcePath() == null) {
9589 // Bail out. The resource and code paths haven't been set.
9590 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
9591 "Code and resource paths haven't been set correctly");
9594 // Make sure we're not adding any bogus keyset info
9595 KeySetManagerService ksms = mSettings.mKeySetManagerService;
9596 ksms.assertScannedPackageValid(pkg);
9598 synchronized (mPackages) {
9599 // The special "android" package can only be defined once
9600 if (pkg.packageName.equals("android")) {
9601 if (mAndroidApplication != null) {
9602 Slog.w(TAG, "*************************************************");
9603 Slog.w(TAG, "Core android package being redefined. Skipping.");
9604 Slog.w(TAG, " codePath=" + pkg.codePath);
9605 Slog.w(TAG, "*************************************************");
9606 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
9607 "Core android package being redefined. Skipping.");
9611 // A package name must be unique; don't allow duplicates
9612 if (mPackages.containsKey(pkg.packageName)) {
9613 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
9614 "Application package " + pkg.packageName
9615 + " already installed. Skipping duplicate.");
9618 if (pkg.applicationInfo.isStaticSharedLibrary()) {
9619 // Static libs have a synthetic package name containing the version
9620 // but we still want the base name to be unique.
9621 if (mPackages.containsKey(pkg.manifestPackageName)) {
9622 throw new PackageManagerException(
9623 "Duplicate static shared lib provider package");
9626 // Static shared libraries should have at least O target SDK
9627 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
9628 throw new PackageManagerException(
9629 "Packages declaring static-shared libs must target O SDK or higher");
9632 // Package declaring static a shared lib cannot be instant apps
9633 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
9634 throw new PackageManagerException(
9635 "Packages declaring static-shared libs cannot be instant apps");
9638 // Package declaring static a shared lib cannot be renamed since the package
9639 // name is synthetic and apps can't code around package manager internals.
9640 if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) {
9641 throw new PackageManagerException(
9642 "Packages declaring static-shared libs cannot be renamed");
9645 // Package declaring static a shared lib cannot declare child packages
9646 if (!ArrayUtils.isEmpty(pkg.childPackages)) {
9647 throw new PackageManagerException(
9648 "Packages declaring static-shared libs cannot have child packages");
9651 // Package declaring static a shared lib cannot declare dynamic libs
9652 if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
9653 throw new PackageManagerException(
9654 "Packages declaring static-shared libs cannot declare dynamic libs");
9657 // Package declaring static a shared lib cannot declare shared users
9658 if (pkg.mSharedUserId != null) {
9659 throw new PackageManagerException(
9660 "Packages declaring static-shared libs cannot declare shared users");
9663 // Static shared libs cannot declare activities
9664 if (!pkg.activities.isEmpty()) {
9665 throw new PackageManagerException(
9666 "Static shared libs cannot declare activities");
9669 // Static shared libs cannot declare services
9670 if (!pkg.services.isEmpty()) {
9671 throw new PackageManagerException(
9672 "Static shared libs cannot declare services");
9675 // Static shared libs cannot declare providers
9676 if (!pkg.providers.isEmpty()) {
9677 throw new PackageManagerException(
9678 "Static shared libs cannot declare content providers");
9681 // Static shared libs cannot declare receivers
9682 if (!pkg.receivers.isEmpty()) {
9683 throw new PackageManagerException(
9684 "Static shared libs cannot declare broadcast receivers");
9687 // Static shared libs cannot declare permission groups
9688 if (!pkg.permissionGroups.isEmpty()) {
9689 throw new PackageManagerException(
9690 "Static shared libs cannot declare permission groups");
9693 // Static shared libs cannot declare permissions
9694 if (!pkg.permissions.isEmpty()) {
9695 throw new PackageManagerException(
9696 "Static shared libs cannot declare permissions");
9699 // Static shared libs cannot declare protected broadcasts
9700 if (pkg.protectedBroadcasts != null) {
9701 throw new PackageManagerException(
9702 "Static shared libs cannot declare protected broadcasts");
9705 // Static shared libs cannot be overlay targets
9706 if (pkg.mOverlayTarget != null) {
9707 throw new PackageManagerException(
9708 "Static shared libs cannot be overlay targets");
9711 // The version codes must be ordered as lib versions
9712 int minVersionCode = Integer.MIN_VALUE;
9713 int maxVersionCode = Integer.MAX_VALUE;
9715 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
9716 pkg.staticSharedLibName);
9717 if (versionedLib != null) {
9718 final int versionCount = versionedLib.size();
9719 for (int i = 0; i < versionCount; i++) {
9720 SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
9721 // TODO: We will change version code to long, so in the new API it is long
9722 final int libVersionCode = (int) libInfo.getDeclaringPackage()
9724 if (libInfo.getVersion() < pkg.staticSharedLibVersion) {
9725 minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
9726 } else if (libInfo.getVersion() > pkg.staticSharedLibVersion) {
9727 maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
9729 minVersionCode = maxVersionCode = libVersionCode;
9734 if (pkg.mVersionCode < minVersionCode || pkg.mVersionCode > maxVersionCode) {
9735 throw new PackageManagerException("Static shared"
9736 + " lib version codes must be ordered as lib versions");
9740 // Only privileged apps and updated privileged apps can add child packages.
9741 if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
9742 if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) {
9743 throw new PackageManagerException("Only privileged apps can add child "
9744 + "packages. Ignoring package " + pkg.packageName);
9746 final int childCount = pkg.childPackages.size();
9747 for (int i = 0; i < childCount; i++) {
9748 PackageParser.Package childPkg = pkg.childPackages.get(i);
9749 if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
9750 childPkg.packageName)) {
9751 throw new PackageManagerException("Can't override child of "
9752 + "another disabled app. Ignoring package " + pkg.packageName);
9757 // If we're only installing presumed-existing packages, require that the
9758 // scanned APK is both already known and at the path previously established
9759 // for it. Previously unknown packages we pick up normally, but if we have an
9760 // a priori expectation about this package's install presence, enforce it.
9761 // With a singular exception for new system packages. When an OTA contains
9762 // a new system package, we allow the codepath to change from a system location
9763 // to the user-installed location. If we don't allow this change, any newer,
9764 // user-installed version of the application will be ignored.
9765 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
9766 if (mExpectingBetter.containsKey(pkg.packageName)) {
9767 logCriticalInfo(Log.WARN,
9768 "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
9770 PackageSetting known = mSettings.getPackageLPr(pkg.packageName);
9771 if (known != null) {
9772 if (DEBUG_PACKAGE_SCANNING) {
9773 Log.d(TAG, "Examining " + pkg.codePath
9774 + " and requiring known paths " + known.codePathString
9775 + " & " + known.resourcePathString);
9777 if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
9778 || !pkg.applicationInfo.getResourcePath().equals(
9779 known.resourcePathString)) {
9780 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
9781 "Application package " + pkg.packageName
9782 + " found at " + pkg.applicationInfo.getCodePath()
9783 + " but expected at " + known.codePathString
9790 // Verify that this new package doesn't have any content providers
9791 // that conflict with existing packages. Only do this if the
9792 // package isn't already installed, since we don't want to break
9793 // things that are installed.
9794 if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
9795 final int N = pkg.providers.size();
9797 for (i=0; i<N; i++) {
9798 PackageParser.Provider p = pkg.providers.get(i);
9799 if (p.info.authority != null) {
9800 String names[] = p.info.authority.split(";");
9801 for (int j = 0; j < names.length; j++) {
9802 if (mProvidersByAuthority.containsKey(names[j])) {
9803 PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
9804 final String otherPackageName =
9805 ((other != null && other.getComponentName() != null) ?
9806 other.getComponentName().getPackageName() : "?");
9807 throw new PackageManagerException(
9808 INSTALL_FAILED_CONFLICTING_PROVIDER,
9809 "Can't install because provider name " + names[j]
9810 + " (in package " + pkg.applicationInfo.packageName
9811 + ") is already used by " + otherPackageName);
9820 private boolean addSharedLibraryLPw(String path, String apk, String name, int version,
9821 int type, String declaringPackageName, int declaringVersionCode) {
9822 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
9823 if (versionedLib == null) {
9824 versionedLib = new SparseArray<>();
9825 mSharedLibraries.put(name, versionedLib);
9826 if (type == SharedLibraryInfo.TYPE_STATIC) {
9827 mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
9829 } else if (versionedLib.indexOfKey(version) >= 0) {
9832 SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name,
9833 version, type, declaringPackageName, declaringVersionCode);
9834 versionedLib.put(version, libEntry);
9838 private boolean removeSharedLibraryLPw(String name, int version) {
9839 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
9840 if (versionedLib == null) {
9843 final int libIdx = versionedLib.indexOfKey(version);
9847 SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx);
9848 versionedLib.remove(version);
9849 if (versionedLib.size() <= 0) {
9850 mSharedLibraries.remove(name);
9851 if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) {
9852 mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage()
9860 * Adds a scanned package to the system. When this method is finished, the package will
9861 * be available for query, resolution, etc...
9863 private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting,
9864 UserHandle user, int scanFlags, boolean chatty) throws PackageManagerException {
9865 final String pkgName = pkg.packageName;
9866 if (mCustomResolverComponentName != null &&
9867 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
9868 setUpCustomResolverActivity(pkg);
9871 if (pkg.packageName.equals("android")) {
9872 synchronized (mPackages) {
9873 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9874 // Set up information for our fall-back user intent resolution activity.
9875 mPlatformPackage = pkg;
9876 pkg.mVersionCode = mSdkVersion;
9877 mAndroidApplication = pkg.applicationInfo;
9878 if (!mResolverReplaced) {
9879 mResolveActivity.applicationInfo = mAndroidApplication;
9880 mResolveActivity.name = ResolverActivity.class.getName();
9881 mResolveActivity.packageName = mAndroidApplication.packageName;
9882 mResolveActivity.processName = "system:ui";
9883 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
9884 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
9885 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
9886 mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
9887 mResolveActivity.exported = true;
9888 mResolveActivity.enabled = true;
9889 mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
9890 mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
9891 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
9892 | ActivityInfo.CONFIG_SCREEN_LAYOUT
9893 | ActivityInfo.CONFIG_ORIENTATION
9894 | ActivityInfo.CONFIG_KEYBOARD
9895 | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
9896 mResolveInfo.activityInfo = mResolveActivity;
9897 mResolveInfo.priority = 0;
9898 mResolveInfo.preferredOrder = 0;
9899 mResolveInfo.match = 0;
9900 mResolveComponentName = new ComponentName(
9901 mAndroidApplication.packageName, mResolveActivity.name);
9907 ArrayList<PackageParser.Package> clientLibPkgs = null;
9909 synchronized (mPackages) {
9910 boolean hasStaticSharedLibs = false;
9912 // Any app can add new static shared libraries
9913 if (pkg.staticSharedLibName != null) {
9914 // Static shared libs don't allow renaming as they have synthetic package
9915 // names to allow install of multiple versions, so use name from manifest.
9916 if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName,
9917 pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC,
9918 pkg.manifestPackageName, pkg.mVersionCode)) {
9919 hasStaticSharedLibs = true;
9921 Slog.w(TAG, "Package " + pkg.packageName + " library "
9922 + pkg.staticSharedLibName + " already exists; skipping");
9924 // Static shared libs cannot be updated once installed since they
9925 // use synthetic package name which includes the version code, so
9926 // not need to update other packages's shared lib dependencies.
9929 if (!hasStaticSharedLibs
9930 && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
9931 // Only system apps can add new dynamic shared libraries.
9932 if (pkg.libraryNames != null) {
9933 for (int i = 0; i < pkg.libraryNames.size(); i++) {
9934 String name = pkg.libraryNames.get(i);
9935 boolean allowed = false;
9936 if (pkg.isUpdatedSystemApp()) {
9937 // New library entries can only be added through the
9938 // system image. This is important to get rid of a lot
9939 // of nasty edge cases: for example if we allowed a non-
9940 // system update of the app to add a library, then uninstalling
9941 // the update would make the library go away, and assumptions
9942 // we made such as through app install filtering would now
9943 // have allowed apps on the device which aren't compatible
9944 // with it. Better to just have the restriction here, be
9945 // conservative, and create many fewer cases that can negatively
9946 // impact the user experience.
9947 final PackageSetting sysPs = mSettings
9948 .getDisabledSystemPkgLPr(pkg.packageName);
9949 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
9950 for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
9951 if (name.equals(sysPs.pkg.libraryNames.get(j))) {
9961 if (!addSharedLibraryLPw(null, pkg.packageName, name,
9962 SharedLibraryInfo.VERSION_UNDEFINED,
9963 SharedLibraryInfo.TYPE_DYNAMIC,
9964 pkg.packageName, pkg.mVersionCode)) {
9965 Slog.w(TAG, "Package " + pkg.packageName + " library "
9966 + name + " already exists; skipping");
9969 Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
9970 + name + " that is not declared on system image; skipping");
9974 if ((scanFlags & SCAN_BOOTING) == 0) {
9975 // If we are not booting, we need to update any applications
9976 // that are clients of our shared library. If we are booting,
9977 // this will all be done once the scan is complete.
9978 clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
9984 if ((scanFlags & SCAN_BOOTING) != 0) {
9985 // No apps can run during boot scan, so they don't need to be frozen
9986 } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
9987 // Caller asked to not kill app, so it's probably not frozen
9988 } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
9989 // Caller asked us to ignore frozen check for some reason; they
9990 // probably didn't know the package name
9992 // We're doing major surgery on this package, so it better be frozen
9993 // right now to keep it from launching
9994 checkPackageFrozen(pkgName);
9997 // Also need to kill any apps that are dependent on the library.
9998 if (clientLibPkgs != null) {
9999 for (int i=0; i<clientLibPkgs.size(); i++) {
10000 PackageParser.Package clientPkg = clientLibPkgs.get(i);
10001 killApplication(clientPkg.applicationInfo.packageName,
10002 clientPkg.applicationInfo.uid, "update lib");
10007 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
10009 synchronized (mPackages) {
10010 // We don't expect installation to fail beyond this point
10012 // Add the new setting to mSettings
10013 mSettings.insertPackageSettingLPw(pkgSetting, pkg);
10014 // Add the new setting to mPackages
10015 mPackages.put(pkg.applicationInfo.packageName, pkg);
10016 // Make sure we don't accidentally delete its data.
10017 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
10018 while (iter.hasNext()) {
10019 PackageCleanItem item = iter.next();
10020 if (pkgName.equals(item.packageName)) {
10025 // Add the package's KeySets to the global KeySetManagerService
10026 KeySetManagerService ksms = mSettings.mKeySetManagerService;
10027 ksms.addScannedPackageLPw(pkg);
10029 int N = pkg.providers.size();
10030 StringBuilder r = null;
10032 for (i=0; i<N; i++) {
10033 PackageParser.Provider p = pkg.providers.get(i);
10034 p.info.processName = fixProcessName(pkg.applicationInfo.processName,
10035 p.info.processName);
10036 mProviders.addProvider(p);
10037 p.syncable = p.info.isSyncable;
10038 if (p.info.authority != null) {
10039 String names[] = p.info.authority.split(";");
10040 p.info.authority = null;
10041 for (int j = 0; j < names.length; j++) {
10042 if (j == 1 && p.syncable) {
10043 // We only want the first authority for a provider to possibly be
10044 // syncable, so if we already added this provider using a different
10045 // authority clear the syncable flag. We copy the provider before
10046 // changing it because the mProviders object contains a reference
10047 // to a provider that we don't want to change.
10048 // Only do this for the second authority since the resulting provider
10049 // object can be the same for all future authorities for this provider.
10050 p = new PackageParser.Provider(p);
10051 p.syncable = false;
10053 if (!mProvidersByAuthority.containsKey(names[j])) {
10054 mProvidersByAuthority.put(names[j], p);
10055 if (p.info.authority == null) {
10056 p.info.authority = names[j];
10058 p.info.authority = p.info.authority + ";" + names[j];
10060 if (DEBUG_PACKAGE_SCANNING) {
10062 Log.d(TAG, "Registered content provider: " + names[j]
10063 + ", className = " + p.info.name + ", isSyncable = "
10064 + p.info.isSyncable);
10067 PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
10068 Slog.w(TAG, "Skipping provider name " + names[j] +
10069 " (in package " + pkg.applicationInfo.packageName +
10070 "): name already used by "
10071 + ((other != null && other.getComponentName() != null)
10072 ? other.getComponentName().getPackageName() : "?"));
10078 r = new StringBuilder(256);
10082 r.append(p.info.name);
10086 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r);
10089 N = pkg.services.size();
10091 for (i=0; i<N; i++) {
10092 PackageParser.Service s = pkg.services.get(i);
10093 s.info.processName = fixProcessName(pkg.applicationInfo.processName,
10094 s.info.processName);
10095 mServices.addService(s);
10098 r = new StringBuilder(256);
10102 r.append(s.info.name);
10106 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r);
10109 N = pkg.receivers.size();
10111 for (i=0; i<N; i++) {
10112 PackageParser.Activity a = pkg.receivers.get(i);
10113 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
10114 a.info.processName);
10115 mReceivers.addActivity(a, "receiver");
10118 r = new StringBuilder(256);
10122 r.append(a.info.name);
10126 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r);
10129 N = pkg.activities.size();
10131 for (i=0; i<N; i++) {
10132 PackageParser.Activity a = pkg.activities.get(i);
10133 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
10134 a.info.processName);
10135 mActivities.addActivity(a, "activity");
10138 r = new StringBuilder(256);
10142 r.append(a.info.name);
10146 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r);
10149 N = pkg.permissionGroups.size();
10151 for (i=0; i<N; i++) {
10152 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
10153 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
10154 final String curPackageName = cur == null ? null : cur.info.packageName;
10155 // Dont allow ephemeral apps to define new permission groups.
10156 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10157 Slog.w(TAG, "Permission group " + pg.info.name + " from package "
10158 + pg.info.packageName
10159 + " ignored: instant apps cannot define new permission groups.");
10162 final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
10163 if (cur == null || isPackageUpdate) {
10164 mPermissionGroups.put(pg.info.name, pg);
10167 r = new StringBuilder(256);
10171 if (isPackageUpdate) {
10174 r.append(pg.info.name);
10177 Slog.w(TAG, "Permission group " + pg.info.name + " from package "
10178 + pg.info.packageName + " ignored: original from "
10179 + cur.info.packageName);
10182 r = new StringBuilder(256);
10187 r.append(pg.info.name);
10192 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r);
10195 N = pkg.permissions.size();
10197 for (i=0; i<N; i++) {
10198 PackageParser.Permission p = pkg.permissions.get(i);
10200 // Dont allow ephemeral apps to define new permissions.
10201 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10202 Slog.w(TAG, "Permission " + p.info.name + " from package "
10203 + p.info.packageName
10204 + " ignored: instant apps cannot define new permissions.");
10208 // Assume by default that we did not install this permission into the system.
10209 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
10211 // Now that permission groups have a special meaning, we ignore permission
10212 // groups for legacy apps to prevent unexpected behavior. In particular,
10213 // permissions for one app being granted to someone just becase they happen
10214 // to be in a group defined by another app (before this had no implications).
10215 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
10216 p.group = mPermissionGroups.get(p.info.group);
10217 // Warn for a permission in an unknown group.
10218 if (p.info.group != null && p.group == null) {
10219 Slog.w(TAG, "Permission " + p.info.name + " from package "
10220 + p.info.packageName + " in an unknown group " + p.info.group);
10224 ArrayMap<String, BasePermission> permissionMap =
10225 p.tree ? mSettings.mPermissionTrees
10226 : mSettings.mPermissions;
10227 BasePermission bp = permissionMap.get(p.info.name);
10229 // Allow system apps to redefine non-system permissions
10230 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
10231 final boolean currentOwnerIsSystem = (bp.perm != null
10232 && isSystemApp(bp.perm.owner));
10233 if (isSystemApp(p.owner)) {
10234 if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
10235 // It's a built-in permission and no owner, take ownership now
10236 bp.packageSetting = pkgSetting;
10238 bp.uid = pkg.applicationInfo.uid;
10239 bp.sourcePackage = p.info.packageName;
10240 p.info.flags |= PermissionInfo.FLAG_INSTALLED;
10241 } else if (!currentOwnerIsSystem) {
10242 String msg = "New decl " + p.owner + " of permission "
10243 + p.info.name + " is system; overriding " + bp.sourcePackage;
10244 reportSettingsProblem(Log.WARN, msg);
10251 bp = new BasePermission(p.info.name, p.info.packageName,
10252 BasePermission.TYPE_NORMAL);
10253 permissionMap.put(p.info.name, bp);
10256 if (bp.perm == null) {
10257 if (bp.sourcePackage == null
10258 || bp.sourcePackage.equals(p.info.packageName)) {
10259 BasePermission tree = findPermissionTreeLP(p.info.name);
10261 || tree.sourcePackage.equals(p.info.packageName)) {
10262 bp.packageSetting = pkgSetting;
10264 bp.uid = pkg.applicationInfo.uid;
10265 bp.sourcePackage = p.info.packageName;
10266 p.info.flags |= PermissionInfo.FLAG_INSTALLED;
10269 r = new StringBuilder(256);
10273 r.append(p.info.name);
10276 Slog.w(TAG, "Permission " + p.info.name + " from package "
10277 + p.info.packageName + " ignored: base tree "
10278 + tree.name + " is from package "
10279 + tree.sourcePackage);
10282 Slog.w(TAG, "Permission " + p.info.name + " from package "
10283 + p.info.packageName + " ignored: original from "
10284 + bp.sourcePackage);
10286 } else if (chatty) {
10288 r = new StringBuilder(256);
10293 r.append(p.info.name);
10295 if (bp.perm == p) {
10296 bp.protectionLevel = p.info.protectionLevel;
10301 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r);
10304 N = pkg.instrumentation.size();
10306 for (i=0; i<N; i++) {
10307 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
10308 a.info.packageName = pkg.applicationInfo.packageName;
10309 a.info.sourceDir = pkg.applicationInfo.sourceDir;
10310 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
10311 a.info.splitNames = pkg.splitNames;
10312 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
10313 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
10314 a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
10315 a.info.dataDir = pkg.applicationInfo.dataDir;
10316 a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
10317 a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
10318 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
10319 a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
10320 mInstrumentation.put(a.getComponentName(), a);
10323 r = new StringBuilder(256);
10327 r.append(a.info.name);
10331 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r);
10334 if (pkg.protectedBroadcasts != null) {
10335 N = pkg.protectedBroadcasts.size();
10336 for (i=0; i<N; i++) {
10337 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
10342 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10346 * Derive the ABI of a non-system package located at {@code scanFile}. This information
10347 * is derived purely on the basis of the contents of {@code scanFile} and
10348 * {@code cpuAbiOverride}.
10350 * If {@code extractLibs} is true, native libraries are extracted from the app if required.
10352 private static void derivePackageAbi(PackageParser.Package pkg, File scanFile,
10353 String cpuAbiOverride, boolean extractLibs,
10354 File appLib32InstallDir)
10355 throws PackageManagerException {
10356 // Give ourselves some initial paths; we'll come back for another
10357 // pass once we've determined ABI below.
10358 setNativeLibraryPaths(pkg, appLib32InstallDir);
10360 // We would never need to extract libs for forward-locked and external packages,
10361 // since the container service will do it for us. We shouldn't attempt to
10362 // extract libs from system app when it was not updated.
10363 if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
10364 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
10365 extractLibs = false;
10368 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
10369 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
10371 NativeLibraryHelper.Handle handle = null;
10373 handle = NativeLibraryHelper.Handle.create(pkg);
10374 // TODO(multiArch): This can be null for apps that didn't go through the
10375 // usual installation process. We can calculate it again, like we
10376 // do during install time.
10378 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
10380 final File nativeLibraryRoot = new File(nativeLibraryRootStr);
10382 // Null out the abis so that they can be recalculated.
10383 pkg.applicationInfo.primaryCpuAbi = null;
10384 pkg.applicationInfo.secondaryCpuAbi = null;
10385 if (isMultiArch(pkg.applicationInfo)) {
10386 // Warn if we've set an abiOverride for multi-lib packages..
10387 // By definition, we need to copy both 32 and 64 bit libraries for
10389 if (pkg.cpuAbiOverride != null
10390 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
10391 Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
10394 int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
10395 int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
10396 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
10398 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
10399 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
10400 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
10401 useIsaSpecificSubdirs);
10403 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
10404 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
10406 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10409 maybeThrowExceptionForMultiArchCopy(
10410 "Error unpackaging 32 bit native libs for multiarch app.", abi32);
10412 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
10414 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
10415 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
10416 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
10417 useIsaSpecificSubdirs);
10419 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
10420 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
10422 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10425 maybeThrowExceptionForMultiArchCopy(
10426 "Error unpackaging 64 bit native libs for multiarch app.", abi64);
10429 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
10433 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
10435 if (pkg.use32bitAbi) {
10436 pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
10437 pkg.applicationInfo.primaryCpuAbi = abi;
10439 pkg.applicationInfo.secondaryCpuAbi = abi;
10442 pkg.applicationInfo.primaryCpuAbi = abi;
10447 String[] abiList = (cpuAbiOverride != null) ?
10448 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
10450 // Enable gross and lame hacks for apps that are built with old
10451 // SDK tools. We must scan their APKs for renderscript bitcode and
10452 // not launch them if it's present. Don't bother checking on devices
10453 // that don't have 64 bit support.
10454 boolean needsRenderScriptOverride = false;
10455 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
10456 NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
10457 abiList = Build.SUPPORTED_32_BIT_ABIS;
10458 needsRenderScriptOverride = true;
10463 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
10464 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
10465 nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
10467 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
10468 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
10470 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10472 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
10473 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
10474 "Error unpackaging native libs for app, errorCode=" + copyRet);
10477 if (copyRet >= 0) {
10478 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
10479 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
10480 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
10481 } else if (needsRenderScriptOverride) {
10482 pkg.applicationInfo.primaryCpuAbi = abiList[0];
10485 } catch (IOException ioe) {
10486 Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
10488 IoUtils.closeQuietly(handle);
10491 // Now that we've calculated the ABIs and determined if it's an internal app,
10492 // we will go ahead and populate the nativeLibraryPath.
10493 setNativeLibraryPaths(pkg, appLib32InstallDir);
10497 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
10498 * i.e, so that all packages can be run inside a single process if required.
10500 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
10501 * this function will either try and make the ABI for all packages in {@code packagesForUser}
10502 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
10503 * the ABI selected for {@code packagesForUser}. This variant is used when installing or
10504 * updating a package that belongs to a shared user.
10506 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
10507 * adds unnecessary complexity.
10509 private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
10510 PackageParser.Package scannedPackage) {
10511 String requiredInstructionSet = null;
10512 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
10513 requiredInstructionSet = VMRuntime.getInstructionSet(
10514 scannedPackage.applicationInfo.primaryCpuAbi);
10517 PackageSetting requirer = null;
10518 for (PackageSetting ps : packagesForUser) {
10519 // If packagesForUser contains scannedPackage, we skip it. This will happen
10520 // when scannedPackage is an update of an existing package. Without this check,
10521 // we will never be able to change the ABI of any package belonging to a shared
10522 // user, even if it's compatible with other packages.
10523 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
10524 if (ps.primaryCpuAbiString == null) {
10528 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
10529 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
10530 // We have a mismatch between instruction sets (say arm vs arm64) warn about
10531 // this but there's not much we can do.
10532 String errorMessage = "Instruction set mismatch, "
10533 + ((requirer == null) ? "[caller]" : requirer)
10534 + " requires " + requiredInstructionSet + " whereas " + ps
10535 + " requires " + instructionSet;
10536 Slog.w(TAG, errorMessage);
10539 if (requiredInstructionSet == null) {
10540 requiredInstructionSet = instructionSet;
10546 if (requiredInstructionSet != null) {
10547 String adjustedAbi;
10548 if (requirer != null) {
10549 // requirer != null implies that either scannedPackage was null or that scannedPackage
10550 // did not require an ABI, in which case we have to adjust scannedPackage to match
10551 // the ABI of the set (which is the same as requirer's ABI)
10552 adjustedAbi = requirer.primaryCpuAbiString;
10553 if (scannedPackage != null) {
10554 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
10557 // requirer == null implies that we're updating all ABIs in the set to
10558 // match scannedPackage.
10559 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi;
10562 for (PackageSetting ps : packagesForUser) {
10563 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
10564 if (ps.primaryCpuAbiString != null) {
10568 ps.primaryCpuAbiString = adjustedAbi;
10569 if (ps.pkg != null && ps.pkg.applicationInfo != null &&
10570 !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
10571 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
10572 Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
10574 + (requirer != null ? requirer.pkg : "null")
10575 + ", scannedPackage="
10576 + (scannedPackage != null ? scannedPackage : "null")
10579 mInstaller.rmdex(ps.codePathString,
10580 getDexCodeInstructionSet(getPreferredInstructionSet()));
10581 } catch (InstallerException ignored) {
10589 private void setUpCustomResolverActivity(PackageParser.Package pkg) {
10590 synchronized (mPackages) {
10591 mResolverReplaced = true;
10592 // Set up information for custom user intent resolution activity.
10593 mResolveActivity.applicationInfo = pkg.applicationInfo;
10594 mResolveActivity.name = mCustomResolverComponentName.getClassName();
10595 mResolveActivity.packageName = pkg.applicationInfo.packageName;
10596 mResolveActivity.processName = pkg.applicationInfo.packageName;
10597 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
10598 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
10599 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
10600 mResolveActivity.theme = 0;
10601 mResolveActivity.exported = true;
10602 mResolveActivity.enabled = true;
10603 mResolveInfo.activityInfo = mResolveActivity;
10604 mResolveInfo.priority = 0;
10605 mResolveInfo.preferredOrder = 0;
10606 mResolveInfo.match = 0;
10607 mResolveComponentName = mCustomResolverComponentName;
10608 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
10609 mResolveComponentName);
10613 private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
10614 if (installerActivity == null) {
10615 if (DEBUG_EPHEMERAL) {
10616 Slog.d(TAG, "Clear ephemeral installer activity");
10618 mInstantAppInstallerActivity = null;
10622 if (DEBUG_EPHEMERAL) {
10623 Slog.d(TAG, "Set ephemeral installer activity: "
10624 + installerActivity.getComponentName());
10626 // Set up information for ephemeral installer activity
10627 mInstantAppInstallerActivity = installerActivity;
10628 mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
10629 | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
10630 mInstantAppInstallerActivity.exported = true;
10631 mInstantAppInstallerActivity.enabled = true;
10632 mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
10633 mInstantAppInstallerInfo.priority = 0;
10634 mInstantAppInstallerInfo.preferredOrder = 1;
10635 mInstantAppInstallerInfo.isDefault = true;
10636 mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
10637 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
10640 private static String calculateBundledApkRoot(final String codePathString) {
10641 final File codePath = new File(codePathString);
10642 final File codeRoot;
10643 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
10644 codeRoot = Environment.getRootDirectory();
10645 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
10646 codeRoot = Environment.getOemDirectory();
10647 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
10648 codeRoot = Environment.getVendorDirectory();
10650 // Unrecognized code path; take its top real segment as the apk root:
10651 // e.g. /something/app/blah.apk => /something
10653 File f = codePath.getCanonicalFile();
10654 File parent = f.getParentFile(); // non-null because codePath is a file
10656 while ((tmp = parent.getParentFile()) != null) {
10661 Slog.w(TAG, "Unrecognized code path "
10662 + codePath + " - using " + codeRoot);
10663 } catch (IOException e) {
10664 // Can't canonicalize the code path -- shenanigans?
10665 Slog.w(TAG, "Can't canonicalize code path " + codePath);
10666 return Environment.getRootDirectory().getPath();
10669 return codeRoot.getPath();
10673 * Derive and set the location of native libraries for the given package,
10674 * which varies depending on where and how the package was installed.
10676 private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
10677 final ApplicationInfo info = pkg.applicationInfo;
10678 final String codePath = pkg.codePath;
10679 final File codeFile = new File(codePath);
10680 final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
10681 final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
10683 info.nativeLibraryRootDir = null;
10684 info.nativeLibraryRootRequiresIsa = false;
10685 info.nativeLibraryDir = null;
10686 info.secondaryNativeLibraryDir = null;
10688 if (isApkFile(codeFile)) {
10689 // Monolithic install
10691 // If "/system/lib64/apkname" exists, assume that is the per-package
10692 // native library directory to use; otherwise use "/system/lib/apkname".
10693 final String apkRoot = calculateBundledApkRoot(info.sourceDir);
10694 final boolean is64Bit = VMRuntime.is64BitInstructionSet(
10695 getPrimaryInstructionSet(info));
10697 // This is a bundled system app so choose the path based on the ABI.
10698 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
10699 // is just the default path.
10700 final String apkName = deriveCodePathName(codePath);
10701 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
10702 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
10703 apkName).getAbsolutePath();
10705 if (info.secondaryCpuAbi != null) {
10706 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
10707 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
10708 secondaryLibDir, apkName).getAbsolutePath();
10710 } else if (asecApp) {
10711 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
10712 .getAbsolutePath();
10714 final String apkName = deriveCodePathName(codePath);
10715 info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
10716 .getAbsolutePath();
10719 info.nativeLibraryRootRequiresIsa = false;
10720 info.nativeLibraryDir = info.nativeLibraryRootDir;
10723 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
10724 info.nativeLibraryRootRequiresIsa = true;
10726 info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
10727 getPrimaryInstructionSet(info)).getAbsolutePath();
10729 if (info.secondaryCpuAbi != null) {
10730 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
10731 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
10737 * Calculate the abis and roots for a bundled app. These can uniquely
10738 * be determined from the contents of the system partition, i.e whether
10739 * it contains 64 or 32 bit shared libraries etc. We do not validate any
10740 * of this information, and instead assume that the system was built
10743 private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
10744 PackageSetting pkgSetting) {
10745 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
10747 // If "/system/lib64/apkname" exists, assume that is the per-package
10748 // native library directory to use; otherwise use "/system/lib/apkname".
10749 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
10750 setBundledAppAbi(pkg, apkRoot, apkName);
10751 // pkgSetting might be null during rescan following uninstall of updates
10752 // to a bundled app, so accommodate that possibility. The settings in
10753 // that case will be established later from the parsed package.
10755 // If the settings aren't null, sync them up with what we've just derived.
10756 // note that apkRoot isn't stored in the package settings.
10757 if (pkgSetting != null) {
10758 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
10759 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
10764 * Deduces the ABI of a bundled app and sets the relevant fields on the
10765 * parsed pkg object.
10767 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
10768 * under which system libraries are installed.
10769 * @param apkName the name of the installed package.
10771 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
10772 final File codeFile = new File(pkg.codePath);
10774 final boolean has64BitLibs;
10775 final boolean has32BitLibs;
10776 if (isApkFile(codeFile)) {
10777 // Monolithic install
10778 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
10779 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
10782 final File rootDir = new File(codeFile, LIB_DIR_NAME);
10783 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
10784 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
10785 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
10786 has64BitLibs = (new File(rootDir, isa)).exists();
10788 has64BitLibs = false;
10790 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
10791 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
10792 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
10793 has32BitLibs = (new File(rootDir, isa)).exists();
10795 has32BitLibs = false;
10799 if (has64BitLibs && !has32BitLibs) {
10800 // The package has 64 bit libs, but not 32 bit libs. Its primary
10801 // ABI should be 64 bit. We can safely assume here that the bundled
10802 // native libraries correspond to the most preferred ABI in the list.
10804 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
10805 pkg.applicationInfo.secondaryCpuAbi = null;
10806 } else if (has32BitLibs && !has64BitLibs) {
10807 // The package has 32 bit libs but not 64 bit libs. Its primary
10808 // ABI should be 32 bit.
10810 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
10811 pkg.applicationInfo.secondaryCpuAbi = null;
10812 } else if (has32BitLibs && has64BitLibs) {
10813 // The application has both 64 and 32 bit bundled libraries. We check
10814 // here that the app declares multiArch support, and warn if it doesn't.
10816 // We will be lenient here and record both ABIs. The primary will be the
10817 // ABI that's higher on the list, i.e, a device that's configured to prefer
10818 // 64 bit apps will see a 64 bit primary ABI,
10820 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
10821 Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
10824 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
10825 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
10826 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
10828 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
10829 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
10832 pkg.applicationInfo.primaryCpuAbi = null;
10833 pkg.applicationInfo.secondaryCpuAbi = null;
10837 private void killApplication(String pkgName, int appId, String reason) {
10838 killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
10841 private void killApplication(String pkgName, int appId, int userId, String reason) {
10842 // Request the ActivityManager to kill the process(only for existing packages)
10843 // so that we do not end up in a confused state while the user is still using the older
10844 // version of the application while the new one gets installed.
10845 final long token = Binder.clearCallingIdentity();
10847 IActivityManager am = ActivityManager.getService();
10850 am.killApplication(pkgName, appId, userId, reason);
10851 } catch (RemoteException e) {
10855 Binder.restoreCallingIdentity(token);
10859 private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
10860 // Remove the parent package setting
10861 PackageSetting ps = (PackageSetting) pkg.mExtras;
10863 removePackageLI(ps, chatty);
10865 // Remove the child package setting
10866 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10867 for (int i = 0; i < childCount; i++) {
10868 PackageParser.Package childPkg = pkg.childPackages.get(i);
10869 ps = (PackageSetting) childPkg.mExtras;
10871 removePackageLI(ps, chatty);
10876 void removePackageLI(PackageSetting ps, boolean chatty) {
10877 if (DEBUG_INSTALL) {
10879 Log.d(TAG, "Removing package " + ps.name);
10883 synchronized (mPackages) {
10884 mPackages.remove(ps.name);
10885 final PackageParser.Package pkg = ps.pkg;
10887 cleanPackageDataStructuresLILPw(pkg, chatty);
10892 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
10893 if (DEBUG_INSTALL) {
10895 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
10899 synchronized (mPackages) {
10900 // Remove the parent package
10901 mPackages.remove(pkg.applicationInfo.packageName);
10902 cleanPackageDataStructuresLILPw(pkg, chatty);
10904 // Remove the child packages
10905 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10906 for (int i = 0; i < childCount; i++) {
10907 PackageParser.Package childPkg = pkg.childPackages.get(i);
10908 mPackages.remove(childPkg.applicationInfo.packageName);
10909 cleanPackageDataStructuresLILPw(childPkg, chatty);
10914 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
10915 int N = pkg.providers.size();
10916 StringBuilder r = null;
10918 for (i=0; i<N; i++) {
10919 PackageParser.Provider p = pkg.providers.get(i);
10920 mProviders.removeProvider(p);
10921 if (p.info.authority == null) {
10923 /* There was another ContentProvider with this authority when
10924 * this app was installed so this authority is null,
10925 * Ignore it as we don't have to unregister the provider.
10929 String names[] = p.info.authority.split(";");
10930 for (int j = 0; j < names.length; j++) {
10931 if (mProvidersByAuthority.get(names[j]) == p) {
10932 mProvidersByAuthority.remove(names[j]);
10933 if (DEBUG_REMOVE) {
10935 Log.d(TAG, "Unregistered content provider: " + names[j]
10936 + ", className = " + p.info.name + ", isSyncable = "
10937 + p.info.isSyncable);
10941 if (DEBUG_REMOVE && chatty) {
10943 r = new StringBuilder(256);
10947 r.append(p.info.name);
10951 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r);
10954 N = pkg.services.size();
10956 for (i=0; i<N; i++) {
10957 PackageParser.Service s = pkg.services.get(i);
10958 mServices.removeService(s);
10961 r = new StringBuilder(256);
10965 r.append(s.info.name);
10969 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r);
10972 N = pkg.receivers.size();
10974 for (i=0; i<N; i++) {
10975 PackageParser.Activity a = pkg.receivers.get(i);
10976 mReceivers.removeActivity(a, "receiver");
10977 if (DEBUG_REMOVE && chatty) {
10979 r = new StringBuilder(256);
10983 r.append(a.info.name);
10987 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r);
10990 N = pkg.activities.size();
10992 for (i=0; i<N; i++) {
10993 PackageParser.Activity a = pkg.activities.get(i);
10994 mActivities.removeActivity(a, "activity");
10995 if (DEBUG_REMOVE && chatty) {
10997 r = new StringBuilder(256);
11001 r.append(a.info.name);
11005 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r);
11008 N = pkg.permissions.size();
11010 for (i=0; i<N; i++) {
11011 PackageParser.Permission p = pkg.permissions.get(i);
11012 BasePermission bp = mSettings.mPermissions.get(p.info.name);
11014 bp = mSettings.mPermissionTrees.get(p.info.name);
11016 if (bp != null && bp.perm == p) {
11018 if (DEBUG_REMOVE && chatty) {
11020 r = new StringBuilder(256);
11024 r.append(p.info.name);
11027 if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
11028 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name);
11029 if (appOpPkgs != null) {
11030 appOpPkgs.remove(pkg.packageName);
11035 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
11038 N = pkg.requestedPermissions.size();
11040 for (i=0; i<N; i++) {
11041 String perm = pkg.requestedPermissions.get(i);
11042 BasePermission bp = mSettings.mPermissions.get(perm);
11043 if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
11044 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm);
11045 if (appOpPkgs != null) {
11046 appOpPkgs.remove(pkg.packageName);
11047 if (appOpPkgs.isEmpty()) {
11048 mAppOpPermissionPackages.remove(perm);
11054 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
11057 N = pkg.instrumentation.size();
11059 for (i=0; i<N; i++) {
11060 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
11061 mInstrumentation.remove(a.getComponentName());
11062 if (DEBUG_REMOVE && chatty) {
11064 r = new StringBuilder(256);
11068 r.append(a.info.name);
11072 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r);
11076 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11077 // Only system apps can hold shared libraries.
11078 if (pkg.libraryNames != null) {
11079 for (i = 0; i < pkg.libraryNames.size(); i++) {
11080 String name = pkg.libraryNames.get(i);
11081 if (removeSharedLibraryLPw(name, 0)) {
11082 if (DEBUG_REMOVE && chatty) {
11084 r = new StringBuilder(256);
11097 // Any package can hold static shared libraries.
11098 if (pkg.staticSharedLibName != null) {
11099 if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
11100 if (DEBUG_REMOVE && chatty) {
11102 r = new StringBuilder(256);
11106 r.append(pkg.staticSharedLibName);
11112 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r);
11116 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
11117 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
11118 if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
11125 static final int UPDATE_PERMISSIONS_ALL = 1<<0;
11126 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
11127 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
11129 private void updatePermissionsLPw(PackageParser.Package pkg, int flags) {
11130 // Update the parent permissions
11131 updatePermissionsLPw(pkg.packageName, pkg, flags);
11132 // Update the child permissions
11133 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11134 for (int i = 0; i < childCount; i++) {
11135 PackageParser.Package childPkg = pkg.childPackages.get(i);
11136 updatePermissionsLPw(childPkg.packageName, childPkg, flags);
11140 private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
11142 final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
11143 updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
11146 private void updatePermissionsLPw(String changingPkg,
11147 PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
11148 // Make sure there are no dangling permission trees.
11149 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
11150 while (it.hasNext()) {
11151 final BasePermission bp = it.next();
11152 if (bp.packageSetting == null) {
11153 // We may not yet have parsed the package, so just see if
11154 // we still know about its settings.
11155 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
11157 if (bp.packageSetting == null) {
11158 Slog.w(TAG, "Removing dangling permission tree: " + bp.name
11159 + " from package " + bp.sourcePackage);
11161 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
11162 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
11163 Slog.i(TAG, "Removing old permission tree: " + bp.name
11164 + " from package " + bp.sourcePackage);
11165 flags |= UPDATE_PERMISSIONS_ALL;
11171 // Make sure all dynamic permissions have been assigned to a package,
11172 // and make sure there are no dangling permissions.
11173 it = mSettings.mPermissions.values().iterator();
11174 while (it.hasNext()) {
11175 final BasePermission bp = it.next();
11176 if (bp.type == BasePermission.TYPE_DYNAMIC) {
11177 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
11178 + bp.name + " pkg=" + bp.sourcePackage
11179 + " info=" + bp.pendingInfo);
11180 if (bp.packageSetting == null && bp.pendingInfo != null) {
11181 final BasePermission tree = findPermissionTreeLP(bp.name);
11182 if (tree != null && tree.perm != null) {
11183 bp.packageSetting = tree.packageSetting;
11184 bp.perm = new PackageParser.Permission(tree.perm.owner,
11185 new PermissionInfo(bp.pendingInfo));
11186 bp.perm.info.packageName = tree.perm.info.packageName;
11187 bp.perm.info.name = bp.name;
11192 if (bp.packageSetting == null) {
11193 // We may not yet have parsed the package, so just see if
11194 // we still know about its settings.
11195 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
11197 if (bp.packageSetting == null) {
11198 Slog.w(TAG, "Removing dangling permission: " + bp.name
11199 + " from package " + bp.sourcePackage);
11201 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
11202 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
11203 Slog.i(TAG, "Removing old permission: " + bp.name
11204 + " from package " + bp.sourcePackage);
11205 flags |= UPDATE_PERMISSIONS_ALL;
11211 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
11212 // Now update the permissions for all packages, in particular
11213 // replace the granted permissions of the system packages.
11214 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
11215 for (PackageParser.Package pkg : mPackages.values()) {
11216 if (pkg != pkgInfo) {
11217 // Only replace for packages on requested volume
11218 final String volumeUuid = getVolumeUuidForPackage(pkg);
11219 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
11220 && Objects.equals(replaceVolumeUuid, volumeUuid);
11221 grantPermissionsLPw(pkg, replace, changingPkg);
11226 if (pkgInfo != null) {
11227 // Only replace for packages on requested volume
11228 final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
11229 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
11230 && Objects.equals(replaceVolumeUuid, volumeUuid);
11231 grantPermissionsLPw(pkgInfo, replace, changingPkg);
11233 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11236 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
11237 String packageOfInterest) {
11238 // IMPORTANT: There are two types of permissions: install and runtime.
11239 // Install time permissions are granted when the app is installed to
11240 // all device users and users added in the future. Runtime permissions
11241 // are granted at runtime explicitly to specific users. Normal and signature
11242 // protected permissions are install time permissions. Dangerous permissions
11243 // are install permissions if the app's target SDK is Lollipop MR1 or older,
11244 // otherwise they are runtime permissions. This function does not manage
11245 // runtime permissions except for the case an app targeting Lollipop MR1
11246 // being upgraded to target a newer SDK, in which case dangerous permissions
11247 // are transformed from install time to runtime ones.
11249 final PackageSetting ps = (PackageSetting) pkg.mExtras;
11254 PermissionsState permissionsState = ps.getPermissionsState();
11255 PermissionsState origPermissions = permissionsState;
11257 final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
11259 boolean runtimePermissionsRevoked = false;
11260 int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
11262 boolean changedInstallPermission = false;
11265 ps.installPermissionsFixed = false;
11266 if (!ps.isSharedUser()) {
11267 origPermissions = new PermissionsState(permissionsState);
11268 permissionsState.reset();
11270 // We need to know only about runtime permission changes since the
11271 // calling code always writes the install permissions state but
11272 // the runtime ones are written only if changed. The only cases of
11273 // changed runtime permissions here are promotion of an install to
11274 // runtime and revocation of a runtime from a shared user.
11275 changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
11276 ps.sharedUser, UserManagerService.getInstance().getUserIds());
11277 if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
11278 runtimePermissionsRevoked = true;
11283 permissionsState.setGlobalGids(mGlobalGids);
11285 final int N = pkg.requestedPermissions.size();
11286 for (int i=0; i<N; i++) {
11287 final String name = pkg.requestedPermissions.get(i);
11288 final BasePermission bp = mSettings.mPermissions.get(name);
11290 if (DEBUG_INSTALL) {
11291 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
11294 if (bp == null || bp.packageSetting == null) {
11295 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
11296 Slog.w(TAG, "Unknown permission " + name
11297 + " in package " + pkg.packageName);
11303 // Limit ephemeral apps to ephemeral allowed permissions.
11304 if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
11305 Log.i(TAG, "Denying non-ephemeral permission " + bp.name + " for package "
11306 + pkg.packageName);
11310 final String perm = bp.name;
11311 boolean allowedSig = false;
11312 int grant = GRANT_DENIED;
11314 // Keep track of app op permissions.
11315 if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
11316 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
11317 if (pkgs == null) {
11318 pkgs = new ArraySet<>();
11319 mAppOpPermissionPackages.put(bp.name, pkgs);
11321 pkgs.add(pkg.packageName);
11324 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
11325 final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
11326 >= Build.VERSION_CODES.M;
11328 case PermissionInfo.PROTECTION_NORMAL: {
11329 // For all apps normal permissions are install time ones.
11330 grant = GRANT_INSTALL;
11333 case PermissionInfo.PROTECTION_DANGEROUS: {
11334 // If a permission review is required for legacy apps we represent
11335 // their permissions as always granted runtime ones since we need
11336 // to keep the review required permission flag per user while an
11337 // install permission's state is shared across all users.
11338 if (!appSupportsRuntimePermissions && !mPermissionReviewRequired) {
11339 // For legacy apps dangerous permissions are install time ones.
11340 grant = GRANT_INSTALL;
11341 } else if (origPermissions.hasInstallPermission(bp.name)) {
11342 // For legacy apps that became modern, install becomes runtime.
11343 grant = GRANT_UPGRADE;
11344 } else if (mPromoteSystemApps
11346 && mExistingSystemPackages.contains(ps.name)) {
11347 // For legacy system apps, install becomes runtime.
11348 // We cannot check hasInstallPermission() for system apps since those
11349 // permissions were granted implicitly and not persisted pre-M.
11350 grant = GRANT_UPGRADE;
11352 // For modern apps keep runtime permissions unchanged.
11353 grant = GRANT_RUNTIME;
11357 case PermissionInfo.PROTECTION_SIGNATURE: {
11358 // For all apps signature permissions are install time ones.
11359 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
11361 grant = GRANT_INSTALL;
11366 if (DEBUG_INSTALL) {
11367 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
11370 if (grant != GRANT_DENIED) {
11371 if (!isSystemApp(ps) && ps.installPermissionsFixed) {
11372 // If this is an existing, non-system package, then
11373 // we can't add any new permissions to it.
11374 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
11375 // Except... if this is a permission that was added
11376 // to the platform (note: need to only do this when
11377 // updating the platform).
11378 if (!isNewPlatformPermissionForPackage(perm, pkg)) {
11379 grant = GRANT_DENIED;
11385 case GRANT_INSTALL: {
11386 // Revoke this as runtime permission to handle the case of
11387 // a runtime permission being downgraded to an install one.
11388 // Also in permission review mode we keep dangerous permissions
11390 for (int userId : UserManagerService.getInstance().getUserIds()) {
11391 if (origPermissions.getRuntimePermissionState(
11392 bp.name, userId) != null) {
11393 // Revoke the runtime permission and clear the flags.
11394 origPermissions.revokeRuntimePermission(bp, userId);
11395 origPermissions.updatePermissionFlags(bp, userId,
11396 PackageManager.MASK_PERMISSION_FLAGS, 0);
11397 // If we revoked a permission permission, we have to write.
11398 changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11399 changedRuntimePermissionUserIds, userId);
11402 // Grant an install permission.
11403 if (permissionsState.grantInstallPermission(bp) !=
11404 PermissionsState.PERMISSION_OPERATION_FAILURE) {
11405 changedInstallPermission = true;
11409 case GRANT_RUNTIME: {
11410 // Grant previously granted runtime permissions.
11411 for (int userId : UserManagerService.getInstance().getUserIds()) {
11412 PermissionState permissionState = origPermissions
11413 .getRuntimePermissionState(bp.name, userId);
11414 int flags = permissionState != null
11415 ? permissionState.getFlags() : 0;
11416 if (origPermissions.hasRuntimePermission(bp.name, userId)) {
11417 // Don't propagate the permission in a permission review mode if
11418 // the former was revoked, i.e. marked to not propagate on upgrade.
11419 // Note that in a permission review mode install permissions are
11420 // represented as constantly granted runtime ones since we need to
11421 // keep a per user state associated with the permission. Also the
11422 // revoke on upgrade flag is no longer applicable and is reset.
11423 final boolean revokeOnUpgrade = (flags & PackageManager
11424 .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
11425 if (revokeOnUpgrade) {
11426 flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
11427 // Since we changed the flags, we have to write.
11428 changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11429 changedRuntimePermissionUserIds, userId);
11431 if (!mPermissionReviewRequired || !revokeOnUpgrade) {
11432 if (permissionsState.grantRuntimePermission(bp, userId) ==
11433 PermissionsState.PERMISSION_OPERATION_FAILURE) {
11434 // If we cannot put the permission as it was,
11435 // we have to write.
11436 changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11437 changedRuntimePermissionUserIds, userId);
11441 // If the app supports runtime permissions no need for a review.
11442 if (mPermissionReviewRequired
11443 && appSupportsRuntimePermissions
11444 && (flags & PackageManager
11445 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
11446 flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
11447 // Since we changed the flags, we have to write.
11448 changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11449 changedRuntimePermissionUserIds, userId);
11451 } else if (mPermissionReviewRequired
11452 && !appSupportsRuntimePermissions) {
11453 // For legacy apps that need a permission review, every new
11454 // runtime permission is granted but it is pending a review.
11455 // We also need to review only platform defined runtime
11456 // permissions as these are the only ones the platform knows
11457 // how to disable the API to simulate revocation as legacy
11458 // apps don't expect to run with revoked permissions.
11459 if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) {
11460 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
11461 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
11462 // We changed the flags, hence have to write.
11463 changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11464 changedRuntimePermissionUserIds, userId);
11467 if (permissionsState.grantRuntimePermission(bp, userId)
11468 != PermissionsState.PERMISSION_OPERATION_FAILURE) {
11469 // We changed the permission, hence have to write.
11470 changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11471 changedRuntimePermissionUserIds, userId);
11474 // Propagate the permission flags.
11475 permissionsState.updatePermissionFlags(bp, userId, flags, flags);
11479 case GRANT_UPGRADE: {
11480 // Grant runtime permissions for a previously held install permission.
11481 PermissionState permissionState = origPermissions
11482 .getInstallPermissionState(bp.name);
11483 final int flags = permissionState != null ? permissionState.getFlags() : 0;
11485 if (origPermissions.revokeInstallPermission(bp)
11486 != PermissionsState.PERMISSION_OPERATION_FAILURE) {
11487 // We will be transferring the permission flags, so clear them.
11488 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
11489 PackageManager.MASK_PERMISSION_FLAGS, 0);
11490 changedInstallPermission = true;
11493 // If the permission is not to be promoted to runtime we ignore it and
11494 // also its other flags as they are not applicable to install permissions.
11495 if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
11496 for (int userId : currentUserIds) {
11497 if (permissionsState.grantRuntimePermission(bp, userId) !=
11498 PermissionsState.PERMISSION_OPERATION_FAILURE) {
11499 // Transfer the permission flags.
11500 permissionsState.updatePermissionFlags(bp, userId,
11502 // If we granted the permission, we have to write.
11503 changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11504 changedRuntimePermissionUserIds, userId);
11511 if (packageOfInterest == null
11512 || packageOfInterest.equals(pkg.packageName)) {
11513 Slog.w(TAG, "Not granting permission " + perm
11514 + " to package " + pkg.packageName
11515 + " because it was previously installed without");
11520 if (permissionsState.revokeInstallPermission(bp) !=
11521 PermissionsState.PERMISSION_OPERATION_FAILURE) {
11522 // Also drop the permission flags.
11523 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
11524 PackageManager.MASK_PERMISSION_FLAGS, 0);
11525 changedInstallPermission = true;
11526 Slog.i(TAG, "Un-granting permission " + perm
11527 + " from package " + pkg.packageName
11528 + " (protectionLevel=" + bp.protectionLevel
11529 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
11531 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
11532 // Don't print warning for app op permissions, since it is fine for them
11533 // not to be granted, there is a UI for the user to decide.
11534 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
11535 Slog.w(TAG, "Not granting permission " + perm
11536 + " to package " + pkg.packageName
11537 + " (protectionLevel=" + bp.protectionLevel
11538 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
11545 if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
11546 !isSystemApp(ps) || isUpdatedSystemApp(ps)){
11547 // This is the first that we have heard about this package, so the
11548 // permissions we have now selected are fixed until explicitly
11550 ps.installPermissionsFixed = true;
11553 // Persist the runtime permissions state for users with changes. If permissions
11554 // were revoked because no app in the shared user declares them we have to
11555 // write synchronously to avoid losing runtime permissions state.
11556 for (int userId : changedRuntimePermissionUserIds) {
11557 mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
11561 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
11562 boolean allowed = false;
11563 final int NP = PackageParser.NEW_PERMISSIONS.length;
11564 for (int ip=0; ip<NP; ip++) {
11565 final PackageParser.NewPermissionInfo npi
11566 = PackageParser.NEW_PERMISSIONS[ip];
11567 if (npi.name.equals(perm)
11568 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
11570 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
11571 + pkg.packageName);
11578 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
11579 BasePermission bp, PermissionsState origPermissions) {
11580 boolean privilegedPermission = (bp.protectionLevel
11581 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0;
11582 boolean privappPermissionsDisable =
11583 RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
11584 boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage);
11585 boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
11586 if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivilegedApp()
11587 && !platformPackage && platformPermission) {
11588 ArraySet<String> wlPermissions = SystemConfig.getInstance()
11589 .getPrivAppPermissions(pkg.packageName);
11590 boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
11591 if (!whitelisted) {
11592 Slog.w(TAG, "Privileged permission " + perm + " for package "
11593 + pkg.packageName + " - not in privapp-permissions whitelist");
11594 // Only report violations for apps on system image
11595 if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
11596 if (mPrivappPermissionsViolations == null) {
11597 mPrivappPermissionsViolations = new ArraySet<>();
11599 mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
11601 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
11606 boolean allowed = (compareSignatures(
11607 bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
11608 == PackageManager.SIGNATURE_MATCH)
11609 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
11610 == PackageManager.SIGNATURE_MATCH);
11611 if (!allowed && privilegedPermission) {
11612 if (isSystemApp(pkg)) {
11613 // For updated system applications, a system permission
11614 // is granted only if it had been defined by the original application.
11615 if (pkg.isUpdatedSystemApp()) {
11616 final PackageSetting sysPs = mSettings
11617 .getDisabledSystemPkgLPr(pkg.packageName);
11618 if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) {
11619 // If the original was granted this permission, we take
11620 // that grant decision as read and propagate it to the
11622 if (sysPs.isPrivileged()) {
11626 // The system apk may have been updated with an older
11627 // version of the one on the data partition, but which
11628 // granted a new system permission that it didn't have
11629 // before. In this case we do want to allow the app to
11630 // now get the new permission if the ancestral apk is
11631 // privileged to get it.
11632 if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) {
11633 for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) {
11634 if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) {
11640 // Also if a privileged parent package on the system image or any of
11641 // its children requested a privileged permission, the updated child
11642 // packages can also get the permission.
11643 if (pkg.parentPackage != null) {
11644 final PackageSetting disabledSysParentPs = mSettings
11645 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
11646 if (disabledSysParentPs != null && disabledSysParentPs.pkg != null
11647 && disabledSysParentPs.isPrivileged()) {
11648 if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) {
11650 } else if (disabledSysParentPs.pkg.childPackages != null) {
11651 final int count = disabledSysParentPs.pkg.childPackages.size();
11652 for (int i = 0; i < count; i++) {
11653 PackageParser.Package disabledSysChildPkg =
11654 disabledSysParentPs.pkg.childPackages.get(i);
11655 if (isPackageRequestingPermission(disabledSysChildPkg,
11666 allowed = isPrivilegedApp(pkg);
11671 if (!allowed && (bp.protectionLevel
11672 & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
11673 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
11674 // If this was a previously normal/dangerous permission that got moved
11675 // to a system permission as part of the runtime permission redesign, then
11676 // we still want to blindly grant it to old apps.
11679 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
11680 && pkg.packageName.equals(mRequiredInstallerPackage)) {
11681 // If this permission is to be granted to the system installer and
11682 // this app is an installer, then it gets the permission.
11685 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
11686 && pkg.packageName.equals(mRequiredVerifierPackage)) {
11687 // If this permission is to be granted to the system verifier and
11688 // this app is a verifier, then it gets the permission.
11691 if (!allowed && (bp.protectionLevel
11692 & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
11693 && isSystemApp(pkg)) {
11694 // Any pre-installed system app is allowed to get this permission.
11697 if (!allowed && (bp.protectionLevel
11698 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
11699 // For development permissions, a development permission
11700 // is granted only if it was already granted.
11701 allowed = origPermissions.hasInstallPermission(perm);
11703 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0
11704 && pkg.packageName.equals(mSetupWizardPackage)) {
11705 // If this permission is to be granted to the system setup wizard and
11706 // this app is a setup wizard, then it gets the permission.
11713 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
11714 final int permCount = pkg.requestedPermissions.size();
11715 for (int j = 0; j < permCount; j++) {
11716 String requestedPermission = pkg.requestedPermissions.get(j);
11717 if (permission.equals(requestedPermission)) {
11724 final class ActivityIntentResolver
11725 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
11726 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
11727 boolean defaultOnly, int userId) {
11728 if (!sUserManager.exists(userId)) return null;
11729 mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
11730 return super.queryIntent(intent, resolvedType, defaultOnly, userId);
11733 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
11735 if (!sUserManager.exists(userId)) return null;
11737 return super.queryIntent(intent, resolvedType,
11738 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
11742 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
11743 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
11744 if (!sUserManager.exists(userId)) return null;
11745 if (packageActivities == null) {
11749 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
11750 final int N = packageActivities.size();
11751 ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
11752 new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
11754 ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
11755 for (int i = 0; i < N; ++i) {
11756 intentFilters = packageActivities.get(i).intents;
11757 if (intentFilters != null && intentFilters.size() > 0) {
11758 PackageParser.ActivityIntentInfo[] array =
11759 new PackageParser.ActivityIntentInfo[intentFilters.size()];
11760 intentFilters.toArray(array);
11761 listCut.add(array);
11764 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
11768 * Finds a privileged activity that matches the specified activity names.
11770 private PackageParser.Activity findMatchingActivity(
11771 List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
11772 for (PackageParser.Activity sysActivity : activityList) {
11773 if (sysActivity.info.name.equals(activityInfo.name)) {
11774 return sysActivity;
11776 if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
11777 return sysActivity;
11779 if (sysActivity.info.targetActivity != null) {
11780 if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
11781 return sysActivity;
11783 if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
11784 return sysActivity;
11791 public class IterGenerator<E> {
11792 public Iterator<E> generate(ActivityIntentInfo info) {
11797 public class ActionIterGenerator extends IterGenerator<String> {
11799 public Iterator<String> generate(ActivityIntentInfo info) {
11800 return info.actionsIterator();
11804 public class CategoriesIterGenerator extends IterGenerator<String> {
11806 public Iterator<String> generate(ActivityIntentInfo info) {
11807 return info.categoriesIterator();
11811 public class SchemesIterGenerator extends IterGenerator<String> {
11813 public Iterator<String> generate(ActivityIntentInfo info) {
11814 return info.schemesIterator();
11818 public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
11820 public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
11821 return info.authoritiesIterator();
11826 * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
11827 * MODIFIED. Do not pass in a list that should not be changed.
11829 private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
11830 IterGenerator<T> generator, Iterator<T> searchIterator) {
11831 // loop through the set of actions; every one must be found in the intent filter
11832 while (searchIterator.hasNext()) {
11833 // we must have at least one filter in the list to consider a match
11834 if (intentList.size() == 0) {
11838 final T searchAction = searchIterator.next();
11840 // loop through the set of intent filters
11841 final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
11842 while (intentIter.hasNext()) {
11843 final ActivityIntentInfo intentInfo = intentIter.next();
11844 boolean selectionFound = false;
11846 // loop through the intent filter's selection criteria; at least one
11847 // of them must match the searched criteria
11848 final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
11849 while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
11850 final T intentSelection = intentSelectionIter.next();
11851 if (intentSelection != null && intentSelection.equals(searchAction)) {
11852 selectionFound = true;
11857 // the selection criteria wasn't found in this filter's set; this filter
11858 // is not a potential match
11859 if (!selectionFound) {
11860 intentIter.remove();
11866 private boolean isProtectedAction(ActivityIntentInfo filter) {
11867 final Iterator<String> actionsIter = filter.actionsIterator();
11868 while (actionsIter != null && actionsIter.hasNext()) {
11869 final String filterAction = actionsIter.next();
11870 if (PROTECTED_ACTIONS.contains(filterAction)) {
11878 * Adjusts the priority of the given intent filter according to policy.
11881 * <li>The priority for non privileged applications is capped to '0'</li>
11882 * <li>The priority for protected actions on privileged applications is capped to '0'</li>
11883 * <li>The priority for unbundled updates to privileged applications is capped to the
11884 * priority defined on the system partition</li>
11887 * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
11888 * allowed to obtain any priority on any action.
11890 private void adjustPriority(
11891 List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
11892 // nothing to do; priority is fine as-is
11893 if (intent.getPriority() <= 0) {
11897 final ActivityInfo activityInfo = intent.activity.info;
11898 final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
11900 final boolean privilegedApp =
11901 ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
11902 if (!privilegedApp) {
11903 // non-privileged applications can never define a priority >0
11904 Slog.w(TAG, "Non-privileged app; cap priority to 0;"
11905 + " package: " + applicationInfo.packageName
11906 + " activity: " + intent.activity.className
11907 + " origPrio: " + intent.getPriority());
11908 intent.setPriority(0);
11912 if (systemActivities == null) {
11913 // the system package is not disabled; we're parsing the system partition
11914 if (isProtectedAction(intent)) {
11915 if (mDeferProtectedFilters) {
11916 // We can't deal with these just yet. No component should ever obtain a
11917 // >0 priority for a protected actions, with ONE exception -- the setup
11918 // wizard. The setup wizard, however, cannot be known until we're able to
11919 // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
11920 // until all intent filters have been processed. Chicken, meet egg.
11921 // Let the filter temporarily have a high priority and rectify the
11922 // priorities after all system packages have been scanned.
11923 mProtectedFilters.add(intent);
11924 if (DEBUG_FILTERS) {
11925 Slog.i(TAG, "Protected action; save for later;"
11926 + " package: " + applicationInfo.packageName
11927 + " activity: " + intent.activity.className
11928 + " origPrio: " + intent.getPriority());
11932 if (DEBUG_FILTERS && mSetupWizardPackage == null) {
11933 Slog.i(TAG, "No setup wizard;"
11934 + " All protected intents capped to priority 0");
11936 if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
11937 if (DEBUG_FILTERS) {
11938 Slog.i(TAG, "Found setup wizard;"
11939 + " allow priority " + intent.getPriority() + ";"
11940 + " package: " + intent.activity.info.packageName
11941 + " activity: " + intent.activity.className
11942 + " priority: " + intent.getPriority());
11944 // setup wizard gets whatever it wants
11947 Slog.w(TAG, "Protected action; cap priority to 0;"
11948 + " package: " + intent.activity.info.packageName
11949 + " activity: " + intent.activity.className
11950 + " origPrio: " + intent.getPriority());
11951 intent.setPriority(0);
11955 // privileged apps on the system image get whatever priority they request
11959 // privileged app unbundled update ... try to find the same activity
11960 final PackageParser.Activity foundActivity =
11961 findMatchingActivity(systemActivities, activityInfo);
11962 if (foundActivity == null) {
11963 // this is a new activity; it cannot obtain >0 priority
11964 if (DEBUG_FILTERS) {
11965 Slog.i(TAG, "New activity; cap priority to 0;"
11966 + " package: " + applicationInfo.packageName
11967 + " activity: " + intent.activity.className
11968 + " origPrio: " + intent.getPriority());
11970 intent.setPriority(0);
11974 // found activity, now check for filter equivalence
11976 // a shallow copy is enough; we modify the list, not its contents
11977 final List<ActivityIntentInfo> intentListCopy =
11978 new ArrayList<>(foundActivity.intents);
11979 final List<ActivityIntentInfo> foundFilters = findFilters(intent);
11981 // find matching action subsets
11982 final Iterator<String> actionsIterator = intent.actionsIterator();
11983 if (actionsIterator != null) {
11984 getIntentListSubset(
11985 intentListCopy, new ActionIterGenerator(), actionsIterator);
11986 if (intentListCopy.size() == 0) {
11987 // no more intents to match; we're not equivalent
11988 if (DEBUG_FILTERS) {
11989 Slog.i(TAG, "Mismatched action; cap priority to 0;"
11990 + " package: " + applicationInfo.packageName
11991 + " activity: " + intent.activity.className
11992 + " origPrio: " + intent.getPriority());
11994 intent.setPriority(0);
11999 // find matching category subsets
12000 final Iterator<String> categoriesIterator = intent.categoriesIterator();
12001 if (categoriesIterator != null) {
12002 getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
12003 categoriesIterator);
12004 if (intentListCopy.size() == 0) {
12005 // no more intents to match; we're not equivalent
12006 if (DEBUG_FILTERS) {
12007 Slog.i(TAG, "Mismatched category; cap priority to 0;"
12008 + " package: " + applicationInfo.packageName
12009 + " activity: " + intent.activity.className
12010 + " origPrio: " + intent.getPriority());
12012 intent.setPriority(0);
12017 // find matching schemes subsets
12018 final Iterator<String> schemesIterator = intent.schemesIterator();
12019 if (schemesIterator != null) {
12020 getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
12022 if (intentListCopy.size() == 0) {
12023 // no more intents to match; we're not equivalent
12024 if (DEBUG_FILTERS) {
12025 Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
12026 + " package: " + applicationInfo.packageName
12027 + " activity: " + intent.activity.className
12028 + " origPrio: " + intent.getPriority());
12030 intent.setPriority(0);
12035 // find matching authorities subsets
12036 final Iterator<IntentFilter.AuthorityEntry>
12037 authoritiesIterator = intent.authoritiesIterator();
12038 if (authoritiesIterator != null) {
12039 getIntentListSubset(intentListCopy,
12040 new AuthoritiesIterGenerator(),
12041 authoritiesIterator);
12042 if (intentListCopy.size() == 0) {
12043 // no more intents to match; we're not equivalent
12044 if (DEBUG_FILTERS) {
12045 Slog.i(TAG, "Mismatched authority; cap priority to 0;"
12046 + " package: " + applicationInfo.packageName
12047 + " activity: " + intent.activity.className
12048 + " origPrio: " + intent.getPriority());
12050 intent.setPriority(0);
12055 // we found matching filter(s); app gets the max priority of all intents
12056 int cappedPriority = 0;
12057 for (int i = intentListCopy.size() - 1; i >= 0; --i) {
12058 cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
12060 if (intent.getPriority() > cappedPriority) {
12061 if (DEBUG_FILTERS) {
12062 Slog.i(TAG, "Found matching filter(s);"
12063 + " cap priority to " + cappedPriority + ";"
12064 + " package: " + applicationInfo.packageName
12065 + " activity: " + intent.activity.className
12066 + " origPrio: " + intent.getPriority());
12068 intent.setPriority(cappedPriority);
12071 // all this for nothing; the requested priority was <= what was on the system
12074 public final void addActivity(PackageParser.Activity a, String type) {
12075 mActivities.put(a.getComponentName(), a);
12076 if (DEBUG_SHOW_INFO)
12078 TAG, " " + type + " " +
12079 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
12080 if (DEBUG_SHOW_INFO)
12081 Log.v(TAG, " Class=" + a.info.name);
12082 final int NI = a.intents.size();
12083 for (int j=0; j<NI; j++) {
12084 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12085 if ("activity".equals(type)) {
12086 final PackageSetting ps =
12087 mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
12088 final List<PackageParser.Activity> systemActivities =
12089 ps != null && ps.pkg != null ? ps.pkg.activities : null;
12090 adjustPriority(systemActivities, intent);
12092 if (DEBUG_SHOW_INFO) {
12093 Log.v(TAG, " IntentFilter:");
12094 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
12096 if (!intent.debugCheck()) {
12097 Log.w(TAG, "==> For Activity " + a.info.name);
12103 public final void removeActivity(PackageParser.Activity a, String type) {
12104 mActivities.remove(a.getComponentName());
12105 if (DEBUG_SHOW_INFO) {
12106 Log.v(TAG, " " + type + " "
12107 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
12108 : a.info.name) + ":");
12109 Log.v(TAG, " Class=" + a.info.name);
12111 final int NI = a.intents.size();
12112 for (int j=0; j<NI; j++) {
12113 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12114 if (DEBUG_SHOW_INFO) {
12115 Log.v(TAG, " IntentFilter:");
12116 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
12118 removeFilter(intent);
12123 protected boolean allowFilterResult(
12124 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
12125 ActivityInfo filterAi = filter.activity.info;
12126 for (int i=dest.size()-1; i>=0; i--) {
12127 ActivityInfo destAi = dest.get(i).activityInfo;
12128 if (destAi.name == filterAi.name
12129 && destAi.packageName == filterAi.packageName) {
12137 protected ActivityIntentInfo[] newArray(int size) {
12138 return new ActivityIntentInfo[size];
12142 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
12143 if (!sUserManager.exists(userId)) return true;
12144 PackageParser.Package p = filter.activity.owner;
12146 PackageSetting ps = (PackageSetting)p.mExtras;
12148 // System apps are never considered stopped for purposes of
12149 // filtering, because there may be no way for the user to
12150 // actually re-launch them.
12151 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
12152 && ps.getStopped(userId);
12159 protected boolean isPackageForFilter(String packageName,
12160 PackageParser.ActivityIntentInfo info) {
12161 return packageName.equals(info.activity.owner.packageName);
12165 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
12166 int match, int userId) {
12167 if (!sUserManager.exists(userId)) return null;
12168 if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
12171 final PackageParser.Activity activity = info.activity;
12172 PackageSetting ps = (PackageSetting) activity.owner.mExtras;
12176 final PackageUserState userState = ps.readUserState(userId);
12177 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags,
12178 userState, userId);
12182 final boolean matchVisibleToInstantApp =
12183 (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12184 final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12185 // throw out filters that aren't visible to ephemeral apps
12186 if (matchVisibleToInstantApp
12187 && !(info.isVisibleToInstantApp() || userState.instantApp)) {
12190 // throw out ephemeral filters if we're not explicitly requesting them
12191 if (!isInstantApp && userState.instantApp) {
12194 // throw out instant app filters if updates are available; will trigger
12195 // instant app resolution
12196 if (userState.instantApp && ps.isUpdateAvailable()) {
12199 final ResolveInfo res = new ResolveInfo();
12200 res.activityInfo = ai;
12201 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12204 if (info != null) {
12205 res.handleAllWebDataURI = info.handleAllWebDataURI();
12207 res.priority = info.getPriority();
12208 res.preferredOrder = activity.owner.mPreferredOrder;
12209 //System.out.println("Result: " + res.activityInfo.className +
12210 // " = " + res.priority);
12212 res.isDefault = info.hasDefault;
12213 res.labelRes = info.labelRes;
12214 res.nonLocalizedLabel = info.nonLocalizedLabel;
12215 if (userNeedsBadging(userId)) {
12216 res.noResourceId = true;
12218 res.icon = info.icon;
12220 res.iconResourceId = info.icon;
12221 res.system = res.activityInfo.applicationInfo.isSystemApp();
12222 res.instantAppAvailable = userState.instantApp;
12227 protected void sortResults(List<ResolveInfo> results) {
12228 Collections.sort(results, mResolvePrioritySorter);
12232 protected void dumpFilter(PrintWriter out, String prefix,
12233 PackageParser.ActivityIntentInfo filter) {
12234 out.print(prefix); out.print(
12235 Integer.toHexString(System.identityHashCode(filter.activity)));
12237 filter.activity.printComponentShortName(out);
12238 out.print(" filter ");
12239 out.println(Integer.toHexString(System.identityHashCode(filter)));
12243 protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
12244 return filter.activity;
12247 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12248 PackageParser.Activity activity = (PackageParser.Activity)label;
12249 out.print(prefix); out.print(
12250 Integer.toHexString(System.identityHashCode(activity)));
12252 activity.printComponentShortName(out);
12254 out.print(" ("); out.print(count); out.print(" filters)");
12259 // Keys are String (activity class name), values are Activity.
12260 private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
12261 = new ArrayMap<ComponentName, PackageParser.Activity>();
12262 private int mFlags;
12265 private final class ServiceIntentResolver
12266 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
12267 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12268 boolean defaultOnly, int userId) {
12269 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
12270 return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12273 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12275 if (!sUserManager.exists(userId)) return null;
12277 return super.queryIntent(intent, resolvedType,
12278 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12282 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12283 int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
12284 if (!sUserManager.exists(userId)) return null;
12285 if (packageServices == null) {
12289 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
12290 final int N = packageServices.size();
12291 ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
12292 new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
12294 ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
12295 for (int i = 0; i < N; ++i) {
12296 intentFilters = packageServices.get(i).intents;
12297 if (intentFilters != null && intentFilters.size() > 0) {
12298 PackageParser.ServiceIntentInfo[] array =
12299 new PackageParser.ServiceIntentInfo[intentFilters.size()];
12300 intentFilters.toArray(array);
12301 listCut.add(array);
12304 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12307 public final void addService(PackageParser.Service s) {
12308 mServices.put(s.getComponentName(), s);
12309 if (DEBUG_SHOW_INFO) {
12311 + (s.info.nonLocalizedLabel != null
12312 ? s.info.nonLocalizedLabel : s.info.name) + ":");
12313 Log.v(TAG, " Class=" + s.info.name);
12315 final int NI = s.intents.size();
12317 for (j=0; j<NI; j++) {
12318 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12319 if (DEBUG_SHOW_INFO) {
12320 Log.v(TAG, " IntentFilter:");
12321 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
12323 if (!intent.debugCheck()) {
12324 Log.w(TAG, "==> For Service " + s.info.name);
12330 public final void removeService(PackageParser.Service s) {
12331 mServices.remove(s.getComponentName());
12332 if (DEBUG_SHOW_INFO) {
12333 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null
12334 ? s.info.nonLocalizedLabel : s.info.name) + ":");
12335 Log.v(TAG, " Class=" + s.info.name);
12337 final int NI = s.intents.size();
12339 for (j=0; j<NI; j++) {
12340 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12341 if (DEBUG_SHOW_INFO) {
12342 Log.v(TAG, " IntentFilter:");
12343 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
12345 removeFilter(intent);
12350 protected boolean allowFilterResult(
12351 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
12352 ServiceInfo filterSi = filter.service.info;
12353 for (int i=dest.size()-1; i>=0; i--) {
12354 ServiceInfo destAi = dest.get(i).serviceInfo;
12355 if (destAi.name == filterSi.name
12356 && destAi.packageName == filterSi.packageName) {
12364 protected PackageParser.ServiceIntentInfo[] newArray(int size) {
12365 return new PackageParser.ServiceIntentInfo[size];
12369 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
12370 if (!sUserManager.exists(userId)) return true;
12371 PackageParser.Package p = filter.service.owner;
12373 PackageSetting ps = (PackageSetting)p.mExtras;
12375 // System apps are never considered stopped for purposes of
12376 // filtering, because there may be no way for the user to
12377 // actually re-launch them.
12378 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
12379 && ps.getStopped(userId);
12386 protected boolean isPackageForFilter(String packageName,
12387 PackageParser.ServiceIntentInfo info) {
12388 return packageName.equals(info.service.owner.packageName);
12392 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
12393 int match, int userId) {
12394 if (!sUserManager.exists(userId)) return null;
12395 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
12396 if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
12399 final PackageParser.Service service = info.service;
12400 PackageSetting ps = (PackageSetting) service.owner.mExtras;
12404 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
12405 ps.readUserState(userId), userId);
12409 final ResolveInfo res = new ResolveInfo();
12410 res.serviceInfo = si;
12411 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12412 res.filter = filter;
12414 res.priority = info.getPriority();
12415 res.preferredOrder = service.owner.mPreferredOrder;
12417 res.isDefault = info.hasDefault;
12418 res.labelRes = info.labelRes;
12419 res.nonLocalizedLabel = info.nonLocalizedLabel;
12420 res.icon = info.icon;
12421 res.system = res.serviceInfo.applicationInfo.isSystemApp();
12426 protected void sortResults(List<ResolveInfo> results) {
12427 Collections.sort(results, mResolvePrioritySorter);
12431 protected void dumpFilter(PrintWriter out, String prefix,
12432 PackageParser.ServiceIntentInfo filter) {
12433 out.print(prefix); out.print(
12434 Integer.toHexString(System.identityHashCode(filter.service)));
12436 filter.service.printComponentShortName(out);
12437 out.print(" filter ");
12438 out.println(Integer.toHexString(System.identityHashCode(filter)));
12442 protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
12443 return filter.service;
12446 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12447 PackageParser.Service service = (PackageParser.Service)label;
12448 out.print(prefix); out.print(
12449 Integer.toHexString(System.identityHashCode(service)));
12451 service.printComponentShortName(out);
12453 out.print(" ("); out.print(count); out.print(" filters)");
12458 // List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
12459 // final Iterator<ResolveInfo> i = resolveInfoList.iterator();
12460 // final List<ResolveInfo> retList = Lists.newArrayList();
12461 // while (i.hasNext()) {
12462 // final ResolveInfo resolveInfo = (ResolveInfo) i;
12463 // if (isEnabledLP(resolveInfo.serviceInfo)) {
12464 // retList.add(resolveInfo);
12470 // Keys are String (activity class name), values are Activity.
12471 private final ArrayMap<ComponentName, PackageParser.Service> mServices
12472 = new ArrayMap<ComponentName, PackageParser.Service>();
12473 private int mFlags;
12476 private final class ProviderIntentResolver
12477 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
12478 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12479 boolean defaultOnly, int userId) {
12480 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
12481 return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12484 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12486 if (!sUserManager.exists(userId))
12489 return super.queryIntent(intent, resolvedType,
12490 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12494 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12495 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
12496 if (!sUserManager.exists(userId))
12498 if (packageProviders == null) {
12502 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
12503 final int N = packageProviders.size();
12504 ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
12505 new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
12507 ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
12508 for (int i = 0; i < N; ++i) {
12509 intentFilters = packageProviders.get(i).intents;
12510 if (intentFilters != null && intentFilters.size() > 0) {
12511 PackageParser.ProviderIntentInfo[] array =
12512 new PackageParser.ProviderIntentInfo[intentFilters.size()];
12513 intentFilters.toArray(array);
12514 listCut.add(array);
12517 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12520 public final void addProvider(PackageParser.Provider p) {
12521 if (mProviders.containsKey(p.getComponentName())) {
12522 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
12526 mProviders.put(p.getComponentName(), p);
12527 if (DEBUG_SHOW_INFO) {
12529 + (p.info.nonLocalizedLabel != null
12530 ? p.info.nonLocalizedLabel : p.info.name) + ":");
12531 Log.v(TAG, " Class=" + p.info.name);
12533 final int NI = p.intents.size();
12535 for (j = 0; j < NI; j++) {
12536 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
12537 if (DEBUG_SHOW_INFO) {
12538 Log.v(TAG, " IntentFilter:");
12539 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
12541 if (!intent.debugCheck()) {
12542 Log.w(TAG, "==> For Provider " + p.info.name);
12548 public final void removeProvider(PackageParser.Provider p) {
12549 mProviders.remove(p.getComponentName());
12550 if (DEBUG_SHOW_INFO) {
12551 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null
12552 ? p.info.nonLocalizedLabel : p.info.name) + ":");
12553 Log.v(TAG, " Class=" + p.info.name);
12555 final int NI = p.intents.size();
12557 for (j = 0; j < NI; j++) {
12558 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
12559 if (DEBUG_SHOW_INFO) {
12560 Log.v(TAG, " IntentFilter:");
12561 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
12563 removeFilter(intent);
12568 protected boolean allowFilterResult(
12569 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
12570 ProviderInfo filterPi = filter.provider.info;
12571 for (int i = dest.size() - 1; i >= 0; i--) {
12572 ProviderInfo destPi = dest.get(i).providerInfo;
12573 if (destPi.name == filterPi.name
12574 && destPi.packageName == filterPi.packageName) {
12582 protected PackageParser.ProviderIntentInfo[] newArray(int size) {
12583 return new PackageParser.ProviderIntentInfo[size];
12587 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
12588 if (!sUserManager.exists(userId))
12590 PackageParser.Package p = filter.provider.owner;
12592 PackageSetting ps = (PackageSetting) p.mExtras;
12594 // System apps are never considered stopped for purposes of
12595 // filtering, because there may be no way for the user to
12596 // actually re-launch them.
12597 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
12598 && ps.getStopped(userId);
12605 protected boolean isPackageForFilter(String packageName,
12606 PackageParser.ProviderIntentInfo info) {
12607 return packageName.equals(info.provider.owner.packageName);
12611 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
12612 int match, int userId) {
12613 if (!sUserManager.exists(userId))
12615 final PackageParser.ProviderIntentInfo info = filter;
12616 if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
12619 final PackageParser.Provider provider = info.provider;
12620 PackageSetting ps = (PackageSetting) provider.owner.mExtras;
12624 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
12625 ps.readUserState(userId), userId);
12629 final ResolveInfo res = new ResolveInfo();
12630 res.providerInfo = pi;
12631 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
12632 res.filter = filter;
12634 res.priority = info.getPriority();
12635 res.preferredOrder = provider.owner.mPreferredOrder;
12637 res.isDefault = info.hasDefault;
12638 res.labelRes = info.labelRes;
12639 res.nonLocalizedLabel = info.nonLocalizedLabel;
12640 res.icon = info.icon;
12641 res.system = res.providerInfo.applicationInfo.isSystemApp();
12646 protected void sortResults(List<ResolveInfo> results) {
12647 Collections.sort(results, mResolvePrioritySorter);
12651 protected void dumpFilter(PrintWriter out, String prefix,
12652 PackageParser.ProviderIntentInfo filter) {
12655 Integer.toHexString(System.identityHashCode(filter.provider)));
12657 filter.provider.printComponentShortName(out);
12658 out.print(" filter ");
12659 out.println(Integer.toHexString(System.identityHashCode(filter)));
12663 protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
12664 return filter.provider;
12667 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12668 PackageParser.Provider provider = (PackageParser.Provider)label;
12669 out.print(prefix); out.print(
12670 Integer.toHexString(System.identityHashCode(provider)));
12672 provider.printComponentShortName(out);
12674 out.print(" ("); out.print(count); out.print(" filters)");
12679 private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
12680 = new ArrayMap<ComponentName, PackageParser.Provider>();
12681 private int mFlags;
12684 static final class EphemeralIntentResolver
12685 extends IntentResolver<AuxiliaryResolveInfo, AuxiliaryResolveInfo> {
12687 * The result that has the highest defined order. Ordering applies on a
12688 * per-package basis. Mapping is from package name to Pair of order and
12689 * EphemeralResolveInfo.
12691 * NOTE: This is implemented as a field variable for convenience and efficiency.
12692 * By having a field variable, we're able to track filter ordering as soon as
12693 * a non-zero order is defined. Otherwise, multiple loops across the result set
12694 * would be needed to apply ordering. If the intent resolver becomes re-entrant,
12695 * this needs to be contained entirely within {@link #filterResults}.
12697 final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
12700 protected AuxiliaryResolveInfo[] newArray(int size) {
12701 return new AuxiliaryResolveInfo[size];
12705 protected boolean isPackageForFilter(String packageName, AuxiliaryResolveInfo responseObj) {
12710 protected AuxiliaryResolveInfo newResult(AuxiliaryResolveInfo responseObj, int match,
12712 if (!sUserManager.exists(userId)) {
12715 final String packageName = responseObj.resolveInfo.getPackageName();
12716 final Integer order = responseObj.getOrder();
12717 final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
12718 mOrderResult.get(packageName);
12719 // ordering is enabled and this item's order isn't high enough
12720 if (lastOrderResult != null && lastOrderResult.first >= order) {
12723 final InstantAppResolveInfo res = responseObj.resolveInfo;
12725 // non-zero order, enable ordering
12726 mOrderResult.put(packageName, new Pair<>(order, res));
12728 return responseObj;
12732 protected void filterResults(List<AuxiliaryResolveInfo> results) {
12733 // only do work if ordering is enabled [most of the time it won't be]
12734 if (mOrderResult.size() == 0) {
12737 int resultSize = results.size();
12738 for (int i = 0; i < resultSize; i++) {
12739 final InstantAppResolveInfo info = results.get(i).resolveInfo;
12740 final String packageName = info.getPackageName();
12741 final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName);
12742 if (savedInfo == null) {
12743 // package doesn't having ordering
12746 if (savedInfo.second == info) {
12747 // circled back to the highest ordered item; remove from order list
12748 mOrderResult.remove(savedInfo);
12749 if (mOrderResult.size() == 0) {
12750 // no more ordered items
12755 // item has a worse order, remove it from the result list
12763 private static final Comparator<ResolveInfo> mResolvePrioritySorter =
12764 new Comparator<ResolveInfo>() {
12765 public int compare(ResolveInfo r1, ResolveInfo r2) {
12766 int v1 = r1.priority;
12767 int v2 = r2.priority;
12768 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
12770 return (v1 > v2) ? -1 : 1;
12772 v1 = r1.preferredOrder;
12773 v2 = r2.preferredOrder;
12775 return (v1 > v2) ? -1 : 1;
12777 if (r1.isDefault != r2.isDefault) {
12778 return r1.isDefault ? -1 : 1;
12782 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
12784 return (v1 > v2) ? -1 : 1;
12786 if (r1.system != r2.system) {
12787 return r1.system ? -1 : 1;
12789 if (r1.activityInfo != null) {
12790 return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
12792 if (r1.serviceInfo != null) {
12793 return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
12795 if (r1.providerInfo != null) {
12796 return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
12802 private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
12803 new Comparator<ProviderInfo>() {
12804 public int compare(ProviderInfo p1, ProviderInfo p2) {
12805 final int v1 = p1.initOrder;
12806 final int v2 = p2.initOrder;
12807 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
12811 final void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
12812 final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
12813 final int[] userIds) {
12814 mHandler.post(new Runnable() {
12816 public void run() {
12818 final IActivityManager am = ActivityManager.getService();
12819 if (am == null) return;
12820 final int[] resolvedUserIds;
12821 if (userIds == null) {
12822 resolvedUserIds = am.getRunningUserIds();
12824 resolvedUserIds = userIds;
12826 for (int id : resolvedUserIds) {
12827 final Intent intent = new Intent(action,
12828 pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
12829 if (extras != null) {
12830 intent.putExtras(extras);
12832 if (targetPkg != null) {
12833 intent.setPackage(targetPkg);
12835 // Modify the UID when posting to other users
12836 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
12837 if (uid > 0 && UserHandle.getUserId(uid) != id) {
12838 uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
12839 intent.putExtra(Intent.EXTRA_UID, uid);
12841 intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
12842 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
12843 if (DEBUG_BROADCASTS) {
12844 RuntimeException here = new RuntimeException("here");
12845 here.fillInStackTrace();
12846 Slog.d(TAG, "Sending to user " + id + ": "
12847 + intent.toShortString(false, true, false, false)
12848 + " " + intent.getExtras(), here);
12850 am.broadcastIntent(null, intent, null, finishedReceiver,
12851 0, null, null, null, android.app.AppOpsManager.OP_NONE,
12852 null, finishedReceiver != null, false, id);
12854 } catch (RemoteException ex) {
12861 * Check if the external storage media is available. This is true if there
12862 * is a mounted external storage medium or if the external storage is
12865 private boolean isExternalMediaAvailable() {
12866 return mMediaMounted || Environment.isExternalStorageEmulated();
12870 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
12872 synchronized (mPackages) {
12873 if (!isExternalMediaAvailable()) {
12874 // If the external storage is no longer mounted at this point,
12875 // the caller may not have been able to delete all of this
12876 // packages files and can not delete any more. Bail.
12879 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
12880 if (lastPackage != null) {
12881 pkgs.remove(lastPackage);
12883 if (pkgs.size() > 0) {
12884 return pkgs.get(0);
12890 void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
12891 final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
12892 userId, andCode ? 1 : 0, packageName);
12893 if (mSystemReady) {
12894 msg.sendToTarget();
12896 if (mPostSystemReadyMessages == null) {
12897 mPostSystemReadyMessages = new ArrayList<>();
12899 mPostSystemReadyMessages.add(msg);
12903 void startCleaningPackages() {
12905 if (!isExternalMediaAvailable()) {
12908 synchronized (mPackages) {
12909 if (mSettings.mPackagesToBeCleaned.isEmpty()) {
12913 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
12914 intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
12915 IActivityManager am = ActivityManager.getService();
12918 getDeviceIdleController().addPowerSaveTempWhitelistApp(Process.SYSTEM_UID,
12919 DEFAULT_CONTAINER_PACKAGE, DEFAULT_CONTAINER_WHITELIST_DURATION,
12920 UserHandle.USER_SYSTEM, false, "cleaning packages");
12921 am.startService(null, intent, null, -1, null, false, mContext.getOpPackageName(),
12922 UserHandle.USER_SYSTEM);
12923 } catch (RemoteException e) {
12929 public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
12930 int installFlags, String installerPackageName, int userId) {
12931 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
12933 final int callingUid = Binder.getCallingUid();
12934 enforceCrossUserPermission(callingUid, userId,
12935 true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");
12937 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
12939 if (observer != null) {
12940 observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
12942 } catch (RemoteException re) {
12947 if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
12948 installFlags |= PackageManager.INSTALL_FROM_ADB;
12951 // Caller holds INSTALL_PACKAGES permission, so we're less strict
12952 // about installerPackageName.
12954 installFlags &= ~PackageManager.INSTALL_FROM_ADB;
12955 installFlags &= ~PackageManager.INSTALL_ALL_USERS;
12959 if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
12960 user = UserHandle.ALL;
12962 user = new UserHandle(userId);
12965 // Only system components can circumvent runtime permissions when installing.
12966 if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
12967 && mContext.checkCallingOrSelfPermission(Manifest.permission
12968 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
12969 throw new SecurityException("You need the "
12970 + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
12971 + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
12974 if ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0
12975 || (installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
12976 throw new IllegalArgumentException(
12977 "New installs into ASEC containers no longer supported");
12980 final File originFile = new File(originPath);
12981 final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
12983 final Message msg = mHandler.obtainMessage(INIT_COPY);
12984 final VerificationInfo verificationInfo = new VerificationInfo(
12985 null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);
12986 final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,
12987 installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,
12988 null /*packageAbiOverride*/, null /*grantedPermissions*/,
12989 null /*certificates*/, PackageManager.INSTALL_REASON_UNKNOWN);
12990 params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
12993 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
12994 System.identityHashCode(msg.obj));
12995 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
12996 System.identityHashCode(msg.obj));
12998 mHandler.sendMessage(msg);
13003 * Ensure that the install reason matches what we know about the package installer (e.g. whether
13004 * it is acting on behalf on an enterprise or the user).
13006 * Note that the ordering of the conditionals in this method is important. The checks we perform
13007 * are as follows, in this order:
13009 * 1) If the install is being performed by a system app, we can trust the app to have set the
13010 * install reason correctly. Thus, we pass through the install reason unchanged, no matter
13012 * 2) If the install is being performed by a device or profile owner app, the install reason
13013 * should be enterprise policy. However, we cannot be sure that the device or profile owner
13014 * set the install reason correctly. If the app targets an older SDK version where install
13015 * reasons did not exist yet, or if the app author simply forgot, the install reason may be
13016 * unset or wrong. Thus, we force the install reason to be enterprise policy.
13017 * 3) In all other cases, the install is being performed by a regular app that is neither part
13018 * of the system nor a device or profile owner. We have no reason to believe that this app is
13019 * acting on behalf of the enterprise admin. Thus, we check whether the install reason was
13020 * set to enterprise policy and if so, change it to unknown instead.
13022 private int fixUpInstallReason(String installerPackageName, int installerUid,
13023 int installReason) {
13024 if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
13025 == PERMISSION_GRANTED) {
13026 // If the install is being performed by a system app, we trust that app to have set the
13027 // install reason correctly.
13028 return installReason;
13031 final IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
13032 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
13034 ComponentName owner = null;
13036 owner = dpm.getDeviceOwnerComponent(true /* callingUserOnly */);
13037 if (owner == null) {
13038 owner = dpm.getProfileOwner(UserHandle.getUserId(installerUid));
13040 } catch (RemoteException e) {
13042 if (owner != null && owner.getPackageName().equals(installerPackageName)) {
13043 // If the install is being performed by a device or profile owner, the install
13044 // reason should be enterprise policy.
13045 return PackageManager.INSTALL_REASON_POLICY;
13049 if (installReason == PackageManager.INSTALL_REASON_POLICY) {
13050 // If the install is being performed by a regular app (i.e. neither system app nor
13051 // device or profile owner), we have no reason to believe that the app is acting on
13052 // behalf of an enterprise. If the app set the install reason to enterprise policy,
13053 // change it to unknown instead.
13054 return PackageManager.INSTALL_REASON_UNKNOWN;
13057 // If the install is being performed by a regular app and the install reason was set to any
13058 // value but enterprise policy, leave the install reason unchanged.
13059 return installReason;
13062 void installStage(String packageName, File stagedDir, String stagedCid,
13063 IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
13064 String installerPackageName, int installerUid, UserHandle user,
13065 Certificate[][] certificates) {
13066 if (DEBUG_EPHEMERAL) {
13067 if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
13068 Slog.d(TAG, "Ephemeral install of " + packageName);
13071 final VerificationInfo verificationInfo = new VerificationInfo(
13072 sessionParams.originatingUri, sessionParams.referrerUri,
13073 sessionParams.originatingUid, installerUid);
13075 final OriginInfo origin;
13076 if (stagedDir != null) {
13077 origin = OriginInfo.fromStagedFile(stagedDir);
13079 origin = OriginInfo.fromStagedContainer(stagedCid);
13082 final Message msg = mHandler.obtainMessage(INIT_COPY);
13083 final int installReason = fixUpInstallReason(installerPackageName, installerUid,
13084 sessionParams.installReason);
13085 final InstallParams params = new InstallParams(origin, null, observer,
13086 sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
13087 verificationInfo, user, sessionParams.abiOverride,
13088 sessionParams.grantedRuntimePermissions, certificates, installReason);
13089 params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
13092 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
13093 System.identityHashCode(msg.obj));
13094 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
13095 System.identityHashCode(msg.obj));
13097 mHandler.sendMessage(msg);
13100 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
13102 final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
13103 sendPackageAddedForNewUsers(packageName, isSystem, pkgSetting.appId, userId);
13106 private void sendPackageAddedForNewUsers(String packageName, boolean isSystem,
13107 int appId, int... userIds) {
13108 if (ArrayUtils.isEmpty(userIds)) {
13111 Bundle extras = new Bundle(1);
13112 // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
13113 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userIds[0], appId));
13115 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
13116 packageName, extras, 0, null, null, userIds);
13118 mHandler.post(() -> {
13119 for (int userId : userIds) {
13120 sendBootCompletedBroadcastToSystemApp(packageName, userId);
13128 * The just-installed/enabled app is bundled on the system, so presumed to be able to run
13129 * automatically without needing an explicit launch.
13130 * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
13132 private void sendBootCompletedBroadcastToSystemApp(String packageName, int userId) {
13133 // If user is not running, the app didn't miss any broadcast
13134 if (!mUserManagerInternal.isUserRunning(userId)) {
13137 final IActivityManager am = ActivityManager.getService();
13139 // Deliver LOCKED_BOOT_COMPLETED first
13140 Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
13141 .setPackage(packageName);
13142 final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
13143 am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
13144 android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13146 // Deliver BOOT_COMPLETED only if user is unlocked
13147 if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
13148 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
13149 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
13150 android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13152 } catch (RemoteException e) {
13153 throw e.rethrowFromSystemServer();
13158 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
13160 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13161 PackageSetting pkgSetting;
13162 final int uid = Binder.getCallingUid();
13163 enforceCrossUserPermission(uid, userId,
13164 true /* requireFullPermission */, true /* checkShell */,
13165 "setApplicationHiddenSetting for user " + userId);
13167 if (hidden && isPackageDeviceAdmin(packageName, userId)) {
13168 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
13172 long callingId = Binder.clearCallingIdentity();
13174 boolean sendAdded = false;
13175 boolean sendRemoved = false;
13177 synchronized (mPackages) {
13178 pkgSetting = mSettings.mPackages.get(packageName);
13179 if (pkgSetting == null) {
13182 // Do not allow "android" is being disabled
13183 if ("android".equals(packageName)) {
13184 Slog.w(TAG, "Cannot hide package: android");
13187 // Cannot hide static shared libs as they are considered
13188 // a part of the using app (emulating static linking). Also
13189 // static libs are installed always on internal storage.
13190 PackageParser.Package pkg = mPackages.get(packageName);
13191 if (pkg != null && pkg.staticSharedLibName != null) {
13192 Slog.w(TAG, "Cannot hide package: " + packageName
13193 + " providing static shared library: "
13194 + pkg.staticSharedLibName);
13197 // Only allow protected packages to hide themselves.
13198 if (hidden && !UserHandle.isSameApp(uid, pkgSetting.appId)
13199 && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13200 Slog.w(TAG, "Not hiding protected package: " + packageName);
13204 if (pkgSetting.getHidden(userId) != hidden) {
13205 pkgSetting.setHidden(hidden, userId);
13206 mSettings.writePackageRestrictionsLPr(userId);
13208 sendRemoved = true;
13215 sendPackageAddedForUser(packageName, pkgSetting, userId);
13219 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
13221 sendApplicationHiddenForUser(packageName, pkgSetting, userId);
13225 Binder.restoreCallingIdentity(callingId);
13230 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
13232 final PackageRemovedInfo info = new PackageRemovedInfo();
13233 info.removedPackage = packageName;
13234 info.removedUsers = new int[] {userId};
13235 info.uid = UserHandle.getUid(userId, pkgSetting.appId);
13236 info.sendPackageRemovedBroadcasts(true /*killApp*/);
13239 private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
13240 if (pkgList.length > 0) {
13241 Bundle extras = new Bundle(1);
13242 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
13244 sendPackageBroadcast(
13245 suspended ? Intent.ACTION_PACKAGES_SUSPENDED
13246 : Intent.ACTION_PACKAGES_UNSUSPENDED,
13247 null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
13248 new int[] {userId});
13253 * Returns true if application is not found or there was an error. Otherwise it returns
13254 * the hidden state of the package for the given user.
13257 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
13258 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13259 enforceCrossUserPermission(Binder.getCallingUid(), userId,
13260 true /* requireFullPermission */, false /* checkShell */,
13261 "getApplicationHidden for user " + userId);
13262 PackageSetting pkgSetting;
13263 long callingId = Binder.clearCallingIdentity();
13266 synchronized (mPackages) {
13267 pkgSetting = mSettings.mPackages.get(packageName);
13268 if (pkgSetting == null) {
13271 return pkgSetting.getHidden(userId);
13274 Binder.restoreCallingIdentity(callingId);
13282 public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
13283 int installReason) {
13284 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
13286 PackageSetting pkgSetting;
13287 final int uid = Binder.getCallingUid();
13288 enforceCrossUserPermission(uid, userId,
13289 true /* requireFullPermission */, true /* checkShell */,
13290 "installExistingPackage for user " + userId);
13291 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
13292 return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
13295 long callingId = Binder.clearCallingIdentity();
13297 boolean installed = false;
13298 final boolean instantApp =
13299 (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
13300 final boolean fullApp =
13301 (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
13304 synchronized (mPackages) {
13305 pkgSetting = mSettings.mPackages.get(packageName);
13306 if (pkgSetting == null) {
13307 return PackageManager.INSTALL_FAILED_INVALID_URI;
13309 if (!pkgSetting.getInstalled(userId)) {
13310 pkgSetting.setInstalled(true, userId);
13311 pkgSetting.setHidden(false, userId);
13312 pkgSetting.setInstallReason(installReason, userId);
13313 mSettings.writePackageRestrictionsLPr(userId);
13314 mSettings.writeKernelMappingLPr(pkgSetting);
13316 } else if (fullApp && pkgSetting.getInstantApp(userId)) {
13317 // upgrade app from instant to full; we don't allow app downgrade
13320 setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
13324 if (pkgSetting.pkg != null) {
13325 synchronized (mInstallLock) {
13326 // We don't need to freeze for a brand new install
13327 prepareAppDataAfterInstallLIF(pkgSetting.pkg);
13330 sendPackageAddedForUser(packageName, pkgSetting, userId);
13331 synchronized (mPackages) {
13332 updateSequenceNumberLP(packageName, new int[]{ userId });
13336 Binder.restoreCallingIdentity(callingId);
13339 return PackageManager.INSTALL_SUCCEEDED;
13342 void setInstantAppForUser(PackageSetting pkgSetting, int userId,
13343 boolean instantApp, boolean fullApp) {
13344 // no state specified; do nothing
13345 if (!instantApp && !fullApp) {
13348 if (userId != UserHandle.USER_ALL) {
13349 if (instantApp && !pkgSetting.getInstantApp(userId)) {
13350 pkgSetting.setInstantApp(true /*instantApp*/, userId);
13351 } else if (fullApp && pkgSetting.getInstantApp(userId)) {
13352 pkgSetting.setInstantApp(false /*instantApp*/, userId);
13355 for (int currentUserId : sUserManager.getUserIds()) {
13356 if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
13357 pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
13358 } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
13359 pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
13365 boolean isUserRestricted(int userId, String restrictionKey) {
13366 Bundle restrictions = sUserManager.getUserRestrictions(userId);
13367 if (restrictions.getBoolean(restrictionKey, false)) {
13368 Log.w(TAG, "User is restricted: " + restrictionKey);
13375 public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
13377 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13378 enforceCrossUserPermission(Binder.getCallingUid(), userId,
13379 true /* requireFullPermission */, true /* checkShell */,
13380 "setPackagesSuspended for user " + userId);
13382 if (ArrayUtils.isEmpty(packageNames)) {
13383 return packageNames;
13386 // List of package names for whom the suspended state has changed.
13387 List<String> changedPackages = new ArrayList<>(packageNames.length);
13388 // List of package names for whom the suspended state is not set as requested in this
13390 List<String> unactionedPackages = new ArrayList<>(packageNames.length);
13391 long callingId = Binder.clearCallingIdentity();
13393 for (int i = 0; i < packageNames.length; i++) {
13394 String packageName = packageNames[i];
13395 boolean changed = false;
13397 synchronized (mPackages) {
13398 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
13399 if (pkgSetting == null) {
13400 Slog.w(TAG, "Could not find package setting for package \"" + packageName
13401 + "\". Skipping suspending/un-suspending.");
13402 unactionedPackages.add(packageName);
13405 appId = pkgSetting.appId;
13406 if (pkgSetting.getSuspended(userId) != suspended) {
13407 if (!canSuspendPackageForUserLocked(packageName, userId)) {
13408 unactionedPackages.add(packageName);
13411 pkgSetting.setSuspended(suspended, userId);
13412 mSettings.writePackageRestrictionsLPr(userId);
13414 changedPackages.add(packageName);
13418 if (changed && suspended) {
13419 killApplication(packageName, UserHandle.getUid(userId, appId),
13420 "suspending package");
13424 Binder.restoreCallingIdentity(callingId);
13427 if (!changedPackages.isEmpty()) {
13428 sendPackagesSuspendedForUser(changedPackages.toArray(
13429 new String[changedPackages.size()]), userId, suspended);
13432 return unactionedPackages.toArray(new String[unactionedPackages.size()]);
13436 public boolean isPackageSuspendedForUser(String packageName, int userId) {
13437 enforceCrossUserPermission(Binder.getCallingUid(), userId,
13438 true /* requireFullPermission */, false /* checkShell */,
13439 "isPackageSuspendedForUser for user " + userId);
13440 synchronized (mPackages) {
13441 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
13442 if (pkgSetting == null) {
13443 throw new IllegalArgumentException("Unknown target package: " + packageName);
13445 return pkgSetting.getSuspended(userId);
13449 private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
13450 if (isPackageDeviceAdmin(packageName, userId)) {
13451 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13452 + "\": has an active device admin");
13456 String activeLauncherPackageName = getActiveLauncherPackageName(userId);
13457 if (packageName.equals(activeLauncherPackageName)) {
13458 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13459 + "\": contains the active launcher");
13463 if (packageName.equals(mRequiredInstallerPackage)) {
13464 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13465 + "\": required for package installation");
13469 if (packageName.equals(mRequiredUninstallerPackage)) {
13470 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13471 + "\": required for package uninstallation");
13475 if (packageName.equals(mRequiredVerifierPackage)) {
13476 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13477 + "\": required for package verification");
13481 if (packageName.equals(getDefaultDialerPackageName(userId))) {
13482 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13483 + "\": is the default dialer");
13487 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13488 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13489 + "\": protected package");
13493 // Cannot suspend static shared libs as they are considered
13494 // a part of the using app (emulating static linking). Also
13495 // static libs are installed always on internal storage.
13496 PackageParser.Package pkg = mPackages.get(packageName);
13497 if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
13498 Slog.w(TAG, "Cannot suspend package: " + packageName
13499 + " providing static shared library: "
13500 + pkg.staticSharedLibName);
13507 private String getActiveLauncherPackageName(int userId) {
13508 Intent intent = new Intent(Intent.ACTION_MAIN);
13509 intent.addCategory(Intent.CATEGORY_HOME);
13510 ResolveInfo resolveInfo = resolveIntent(
13512 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
13513 PackageManager.MATCH_DEFAULT_ONLY,
13516 return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
13519 private String getDefaultDialerPackageName(int userId) {
13520 synchronized (mPackages) {
13521 return mSettings.getDefaultDialerPackageNameLPw(userId);
13526 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
13527 mContext.enforceCallingOrSelfPermission(
13528 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13529 "Only package verification agents can verify applications");
13531 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
13532 final PackageVerificationResponse response = new PackageVerificationResponse(
13533 verificationCode, Binder.getCallingUid());
13535 msg.obj = response;
13536 mHandler.sendMessage(msg);
13540 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
13541 long millisecondsToDelay) {
13542 mContext.enforceCallingOrSelfPermission(
13543 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13544 "Only package verification agents can extend verification timeouts");
13546 final PackageVerificationState state = mPendingVerification.get(id);
13547 final PackageVerificationResponse response = new PackageVerificationResponse(
13548 verificationCodeAtTimeout, Binder.getCallingUid());
13550 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
13551 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
13553 if (millisecondsToDelay < 0) {
13554 millisecondsToDelay = 0;
13556 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
13557 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
13558 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
13561 if ((state != null) && !state.timeoutExtended()) {
13562 state.extendTimeout();
13564 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
13566 msg.obj = response;
13567 mHandler.sendMessageDelayed(msg, millisecondsToDelay);
13571 private void broadcastPackageVerified(int verificationId, Uri packageUri,
13572 int verificationCode, UserHandle user) {
13573 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
13574 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
13575 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
13576 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
13577 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
13579 mContext.sendBroadcastAsUser(intent, user,
13580 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
13583 private ComponentName matchComponentForVerifier(String packageName,
13584 List<ResolveInfo> receivers) {
13585 ActivityInfo targetReceiver = null;
13587 final int NR = receivers.size();
13588 for (int i = 0; i < NR; i++) {
13589 final ResolveInfo info = receivers.get(i);
13590 if (info.activityInfo == null) {
13594 if (packageName.equals(info.activityInfo.packageName)) {
13595 targetReceiver = info.activityInfo;
13600 if (targetReceiver == null) {
13604 return new ComponentName(targetReceiver.packageName, targetReceiver.name);
13607 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
13608 List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
13609 if (pkgInfo.verifiers.length == 0) {
13613 final int N = pkgInfo.verifiers.length;
13614 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
13615 for (int i = 0; i < N; i++) {
13616 final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
13618 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
13620 if (comp == null) {
13624 final int verifierUid = getUidForVerifier(verifierInfo);
13625 if (verifierUid == -1) {
13629 if (DEBUG_VERIFY) {
13630 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
13631 + " with the correct signature");
13633 sufficientVerifiers.add(comp);
13634 verificationState.addSufficientVerifier(verifierUid);
13637 return sufficientVerifiers;
13640 private int getUidForVerifier(VerifierInfo verifierInfo) {
13641 synchronized (mPackages) {
13642 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
13645 } else if (pkg.mSignatures.length != 1) {
13646 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
13647 + " has more than one signature; ignoring");
13652 * If the public key of the package's signature does not match
13653 * our expected public key, then this is a different package and
13657 final byte[] expectedPublicKey;
13659 final Signature verifierSig = pkg.mSignatures[0];
13660 final PublicKey publicKey = verifierSig.getPublicKey();
13661 expectedPublicKey = publicKey.getEncoded();
13662 } catch (CertificateException e) {
13666 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
13668 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
13669 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
13670 + " does not have the expected public key; ignoring");
13674 return pkg.applicationInfo.uid;
13679 public void finishPackageInstall(int token, boolean didLaunch) {
13680 enforceSystemOrRoot("Only the system is allowed to finish installs");
13682 if (DEBUG_INSTALL) {
13683 Slog.v(TAG, "BM finishing package install for " + token);
13685 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
13687 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
13688 mHandler.sendMessage(msg);
13692 * Get the verification agent timeout.
13694 * @return verification timeout in milliseconds
13696 private long getVerificationTimeout() {
13697 return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
13698 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
13699 DEFAULT_VERIFICATION_TIMEOUT);
13703 * Get the default verification agent response code.
13705 * @return default verification response code
13707 private int getDefaultVerificationResponse() {
13708 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
13709 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
13710 DEFAULT_VERIFICATION_RESPONSE);
13714 * Check whether or not package verification has been enabled.
13716 * @return true if verification should be performed
13718 private boolean isVerificationEnabled(int userId, int installFlags) {
13719 if (!DEFAULT_VERIFY_ENABLE) {
13723 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
13725 // Check if installing from ADB
13726 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
13727 // Do not run verification in a test harness environment
13728 if (ActivityManager.isRunningInTestHarness()) {
13731 if (ensureVerifyAppsEnabled) {
13734 // Check if the developer does not want package verification for ADB installs
13735 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
13736 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
13741 if (ensureVerifyAppsEnabled) {
13745 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
13746 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
13750 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
13751 throws RemoteException {
13752 mContext.enforceCallingOrSelfPermission(
13753 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
13754 "Only intentfilter verification agents can verify applications");
13756 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
13757 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
13758 Binder.getCallingUid(), verificationCode, failedDomains);
13760 msg.obj = response;
13761 mHandler.sendMessage(msg);
13765 public int getIntentVerificationStatus(String packageName, int userId) {
13766 synchronized (mPackages) {
13767 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
13772 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
13773 mContext.enforceCallingOrSelfPermission(
13774 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
13776 boolean result = false;
13777 synchronized (mPackages) {
13778 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
13781 scheduleWritePackageRestrictionsLocked(userId);
13787 public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
13788 String packageName) {
13789 synchronized (mPackages) {
13790 return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
13795 public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
13796 if (TextUtils.isEmpty(packageName)) {
13797 return ParceledListSlice.emptyList();
13799 synchronized (mPackages) {
13800 PackageParser.Package pkg = mPackages.get(packageName);
13801 if (pkg == null || pkg.activities == null) {
13802 return ParceledListSlice.emptyList();
13804 final int count = pkg.activities.size();
13805 ArrayList<IntentFilter> result = new ArrayList<>();
13806 for (int n=0; n<count; n++) {
13807 PackageParser.Activity activity = pkg.activities.get(n);
13808 if (activity.intents != null && activity.intents.size() > 0) {
13809 result.addAll(activity.intents);
13812 return new ParceledListSlice<>(result);
13817 public boolean setDefaultBrowserPackageName(String packageName, int userId) {
13818 mContext.enforceCallingOrSelfPermission(
13819 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
13821 synchronized (mPackages) {
13822 boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
13823 if (packageName != null) {
13824 result |= updateIntentVerificationStatus(packageName,
13825 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS,
13827 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
13828 packageName, userId);
13835 public String getDefaultBrowserPackageName(int userId) {
13836 synchronized (mPackages) {
13837 return mSettings.getDefaultBrowserPackageNameLPw(userId);
13842 * Get the "allow unknown sources" setting.
13844 * @return the current "allow unknown sources" setting
13846 private int getUnknownSourcesSettings() {
13847 return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
13848 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
13853 public void setInstallerPackageName(String targetPackage, String installerPackageName) {
13854 final int uid = Binder.getCallingUid();
13856 synchronized (mPackages) {
13857 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
13858 if (targetPackageSetting == null) {
13859 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
13862 PackageSetting installerPackageSetting;
13863 if (installerPackageName != null) {
13864 installerPackageSetting = mSettings.mPackages.get(installerPackageName);
13865 if (installerPackageSetting == null) {
13866 throw new IllegalArgumentException("Unknown installer package: "
13867 + installerPackageName);
13870 installerPackageSetting = null;
13873 Signature[] callerSignature;
13874 Object obj = mSettings.getUserIdLPr(uid);
13876 if (obj instanceof SharedUserSetting) {
13877 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
13878 } else if (obj instanceof PackageSetting) {
13879 callerSignature = ((PackageSetting)obj).signatures.mSignatures;
13881 throw new SecurityException("Bad object " + obj + " for uid " + uid);
13884 throw new SecurityException("Unknown calling UID: " + uid);
13887 // Verify: can't set installerPackageName to a package that is
13888 // not signed with the same cert as the caller.
13889 if (installerPackageSetting != null) {
13890 if (compareSignatures(callerSignature,
13891 installerPackageSetting.signatures.mSignatures)
13892 != PackageManager.SIGNATURE_MATCH) {
13893 throw new SecurityException(
13894 "Caller does not have same cert as new installer package "
13895 + installerPackageName);
13899 // Verify: if target already has an installer package, it must
13900 // be signed with the same cert as the caller.
13901 if (targetPackageSetting.installerPackageName != null) {
13902 PackageSetting setting = mSettings.mPackages.get(
13903 targetPackageSetting.installerPackageName);
13904 // If the currently set package isn't valid, then it's always
13905 // okay to change it.
13906 if (setting != null) {
13907 if (compareSignatures(callerSignature,
13908 setting.signatures.mSignatures)
13909 != PackageManager.SIGNATURE_MATCH) {
13910 throw new SecurityException(
13911 "Caller does not have same cert as old installer package "
13912 + targetPackageSetting.installerPackageName);
13918 targetPackageSetting.installerPackageName = installerPackageName;
13919 if (installerPackageName != null) {
13920 mSettings.mInstallerPackages.add(installerPackageName);
13922 scheduleWriteSettingsLocked();
13927 public void setApplicationCategoryHint(String packageName, int categoryHint,
13928 String callerPackageName) {
13929 mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
13930 callerPackageName);
13931 synchronized (mPackages) {
13932 PackageSetting ps = mSettings.mPackages.get(packageName);
13934 throw new IllegalArgumentException("Unknown target package " + packageName);
13937 if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
13938 throw new IllegalArgumentException("Calling package " + callerPackageName
13939 + " is not installer for " + packageName);
13942 if (ps.categoryHint != categoryHint) {
13943 ps.categoryHint = categoryHint;
13944 scheduleWriteSettingsLocked();
13949 private void processPendingInstall(final InstallArgs args, final int currentStatus) {
13950 // Queue up an async operation since the package installation may take a little while.
13951 mHandler.post(new Runnable() {
13952 public void run() {
13953 mHandler.removeCallbacks(this);
13954 // Result object to be returned
13955 PackageInstalledInfo res = new PackageInstalledInfo();
13956 res.setReturnCode(currentStatus);
13959 res.removedInfo = null;
13960 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
13961 args.doPreInstall(res.returnCode);
13962 synchronized (mInstallLock) {
13963 installPackageTracedLI(args, res);
13965 args.doPostInstall(res.returnCode, res.uid);
13968 // A restore should be performed at this point if (a) the install
13969 // succeeded, (b) the operation is not an update, and (c) the new
13970 // package has not opted out of backup participation.
13971 final boolean update = res.removedInfo != null
13972 && res.removedInfo.removedPackage != null;
13973 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
13974 boolean doRestore = !update
13975 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
13977 // Set up the post-install work request bookkeeping. This will be used
13978 // and cleaned up by the post-install event handling regardless of whether
13979 // there's a restore pass performed. Token values are >= 1.
13981 if (mNextInstallToken < 0) mNextInstallToken = 1;
13982 token = mNextInstallToken++;
13984 PostInstallData data = new PostInstallData(args, res);
13985 mRunningInstalls.put(token, data);
13986 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
13988 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
13989 // Pass responsibility to the Backup Manager. It will perform a
13990 // restore if appropriate, then pass responsibility back to the
13991 // Package Manager to run the post-install observer callbacks
13993 IBackupManager bm = IBackupManager.Stub.asInterface(
13994 ServiceManager.getService(Context.BACKUP_SERVICE));
13996 if (DEBUG_INSTALL) Log.v(TAG, "token " + token
13997 + " to BM for possible restore");
13998 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
14000 // TODO: http://b/22388012
14001 if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
14002 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
14006 } catch (RemoteException e) {
14007 // can't happen; the backup manager is local
14008 } catch (Exception e) {
14009 Slog.e(TAG, "Exception trying to enqueue restore", e);
14013 Slog.e(TAG, "Backup Manager not found!");
14019 // No restore possible, or the Backup Manager was mysteriously not
14020 // available -- just fire the post-install work request directly.
14021 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
14023 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
14025 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
14026 mHandler.sendMessage(msg);
14033 * Callback from PackageSettings whenever an app is first transitioned out of the
14034 * 'stopped' state. Normally we just issue the broadcast, but we can't do that if
14035 * the app was "launched" for a restoreAtInstall operation. Therefore we check
14036 * here whether the app is the target of an ongoing install, and only send the
14037 * broadcast immediately if it is not in that state. If it *is* undergoing a restore,
14038 * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
14041 void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) {
14042 // Serialize this with the rest of the install-process message chain. In the
14043 // restore-at-install case, this Runnable will necessarily run before the
14044 // POST_INSTALL message is processed, so the contents of mRunningInstalls
14045 // are coherent. In the non-restore case, the app has already completed install
14046 // and been launched through some other means, so it is not in a problematic
14047 // state for observers to see the FIRST_LAUNCH signal.
14048 mHandler.post(new Runnable() {
14050 public void run() {
14051 for (int i = 0; i < mRunningInstalls.size(); i++) {
14052 final PostInstallData data = mRunningInstalls.valueAt(i);
14053 if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
14056 if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) {
14057 // right package; but is it for the right user?
14058 for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
14059 if (userId == data.res.newUsers[uIndex]) {
14060 if (DEBUG_BACKUP) {
14061 Slog.i(TAG, "Package " + pkgName
14062 + " being restored so deferring FIRST_LAUNCH");
14069 // didn't find it, so not being restored
14070 if (DEBUG_BACKUP) {
14071 Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH");
14073 sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId});
14078 private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) {
14079 sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
14080 installerPkg, null, userIds);
14083 private abstract class HandlerParams {
14084 private static final int MAX_RETRIES = 4;
14087 * Number of times startCopy() has been attempted and had a non-fatal
14090 private int mRetries = 0;
14092 /** User handle for the user requesting the information or installation. */
14093 private final UserHandle mUser;
14094 String traceMethod;
14097 HandlerParams(UserHandle user) {
14101 UserHandle getUser() {
14105 HandlerParams setTraceMethod(String traceMethod) {
14106 this.traceMethod = traceMethod;
14110 HandlerParams setTraceCookie(int traceCookie) {
14111 this.traceCookie = traceCookie;
14115 final boolean startCopy() {
14118 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
14120 if (++mRetries > MAX_RETRIES) {
14121 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
14122 mHandler.sendEmptyMessage(MCS_GIVE_UP);
14123 handleServiceError();
14129 } catch (RemoteException e) {
14130 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
14131 mHandler.sendEmptyMessage(MCS_RECONNECT);
14134 handleReturnCode();
14138 final void serviceError() {
14139 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
14140 handleServiceError();
14141 handleReturnCode();
14144 abstract void handleStartCopy() throws RemoteException;
14145 abstract void handleServiceError();
14146 abstract void handleReturnCode();
14149 private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
14150 for (File path : paths) {
14152 mcs.clearDirectory(path.getAbsolutePath());
14153 } catch (RemoteException e) {
14158 static class OriginInfo {
14160 * Location where install is coming from, before it has been
14161 * copied/renamed into place. This could be a single monolithic APK
14162 * file, or a cluster directory. This location may be untrusted.
14168 * Flag indicating that {@link #file} or {@link #cid} has already been
14169 * staged, meaning downstream users don't need to defensively copy the
14172 final boolean staged;
14175 * Flag indicating that {@link #file} or {@link #cid} is an already
14176 * installed app that is being moved.
14178 final boolean existing;
14180 final String resolvedPath;
14181 final File resolvedFile;
14183 static OriginInfo fromNothing() {
14184 return new OriginInfo(null, null, false, false);
14187 static OriginInfo fromUntrustedFile(File file) {
14188 return new OriginInfo(file, null, false, false);
14191 static OriginInfo fromExistingFile(File file) {
14192 return new OriginInfo(file, null, false, true);
14195 static OriginInfo fromStagedFile(File file) {
14196 return new OriginInfo(file, null, true, false);
14199 static OriginInfo fromStagedContainer(String cid) {
14200 return new OriginInfo(null, cid, true, false);
14203 private OriginInfo(File file, String cid, boolean staged, boolean existing) {
14206 this.staged = staged;
14207 this.existing = existing;
14210 resolvedPath = PackageHelper.getSdDir(cid);
14211 resolvedFile = new File(resolvedPath);
14212 } else if (file != null) {
14213 resolvedPath = file.getAbsolutePath();
14214 resolvedFile = file;
14216 resolvedPath = null;
14217 resolvedFile = null;
14222 static class MoveInfo {
14224 final String fromUuid;
14225 final String toUuid;
14226 final String packageName;
14227 final String dataAppName;
14229 final String seinfo;
14230 final int targetSdkVersion;
14232 public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
14233 String dataAppName, int appId, String seinfo, int targetSdkVersion) {
14234 this.moveId = moveId;
14235 this.fromUuid = fromUuid;
14236 this.toUuid = toUuid;
14237 this.packageName = packageName;
14238 this.dataAppName = dataAppName;
14239 this.appId = appId;
14240 this.seinfo = seinfo;
14241 this.targetSdkVersion = targetSdkVersion;
14245 static class VerificationInfo {
14246 /** A constant used to indicate that a uid value is not present. */
14247 public static final int NO_UID = -1;
14249 /** URI referencing where the package was downloaded from. */
14250 final Uri originatingUri;
14252 /** HTTP referrer URI associated with the originatingURI. */
14253 final Uri referrer;
14255 /** UID of the application that the install request originated from. */
14256 final int originatingUid;
14258 /** UID of application requesting the install */
14259 final int installerUid;
14261 VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
14262 this.originatingUri = originatingUri;
14263 this.referrer = referrer;
14264 this.originatingUid = originatingUid;
14265 this.installerUid = installerUid;
14269 class InstallParams extends HandlerParams {
14270 final OriginInfo origin;
14271 final MoveInfo move;
14272 final IPackageInstallObserver2 observer;
14274 final String installerPackageName;
14275 final String volumeUuid;
14276 private InstallArgs mArgs;
14278 final String packageAbiOverride;
14279 final String[] grantedRuntimePermissions;
14280 final VerificationInfo verificationInfo;
14281 final Certificate[][] certificates;
14282 final int installReason;
14284 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
14285 int installFlags, String installerPackageName, String volumeUuid,
14286 VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
14287 String[] grantedPermissions, Certificate[][] certificates, int installReason) {
14289 this.origin = origin;
14291 this.observer = observer;
14292 this.installFlags = installFlags;
14293 this.installerPackageName = installerPackageName;
14294 this.volumeUuid = volumeUuid;
14295 this.verificationInfo = verificationInfo;
14296 this.packageAbiOverride = packageAbiOverride;
14297 this.grantedRuntimePermissions = grantedPermissions;
14298 this.certificates = certificates;
14299 this.installReason = installReason;
14303 public String toString() {
14304 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
14305 + " file=" + origin.file + " cid=" + origin.cid + "}";
14308 private int installLocationPolicy(PackageInfoLite pkgLite) {
14309 String packageName = pkgLite.packageName;
14310 int installLocation = pkgLite.installLocation;
14311 boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
14313 synchronized (mPackages) {
14314 // Currently installed package which the new package is attempting to replace or
14315 // null if no such package is installed.
14316 PackageParser.Package installedPkg = mPackages.get(packageName);
14317 // Package which currently owns the data which the new package will own if installed.
14318 // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
14319 // will be null whereas dataOwnerPkg will contain information about the package
14320 // which was uninstalled while keeping its data.
14321 PackageParser.Package dataOwnerPkg = installedPkg;
14322 if (dataOwnerPkg == null) {
14323 PackageSetting ps = mSettings.mPackages.get(packageName);
14325 dataOwnerPkg = ps.pkg;
14329 if (dataOwnerPkg != null) {
14330 // If installed, the package will get access to data left on the device by its
14331 // predecessor. As a security measure, this is permited only if this is not a
14332 // version downgrade or if the predecessor package is marked as debuggable and
14333 // a downgrade is explicitly requested.
14335 // On debuggable platform builds, downgrades are permitted even for
14336 // non-debuggable packages to make testing easier. Debuggable platform builds do
14337 // not offer security guarantees and thus it's OK to disable some security
14338 // mechanisms to make debugging/testing easier on those builds. However, even on
14339 // debuggable builds downgrades of packages are permitted only if requested via
14340 // installFlags. This is because we aim to keep the behavior of debuggable
14341 // platform builds as close as possible to the behavior of non-debuggable
14342 // platform builds.
14343 final boolean downgradeRequested =
14344 (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
14345 final boolean packageDebuggable =
14346 (dataOwnerPkg.applicationInfo.flags
14347 & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
14348 final boolean downgradePermitted =
14349 (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
14350 if (!downgradePermitted) {
14352 checkDowngrade(dataOwnerPkg, pkgLite);
14353 } catch (PackageManagerException e) {
14354 Slog.w(TAG, "Downgrade detected: " + e.getMessage());
14355 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
14360 if (installedPkg != null) {
14361 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
14362 // Check for updated system application.
14363 if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14365 Slog.w(TAG, "Cannot install update to system app on sdcard");
14366 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
14368 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14371 // Install flag overrides everything.
14372 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14374 // If current upgrade specifies particular preference
14375 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
14376 // Application explicitly specified internal.
14377 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14378 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
14379 // App explictly prefers external. Let policy decide
14381 // Prefer previous location
14382 if (isExternal(installedPkg)) {
14383 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14385 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14389 // Invalid install. Return error code
14390 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
14394 // All the special cases have been taken care of.
14395 // Return result based on recommended install location.
14397 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14399 return pkgLite.recommendedInstallLocation;
14403 * Invoke remote method to get package information and install
14404 * location values. Override install location based on default
14405 * policy if needed and then create install arguments based
14406 * on the install location.
14408 public void handleStartCopy() throws RemoteException {
14409 int ret = PackageManager.INSTALL_SUCCEEDED;
14411 // If we're already staged, we've firmly committed to an install location
14412 if (origin.staged) {
14413 if (origin.file != null) {
14414 installFlags |= PackageManager.INSTALL_INTERNAL;
14415 installFlags &= ~PackageManager.INSTALL_EXTERNAL;
14416 } else if (origin.cid != null) {
14417 installFlags |= PackageManager.INSTALL_EXTERNAL;
14418 installFlags &= ~PackageManager.INSTALL_INTERNAL;
14420 throw new IllegalStateException("Invalid stage location");
14424 final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
14425 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
14426 final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
14427 PackageInfoLite pkgLite = null;
14429 if (onInt && onSd) {
14430 // Check if both bits are set.
14431 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
14432 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14433 } else if (onSd && ephemeral) {
14434 Slog.w(TAG, "Conflicting flags specified for installing ephemeral on external");
14435 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14437 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
14438 packageAbiOverride);
14440 if (DEBUG_EPHEMERAL && ephemeral) {
14441 Slog.v(TAG, "pkgLite for install: " + pkgLite);
14445 * If we have too little free space, try to free cache
14446 * before giving up.
14448 if (!origin.staged && pkgLite.recommendedInstallLocation
14449 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
14450 // TODO: focus freeing disk space on the target device
14451 final StorageManager storage = StorageManager.from(mContext);
14452 final long lowThreshold = storage.getStorageLowBytes(
14453 Environment.getDataDirectory());
14455 final long sizeBytes = mContainerService.calculateInstalledSize(
14456 origin.resolvedPath, isForwardLocked(), packageAbiOverride);
14459 mInstaller.freeCache(null, sizeBytes + lowThreshold, 0);
14460 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
14461 installFlags, packageAbiOverride);
14462 } catch (InstallerException e) {
14463 Slog.w(TAG, "Failed to free cache", e);
14467 * The cache free must have deleted the file we
14468 * downloaded to install.
14470 * TODO: fix the "freeCache" call to not delete
14471 * the file we care about.
14473 if (pkgLite.recommendedInstallLocation
14474 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
14475 pkgLite.recommendedInstallLocation
14476 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
14481 if (ret == PackageManager.INSTALL_SUCCEEDED) {
14482 int loc = pkgLite.recommendedInstallLocation;
14483 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
14484 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14485 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
14486 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
14487 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
14488 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
14489 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
14490 ret = PackageManager.INSTALL_FAILED_INVALID_APK;
14491 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
14492 ret = PackageManager.INSTALL_FAILED_INVALID_URI;
14493 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
14494 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
14496 // Override with defaults if needed.
14497 loc = installLocationPolicy(pkgLite);
14498 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
14499 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
14500 } else if (!onSd && !onInt) {
14501 // Override install location with flags
14502 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
14503 // Set the flag to install on external media.
14504 installFlags |= PackageManager.INSTALL_EXTERNAL;
14505 installFlags &= ~PackageManager.INSTALL_INTERNAL;
14506 } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
14507 if (DEBUG_EPHEMERAL) {
14508 Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
14510 installFlags |= PackageManager.INSTALL_INSTANT_APP;
14511 installFlags &= ~(PackageManager.INSTALL_EXTERNAL
14512 |PackageManager.INSTALL_INTERNAL);
14514 // Make sure the flag for installing on external
14516 installFlags |= PackageManager.INSTALL_INTERNAL;
14517 installFlags &= ~PackageManager.INSTALL_EXTERNAL;
14523 final InstallArgs args = createInstallArgs(this);
14526 if (ret == PackageManager.INSTALL_SUCCEEDED) {
14527 // TODO: http://b/22976637
14528 // Apps installed for "all" users use the device owner to verify the app
14529 UserHandle verifierUser = getUser();
14530 if (verifierUser == UserHandle.ALL) {
14531 verifierUser = UserHandle.SYSTEM;
14535 * Determine if we have any installed package verifiers. If we
14536 * do, then we'll defer to them to verify the packages.
14538 final int requiredUid = mRequiredVerifierPackage == null ? -1
14539 : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
14540 verifierUser.getIdentifier());
14541 if (!origin.existing && requiredUid != -1
14542 && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) {
14543 final Intent verification = new Intent(
14544 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
14545 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14546 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
14547 PACKAGE_MIME_TYPE);
14548 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
14550 // Query all live verifiers based on current user state
14551 final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
14552 PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier());
14554 if (DEBUG_VERIFY) {
14555 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
14556 + verification.toString() + " with " + pkgLite.verifiers.length
14557 + " optional verifiers");
14560 final int verificationId = mPendingVerificationToken++;
14562 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
14564 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
14565 installerPackageName);
14567 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
14570 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
14571 pkgLite.packageName);
14573 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
14574 pkgLite.versionCode);
14576 if (verificationInfo != null) {
14577 if (verificationInfo.originatingUri != null) {
14578 verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
14579 verificationInfo.originatingUri);
14581 if (verificationInfo.referrer != null) {
14582 verification.putExtra(Intent.EXTRA_REFERRER,
14583 verificationInfo.referrer);
14585 if (verificationInfo.originatingUid >= 0) {
14586 verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
14587 verificationInfo.originatingUid);
14589 if (verificationInfo.installerUid >= 0) {
14590 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
14591 verificationInfo.installerUid);
14595 final PackageVerificationState verificationState = new PackageVerificationState(
14596 requiredUid, args);
14598 mPendingVerification.append(verificationId, verificationState);
14600 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
14601 receivers, verificationState);
14603 DeviceIdleController.LocalService idleController = getDeviceIdleController();
14604 final long idleDuration = getVerificationTimeout();
14607 * If any sufficient verifiers were listed in the package
14608 * manifest, attempt to ask them.
14610 if (sufficientVerifiers != null) {
14611 final int N = sufficientVerifiers.size();
14613 Slog.i(TAG, "Additional verifiers required, but none installed.");
14614 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
14616 for (int i = 0; i < N; i++) {
14617 final ComponentName verifierComponent = sufficientVerifiers.get(i);
14618 idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
14619 verifierComponent.getPackageName(), idleDuration,
14620 verifierUser.getIdentifier(), false, "package verifier");
14622 final Intent sufficientIntent = new Intent(verification);
14623 sufficientIntent.setComponent(verifierComponent);
14624 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
14629 final ComponentName requiredVerifierComponent = matchComponentForVerifier(
14630 mRequiredVerifierPackage, receivers);
14631 if (ret == PackageManager.INSTALL_SUCCEEDED
14632 && mRequiredVerifierPackage != null) {
14633 Trace.asyncTraceBegin(
14634 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
14636 * Send the intent to the required verification agent,
14637 * but only start the verification timeout after the
14638 * target BroadcastReceivers have run.
14640 verification.setComponent(requiredVerifierComponent);
14641 idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
14642 mRequiredVerifierPackage, idleDuration,
14643 verifierUser.getIdentifier(), false, "package verifier");
14644 mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
14645 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14646 new BroadcastReceiver() {
14648 public void onReceive(Context context, Intent intent) {
14649 final Message msg = mHandler
14650 .obtainMessage(CHECK_PENDING_VERIFICATION);
14651 msg.arg1 = verificationId;
14652 mHandler.sendMessageDelayed(msg, getVerificationTimeout());
14654 }, null, 0, null, null);
14657 * We don't want the copy to proceed until verification
14658 * succeeds, so null out this field.
14664 * No package verification is enabled, so immediately start
14665 * the remote call to initiate copy using temporary file.
14667 ret = args.copyApk(mContainerService, true);
14675 void handleReturnCode() {
14676 // If mArgs is null, then MCS couldn't be reached. When it
14677 // reconnects, it will try again to install. At that point, this
14679 if (mArgs != null) {
14680 processPendingInstall(mArgs, mRet);
14685 void handleServiceError() {
14686 mArgs = createInstallArgs(this);
14687 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
14690 public boolean isForwardLocked() {
14691 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
14696 * Used during creation of InstallArgs
14698 * @param installFlags package installation flags
14699 * @return true if should be installed on external storage
14701 private static boolean installOnExternalAsec(int installFlags) {
14702 if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
14705 if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
14712 * Used during creation of InstallArgs
14714 * @param installFlags package installation flags
14715 * @return true if should be installed as forward locked
14717 private static boolean installForwardLocked(int installFlags) {
14718 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
14721 private InstallArgs createInstallArgs(InstallParams params) {
14722 if (params.move != null) {
14723 return new MoveInstallArgs(params);
14724 } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
14725 return new AsecInstallArgs(params);
14727 return new FileInstallArgs(params);
14732 * Create args that describe an existing installed package. Typically used
14733 * when cleaning up old installs, or used as a move source.
14735 private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
14736 String resourcePath, String[] instructionSets) {
14737 final boolean isInAsec;
14738 if (installOnExternalAsec(installFlags)) {
14739 /* Apps on SD card are always in ASEC containers. */
14741 } else if (installForwardLocked(installFlags)
14742 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
14744 * Forward-locked apps are only in ASEC containers if they're the
14753 return new AsecInstallArgs(codePath, instructionSets,
14754 installOnExternalAsec(installFlags), installForwardLocked(installFlags));
14756 return new FileInstallArgs(codePath, resourcePath, instructionSets);
14760 static abstract class InstallArgs {
14761 /** @see InstallParams#origin */
14762 final OriginInfo origin;
14763 /** @see InstallParams#move */
14764 final MoveInfo move;
14766 final IPackageInstallObserver2 observer;
14767 // Always refers to PackageManager flags only
14768 final int installFlags;
14769 final String installerPackageName;
14770 final String volumeUuid;
14771 final UserHandle user;
14772 final String abiOverride;
14773 final String[] installGrantPermissions;
14774 /** If non-null, drop an async trace when the install completes */
14775 final String traceMethod;
14776 final int traceCookie;
14777 final Certificate[][] certificates;
14778 final int installReason;
14780 // The list of instruction sets supported by this app. This is currently
14781 // only used during the rmdex() phase to clean up resources. We can get rid of this
14782 // if we move dex files under the common app path.
14783 /* nullable */ String[] instructionSets;
14785 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
14786 int installFlags, String installerPackageName, String volumeUuid,
14787 UserHandle user, String[] instructionSets,
14788 String abiOverride, String[] installGrantPermissions,
14789 String traceMethod, int traceCookie, Certificate[][] certificates,
14790 int installReason) {
14791 this.origin = origin;
14793 this.installFlags = installFlags;
14794 this.observer = observer;
14795 this.installerPackageName = installerPackageName;
14796 this.volumeUuid = volumeUuid;
14798 this.instructionSets = instructionSets;
14799 this.abiOverride = abiOverride;
14800 this.installGrantPermissions = installGrantPermissions;
14801 this.traceMethod = traceMethod;
14802 this.traceCookie = traceCookie;
14803 this.certificates = certificates;
14804 this.installReason = installReason;
14807 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
14808 abstract int doPreInstall(int status);
14811 * Rename package into final resting place. All paths on the given
14812 * scanned package should be updated to reflect the rename.
14814 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
14815 abstract int doPostInstall(int status, int uid);
14817 /** @see PackageSettingBase#codePathString */
14818 abstract String getCodePath();
14819 /** @see PackageSettingBase#resourcePathString */
14820 abstract String getResourcePath();
14822 // Need installer lock especially for dex file removal.
14823 abstract void cleanUpResourcesLI();
14824 abstract boolean doPostDeleteLI(boolean delete);
14827 * Called before the source arguments are copied. This is used mostly
14828 * for MoveParams when it needs to read the source file to put it in the
14832 return PackageManager.INSTALL_SUCCEEDED;
14836 * Called after the source arguments are copied. This is used mostly for
14837 * MoveParams when it needs to read the source file to put it in the
14840 int doPostCopy(int uid) {
14841 return PackageManager.INSTALL_SUCCEEDED;
14844 protected boolean isFwdLocked() {
14845 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
14848 protected boolean isExternalAsec() {
14849 return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
14852 protected boolean isEphemeral() {
14853 return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
14856 UserHandle getUser() {
14861 private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
14862 if (!allCodePaths.isEmpty()) {
14863 if (instructionSets == null) {
14864 throw new IllegalStateException("instructionSet == null");
14866 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
14867 for (String codePath : allCodePaths) {
14868 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
14870 mInstaller.rmdex(codePath, dexCodeInstructionSet);
14871 } catch (InstallerException ignored) {
14879 * Logic to handle installation of non-ASEC applications, including copying
14880 * and renaming logic.
14882 class FileInstallArgs extends InstallArgs {
14883 private File codeFile;
14884 private File resourceFile;
14886 // Example topology:
14887 // /data/app/com.example/base.apk
14888 // /data/app/com.example/split_foo.apk
14889 // /data/app/com.example/lib/arm/libfoo.so
14890 // /data/app/com.example/lib/arm64/libfoo.so
14891 // /data/app/com.example/dalvik/arm/base.apk@classes.dex
14894 FileInstallArgs(InstallParams params) {
14895 super(params.origin, params.move, params.observer, params.installFlags,
14896 params.installerPackageName, params.volumeUuid,
14897 params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
14898 params.grantedRuntimePermissions,
14899 params.traceMethod, params.traceCookie, params.certificates,
14900 params.installReason);
14901 if (isFwdLocked()) {
14902 throw new IllegalArgumentException("Forward locking only supported in ASEC");
14906 /** Existing install */
14907 FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
14908 super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
14909 null, null, null, 0, null /*certificates*/,
14910 PackageManager.INSTALL_REASON_UNKNOWN);
14911 this.codeFile = (codePath != null) ? new File(codePath) : null;
14912 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
14915 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
14916 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
14918 return doCopyApk(imcs, temp);
14920 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
14924 private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
14925 if (origin.staged) {
14926 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
14927 codeFile = origin.file;
14928 resourceFile = origin.file;
14929 return PackageManager.INSTALL_SUCCEEDED;
14933 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
14934 final File tempDir =
14935 mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
14936 codeFile = tempDir;
14937 resourceFile = tempDir;
14938 } catch (IOException e) {
14939 Slog.w(TAG, "Failed to create copy file: " + e);
14940 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
14943 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
14945 public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
14946 if (!FileUtils.isValidExtFilename(name)) {
14947 throw new IllegalArgumentException("Invalid filename: " + name);
14950 final File file = new File(codeFile, name);
14951 final FileDescriptor fd = Os.open(file.getAbsolutePath(),
14952 O_RDWR | O_CREAT, 0644);
14953 Os.chmod(file.getAbsolutePath(), 0644);
14954 return new ParcelFileDescriptor(fd);
14955 } catch (ErrnoException e) {
14956 throw new RemoteException("Failed to open: " + e.getMessage());
14961 int ret = PackageManager.INSTALL_SUCCEEDED;
14962 ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
14963 if (ret != PackageManager.INSTALL_SUCCEEDED) {
14964 Slog.e(TAG, "Failed to copy package");
14968 final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
14969 NativeLibraryHelper.Handle handle = null;
14971 handle = NativeLibraryHelper.Handle.create(codeFile);
14972 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
14974 } catch (IOException e) {
14975 Slog.e(TAG, "Copying native libraries failed", e);
14976 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
14978 IoUtils.closeQuietly(handle);
14984 int doPreInstall(int status) {
14985 if (status != PackageManager.INSTALL_SUCCEEDED) {
14991 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
14992 if (status != PackageManager.INSTALL_SUCCEEDED) {
14997 final File targetDir = codeFile.getParentFile();
14998 final File beforeCodeFile = codeFile;
14999 final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
15001 if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
15003 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
15004 } catch (ErrnoException e) {
15005 Slog.w(TAG, "Failed to rename", e);
15009 if (!SELinux.restoreconRecursive(afterCodeFile)) {
15010 Slog.w(TAG, "Failed to restorecon");
15014 // Reflect the rename internally
15015 codeFile = afterCodeFile;
15016 resourceFile = afterCodeFile;
15018 // Reflect the rename in scanned details
15019 pkg.setCodePath(afterCodeFile.getAbsolutePath());
15020 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
15021 afterCodeFile, pkg.baseCodePath));
15022 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
15023 afterCodeFile, pkg.splitCodePaths));
15025 // Reflect the rename in app info
15026 pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15027 pkg.setApplicationInfoCodePath(pkg.codePath);
15028 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15029 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15030 pkg.setApplicationInfoResourcePath(pkg.codePath);
15031 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15032 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15037 int doPostInstall(int status, int uid) {
15038 if (status != PackageManager.INSTALL_SUCCEEDED) {
15045 String getCodePath() {
15046 return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15050 String getResourcePath() {
15051 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15054 private boolean cleanUp() {
15055 if (codeFile == null || !codeFile.exists()) {
15059 removeCodePathLI(codeFile);
15061 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
15062 resourceFile.delete();
15068 void cleanUpResourcesLI() {
15069 // Try enumerating all code paths before deleting
15070 List<String> allCodePaths = Collections.EMPTY_LIST;
15071 if (codeFile != null && codeFile.exists()) {
15073 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
15074 allCodePaths = pkg.getAllCodePaths();
15075 } catch (PackageParserException e) {
15076 // Ignored; we tried our best
15081 removeDexFiles(allCodePaths, instructionSets);
15084 boolean doPostDeleteLI(boolean delete) {
15085 // XXX err, shouldn't we respect the delete flag?
15086 cleanUpResourcesLI();
15091 private boolean isAsecExternal(String cid) {
15092 final String asecPath = PackageHelper.getSdFilesystem(cid);
15093 return !asecPath.startsWith(mAsecInternalPath);
15096 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
15097 PackageManagerException {
15099 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
15100 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
15101 throw new PackageManagerException(copyRet, message);
15107 * Extract the StorageManagerService "container ID" from the full code path of an
15110 static String cidFromCodePath(String fullCodePath) {
15111 int eidx = fullCodePath.lastIndexOf("/");
15112 String subStr1 = fullCodePath.substring(0, eidx);
15113 int sidx = subStr1.lastIndexOf("/");
15114 return subStr1.substring(sidx+1, eidx);
15118 * Logic to handle installation of ASEC applications, including copying and
15121 class AsecInstallArgs extends InstallArgs {
15122 static final String RES_FILE_NAME = "pkg.apk";
15123 static final String PUBLIC_RES_FILE_NAME = "res.zip";
15126 String packagePath;
15127 String resourcePath;
15130 AsecInstallArgs(InstallParams params) {
15131 super(params.origin, params.move, params.observer, params.installFlags,
15132 params.installerPackageName, params.volumeUuid,
15133 params.getUser(), null /* instruction sets */, params.packageAbiOverride,
15134 params.grantedRuntimePermissions,
15135 params.traceMethod, params.traceCookie, params.certificates,
15136 params.installReason);
15139 /** Existing install */
15140 AsecInstallArgs(String fullCodePath, String[] instructionSets,
15141 boolean isExternal, boolean isForwardLocked) {
15142 super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
15143 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
15144 instructionSets, null, null, null, 0, null /*certificates*/,
15145 PackageManager.INSTALL_REASON_UNKNOWN);
15146 // Hackily pretend we're still looking at a full code path
15147 if (!fullCodePath.endsWith(RES_FILE_NAME)) {
15148 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
15151 // Extract cid from fullCodePath
15152 int eidx = fullCodePath.lastIndexOf("/");
15153 String subStr1 = fullCodePath.substring(0, eidx);
15154 int sidx = subStr1.lastIndexOf("/");
15155 cid = subStr1.substring(sidx+1, eidx);
15156 setMountPath(subStr1);
15159 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
15160 super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
15161 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
15162 instructionSets, null, null, null, 0, null /*certificates*/,
15163 PackageManager.INSTALL_REASON_UNKNOWN);
15165 setMountPath(PackageHelper.getSdDir(cid));
15168 void createCopyFile() {
15169 cid = mInstallerService.allocateExternalStageCidLegacy();
15172 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15173 if (origin.staged && origin.cid != null) {
15174 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy");
15176 setMountPath(PackageHelper.getSdDir(cid));
15177 return PackageManager.INSTALL_SUCCEEDED;
15184 * Pre-emptively destroy the container since it's destroyed if
15185 * copying fails due to it existing anyway.
15187 PackageHelper.destroySdDir(cid);
15190 final String newMountPath = imcs.copyPackageToContainer(
15191 origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
15192 isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
15194 if (newMountPath != null) {
15195 setMountPath(newMountPath);
15196 return PackageManager.INSTALL_SUCCEEDED;
15198 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15203 String getCodePath() {
15204 return packagePath;
15208 String getResourcePath() {
15209 return resourcePath;
15212 int doPreInstall(int status) {
15213 if (status != PackageManager.INSTALL_SUCCEEDED) {
15214 // Destroy container
15215 PackageHelper.destroySdDir(cid);
15217 boolean mounted = PackageHelper.isContainerMounted(cid);
15219 String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
15220 Process.SYSTEM_UID);
15221 if (newMountPath != null) {
15222 setMountPath(newMountPath);
15224 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15231 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15232 String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
15233 String newMountPath = null;
15234 if (PackageHelper.isContainerMounted(cid)) {
15235 // Unmount the container
15236 if (!PackageHelper.unMountSdDir(cid)) {
15237 Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
15241 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
15242 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
15243 " which might be stale. Will try to clean up.");
15244 // Clean up the stale container and proceed to recreate.
15245 if (!PackageHelper.destroySdDir(newCacheId)) {
15246 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
15249 // Successfully cleaned up stale container. Try to rename again.
15250 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
15251 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
15252 + " inspite of cleaning it up.");
15256 if (!PackageHelper.isContainerMounted(newCacheId)) {
15257 Slog.w(TAG, "Mounting container " + newCacheId);
15258 newMountPath = PackageHelper.mountSdDir(newCacheId,
15259 getEncryptKey(), Process.SYSTEM_UID);
15261 newMountPath = PackageHelper.getSdDir(newCacheId);
15263 if (newMountPath == null) {
15264 Slog.w(TAG, "Failed to get cache path for " + newCacheId);
15267 Log.i(TAG, "Succesfully renamed " + cid +
15268 " to " + newCacheId +
15269 " at new path: " + newMountPath);
15272 final File beforeCodeFile = new File(packagePath);
15273 setMountPath(newMountPath);
15274 final File afterCodeFile = new File(packagePath);
15276 // Reflect the rename in scanned details
15277 pkg.setCodePath(afterCodeFile.getAbsolutePath());
15278 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
15279 afterCodeFile, pkg.baseCodePath));
15280 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
15281 afterCodeFile, pkg.splitCodePaths));
15283 // Reflect the rename in app info
15284 pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15285 pkg.setApplicationInfoCodePath(pkg.codePath);
15286 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15287 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15288 pkg.setApplicationInfoResourcePath(pkg.codePath);
15289 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15290 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15295 private void setMountPath(String mountPath) {
15296 final File mountFile = new File(mountPath);
15298 final File monolithicFile = new File(mountFile, RES_FILE_NAME);
15299 if (monolithicFile.exists()) {
15300 packagePath = monolithicFile.getAbsolutePath();
15301 if (isFwdLocked()) {
15302 resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
15304 resourcePath = packagePath;
15307 packagePath = mountFile.getAbsolutePath();
15308 resourcePath = packagePath;
15312 int doPostInstall(int status, int uid) {
15313 if (status != PackageManager.INSTALL_SUCCEEDED) {
15316 final int groupOwner;
15317 final String protectedFile;
15318 if (isFwdLocked()) {
15319 groupOwner = UserHandle.getSharedAppGid(uid);
15320 protectedFile = RES_FILE_NAME;
15323 protectedFile = null;
15326 if (uid < Process.FIRST_APPLICATION_UID
15327 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
15328 Slog.e(TAG, "Failed to finalize " + cid);
15329 PackageHelper.destroySdDir(cid);
15330 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15333 boolean mounted = PackageHelper.isContainerMounted(cid);
15335 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
15341 private void cleanUp() {
15342 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
15344 // Destroy secure container
15345 PackageHelper.destroySdDir(cid);
15348 private List<String> getAllCodePaths() {
15349 final File codeFile = new File(getCodePath());
15350 if (codeFile != null && codeFile.exists()) {
15352 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
15353 return pkg.getAllCodePaths();
15354 } catch (PackageParserException e) {
15355 // Ignored; we tried our best
15358 return Collections.EMPTY_LIST;
15361 void cleanUpResourcesLI() {
15362 // Enumerate all code paths before deleting
15363 cleanUpResourcesLI(getAllCodePaths());
15366 private void cleanUpResourcesLI(List<String> allCodePaths) {
15368 removeDexFiles(allCodePaths, instructionSets);
15371 String getPackageName() {
15372 return getAsecPackageName(cid);
15375 boolean doPostDeleteLI(boolean delete) {
15376 if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
15377 final List<String> allCodePaths = getAllCodePaths();
15378 boolean mounted = PackageHelper.isContainerMounted(cid);
15381 if (PackageHelper.unMountSdDir(cid)) {
15385 if (!mounted && delete) {
15386 cleanUpResourcesLI(allCodePaths);
15393 if (isFwdLocked()) {
15394 if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE,
15395 MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) {
15396 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15400 return PackageManager.INSTALL_SUCCEEDED;
15404 int doPostCopy(int uid) {
15405 if (isFwdLocked()) {
15406 if (uid < Process.FIRST_APPLICATION_UID
15407 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
15409 Slog.e(TAG, "Failed to finalize " + cid);
15410 PackageHelper.destroySdDir(cid);
15411 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15415 return PackageManager.INSTALL_SUCCEEDED;
15420 * Logic to handle movement of existing installed applications.
15422 class MoveInstallArgs extends InstallArgs {
15423 private File codeFile;
15424 private File resourceFile;
15427 MoveInstallArgs(InstallParams params) {
15428 super(params.origin, params.move, params.observer, params.installFlags,
15429 params.installerPackageName, params.volumeUuid,
15430 params.getUser(), null /* instruction sets */, params.packageAbiOverride,
15431 params.grantedRuntimePermissions,
15432 params.traceMethod, params.traceCookie, params.certificates,
15433 params.installReason);
15436 int copyApk(IMediaContainerService imcs, boolean temp) {
15437 if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
15438 + move.fromUuid + " to " + move.toUuid);
15439 synchronized (mInstaller) {
15441 mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
15442 move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
15443 } catch (InstallerException e) {
15444 Slog.w(TAG, "Failed to move app", e);
15445 return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15449 codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
15450 resourceFile = codeFile;
15451 if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
15453 return PackageManager.INSTALL_SUCCEEDED;
15456 int doPreInstall(int status) {
15457 if (status != PackageManager.INSTALL_SUCCEEDED) {
15458 cleanUp(move.toUuid);
15463 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15464 if (status != PackageManager.INSTALL_SUCCEEDED) {
15465 cleanUp(move.toUuid);
15469 // Reflect the move in app info
15470 pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15471 pkg.setApplicationInfoCodePath(pkg.codePath);
15472 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15473 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15474 pkg.setApplicationInfoResourcePath(pkg.codePath);
15475 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15476 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15481 int doPostInstall(int status, int uid) {
15482 if (status == PackageManager.INSTALL_SUCCEEDED) {
15483 cleanUp(move.fromUuid);
15485 cleanUp(move.toUuid);
15491 String getCodePath() {
15492 return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15496 String getResourcePath() {
15497 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15500 private boolean cleanUp(String volumeUuid) {
15501 final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
15503 Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
15504 final int[] userIds = sUserManager.getUserIds();
15505 synchronized (mInstallLock) {
15506 // Clean up both app data and code
15507 // All package moves are frozen until finished
15508 for (int userId : userIds) {
15510 mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
15511 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
15512 } catch (InstallerException e) {
15513 Slog.w(TAG, String.valueOf(e));
15516 removeCodePathLI(codeFile);
15521 void cleanUpResourcesLI() {
15522 throw new UnsupportedOperationException();
15525 boolean doPostDeleteLI(boolean delete) {
15526 throw new UnsupportedOperationException();
15530 static String getAsecPackageName(String packageCid) {
15531 int idx = packageCid.lastIndexOf("-");
15535 return packageCid.substring(0, idx);
15538 // Utility method used to create code paths based on package name and available index.
15539 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
15540 String idxStr = "";
15542 // Fall back to default value of idx=1 if prefix is not
15543 // part of oldCodePath
15544 if (oldCodePath != null) {
15545 String subStr = oldCodePath;
15546 // Drop the suffix right away
15547 if (suffix != null && subStr.endsWith(suffix)) {
15548 subStr = subStr.substring(0, subStr.length() - suffix.length());
15550 // If oldCodePath already contains prefix find out the
15551 // ending index to either increment or decrement.
15552 int sidx = subStr.lastIndexOf(prefix);
15554 subStr = subStr.substring(sidx + prefix.length());
15555 if (subStr != null) {
15556 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
15557 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
15560 idx = Integer.parseInt(subStr);
15566 } catch(NumberFormatException e) {
15571 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
15572 return prefix + idxStr;
15575 private File getNextCodePath(File targetDir, String packageName) {
15577 SecureRandom random = new SecureRandom();
15578 byte[] bytes = new byte[16];
15580 random.nextBytes(bytes);
15581 String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
15582 result = new File(targetDir, packageName + "-" + suffix);
15583 } while (result.exists());
15587 // Utility method that returns the relative package path with respect
15588 // to the installation directory. Like say for /data/data/com.test-1.apk
15589 // string com.test-1 is returned.
15590 static String deriveCodePathName(String codePath) {
15591 if (codePath == null) {
15594 final File codeFile = new File(codePath);
15595 final String name = codeFile.getName();
15596 if (codeFile.isDirectory()) {
15598 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
15599 final int lastDot = name.lastIndexOf('.');
15600 return name.substring(0, lastDot);
15602 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
15607 static class PackageInstalledInfo {
15610 // The set of users that originally had this package installed.
15612 // The set of users that now have this package installed.
15614 PackageParser.Package pkg;
15617 PackageRemovedInfo removedInfo;
15618 ArrayMap<String, PackageInstalledInfo> addedChildPackages;
15620 public void setError(int code, String msg) {
15621 setReturnCode(code);
15622 setReturnMessage(msg);
15626 public void setError(String msg, PackageParserException e) {
15627 setReturnCode(e.error);
15628 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15629 Slog.w(TAG, msg, e);
15632 public void setError(String msg, PackageManagerException e) {
15633 returnCode = e.error;
15634 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15635 Slog.w(TAG, msg, e);
15638 public void setReturnCode(int returnCode) {
15639 this.returnCode = returnCode;
15640 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15641 for (int i = 0; i < childCount; i++) {
15642 addedChildPackages.valueAt(i).returnCode = returnCode;
15646 private void setReturnMessage(String returnMsg) {
15647 this.returnMsg = returnMsg;
15648 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15649 for (int i = 0; i < childCount; i++) {
15650 addedChildPackages.valueAt(i).returnMsg = returnMsg;
15654 // In some error cases we want to convey more info back to the observer
15655 String origPackage;
15656 String origPermission;
15660 * Install a non-existing package.
15662 private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
15663 int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
15664 PackageInstalledInfo res, int installReason) {
15665 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
15667 // Remember this for later, in case we need to rollback this install
15668 String pkgName = pkg.packageName;
15670 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
15672 synchronized(mPackages) {
15673 final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName);
15674 if (renamedPackage != null) {
15675 // A package with the same name is already installed, though
15676 // it has been renamed to an older name. The package we
15677 // are trying to install should be installed as an update to
15678 // the existing one, but that has not been requested, so bail.
15679 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
15680 + " without first uninstalling package running as "
15684 if (mPackages.containsKey(pkgName)) {
15685 // Don't allow installation over an existing package with the same name.
15686 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
15687 + " without first uninstalling.");
15693 PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
15694 System.currentTimeMillis(), user);
15696 updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
15698 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
15699 prepareAppDataAfterInstallLIF(newPackage);
15702 // Remove package from internal structures, but keep around any
15703 // data that might have already existed
15704 deletePackageLIF(pkgName, UserHandle.ALL, false, null,
15705 PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
15707 } catch (PackageManagerException e) {
15708 res.setError("Package couldn't be installed in " + pkg.codePath, e);
15711 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15714 private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
15715 // Can't rotate keys during boot or if sharedUser.
15716 if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
15717 || !oldPs.keySetData.isUsingUpgradeKeySets()) {
15720 // app is using upgradeKeySets; make sure all are valid
15721 KeySetManagerService ksms = mSettings.mKeySetManagerService;
15722 long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
15723 for (int i = 0; i < upgradeKeySets.length; i++) {
15724 if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
15725 Slog.wtf(TAG, "Package "
15726 + (oldPs.name != null ? oldPs.name : "<null>")
15727 + " contains upgrade-key-set reference to unknown key-set: "
15728 + upgradeKeySets[i]
15729 + " reverting to signatures check.");
15736 private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
15737 // Upgrade keysets are being used. Determine if new package has a superset of the
15739 long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
15740 KeySetManagerService ksms = mSettings.mKeySetManagerService;
15741 for (int i = 0; i < upgradeKeySets.length; i++) {
15742 Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
15743 if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
15750 private static void updateDigest(MessageDigest digest, File file) throws IOException {
15751 try (DigestInputStream digestStream =
15752 new DigestInputStream(new FileInputStream(file), digest)) {
15753 while (digestStream.read() != -1) {} // nothing to do; just plow through the file
15757 private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags,
15758 UserHandle user, String installerPackageName, PackageInstalledInfo res,
15759 int installReason) {
15760 final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
15762 final PackageParser.Package oldPackage;
15763 final String pkgName = pkg.packageName;
15764 final int[] allUsers;
15765 final int[] installedUsers;
15767 synchronized(mPackages) {
15768 oldPackage = mPackages.get(pkgName);
15769 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
15771 // don't allow upgrade to target a release SDK from a pre-release SDK
15772 final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
15773 == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
15774 final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
15775 == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
15776 if (oldTargetsPreRelease
15777 && !newTargetsPreRelease
15778 && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
15779 Slog.w(TAG, "Can't install package targeting released sdk");
15780 res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
15784 final PackageSetting ps = mSettings.mPackages.get(pkgName);
15786 // verify signatures are valid
15787 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
15788 if (!checkUpgradeKeySetLP(ps, pkg)) {
15789 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
15790 "New package not signed by keys specified by upgrade-keysets: "
15795 // default to original signature matching
15796 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
15797 != PackageManager.SIGNATURE_MATCH) {
15798 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
15799 "New package has a different signature: " + pkgName);
15804 // don't allow a system upgrade unless the upgrade hash matches
15805 if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) {
15806 byte[] digestBytes = null;
15808 final MessageDigest digest = MessageDigest.getInstance("SHA-512");
15809 updateDigest(digest, new File(pkg.baseCodePath));
15810 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
15811 for (String path : pkg.splitCodePaths) {
15812 updateDigest(digest, new File(path));
15815 digestBytes = digest.digest();
15816 } catch (NoSuchAlgorithmException | IOException e) {
15817 res.setError(INSTALL_FAILED_INVALID_APK,
15818 "Could not compute hash: " + pkgName);
15821 if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
15822 res.setError(INSTALL_FAILED_INVALID_APK,
15823 "New package fails restrict-update check: " + pkgName);
15826 // retain upgrade restriction
15827 pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
15830 // Check for shared user id changes
15831 String invalidPackageName =
15832 getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
15833 if (invalidPackageName != null) {
15834 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
15835 "Package " + invalidPackageName + " tried to change user "
15836 + oldPackage.mSharedUserId);
15840 // In case of rollback, remember per-user/profile install state
15841 allUsers = sUserManager.getUserIds();
15842 installedUsers = ps.queryInstalledUsers(allUsers, true);
15844 // don't allow an upgrade from full to ephemeral
15845 if (isInstantApp) {
15846 if (user == null || user.getIdentifier() == UserHandle.USER_ALL) {
15847 for (int currentUser : allUsers) {
15848 if (!ps.getInstantApp(currentUser)) {
15849 // can't downgrade from full to instant
15850 Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
15851 + " for user: " + currentUser);
15852 res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
15856 } else if (!ps.getInstantApp(user.getIdentifier())) {
15857 // can't downgrade from full to instant
15858 Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
15859 + " for user: " + user.getIdentifier());
15860 res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
15866 // Update what is removed
15867 res.removedInfo = new PackageRemovedInfo();
15868 res.removedInfo.uid = oldPackage.applicationInfo.uid;
15869 res.removedInfo.removedPackage = oldPackage.packageName;
15870 res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
15871 res.removedInfo.isUpdate = true;
15872 res.removedInfo.origUsers = installedUsers;
15873 final PackageSetting ps = mSettings.getPackageLPr(pkgName);
15874 res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
15875 for (int i = 0; i < installedUsers.length; i++) {
15876 final int userId = installedUsers[i];
15877 res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
15880 final int childCount = (oldPackage.childPackages != null)
15881 ? oldPackage.childPackages.size() : 0;
15882 for (int i = 0; i < childCount; i++) {
15883 boolean childPackageUpdated = false;
15884 PackageParser.Package childPkg = oldPackage.childPackages.get(i);
15885 final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
15886 if (res.addedChildPackages != null) {
15887 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
15888 if (childRes != null) {
15889 childRes.removedInfo.uid = childPkg.applicationInfo.uid;
15890 childRes.removedInfo.removedPackage = childPkg.packageName;
15891 childRes.removedInfo.isUpdate = true;
15892 childRes.removedInfo.installReasons = res.removedInfo.installReasons;
15893 childPackageUpdated = true;
15896 if (!childPackageUpdated) {
15897 PackageRemovedInfo childRemovedRes = new PackageRemovedInfo();
15898 childRemovedRes.removedPackage = childPkg.packageName;
15899 childRemovedRes.isUpdate = false;
15900 childRemovedRes.dataRemoved = true;
15901 synchronized (mPackages) {
15902 if (childPs != null) {
15903 childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
15906 if (res.removedInfo.removedChildPackages == null) {
15907 res.removedInfo.removedChildPackages = new ArrayMap<>();
15909 res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
15913 boolean sysPkg = (isSystemApp(oldPackage));
15915 // Set the system/privileged flags as needed
15916 final boolean privileged =
15917 (oldPackage.applicationInfo.privateFlags
15918 & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
15919 final int systemPolicyFlags = policyFlags
15920 | PackageParser.PARSE_IS_SYSTEM
15921 | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0);
15923 replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags,
15924 user, allUsers, installerPackageName, res, installReason);
15926 replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags,
15927 user, allUsers, installerPackageName, res, installReason);
15931 public List<String> getPreviousCodePaths(String packageName) {
15932 final PackageSetting ps = mSettings.mPackages.get(packageName);
15933 final List<String> result = new ArrayList<String>();
15934 if (ps != null && ps.oldCodePaths != null) {
15935 result.addAll(ps.oldCodePaths);
15940 private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
15941 PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
15942 int[] allUsers, String installerPackageName, PackageInstalledInfo res,
15943 int installReason) {
15944 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
15947 String pkgName = deletedPackage.packageName;
15948 boolean deletedPkg = true;
15949 boolean addedPkg = false;
15950 boolean updatedSettings = false;
15951 final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
15952 final int deleteFlags = PackageManager.DELETE_KEEP_DATA
15953 | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
15955 final long origUpdateTime = (pkg.mExtras != null)
15956 ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
15958 // First delete the existing package while retaining the data directory
15959 if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
15960 res.removedInfo, true, pkg)) {
15961 // If the existing package wasn't successfully deleted
15962 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
15963 deletedPkg = false;
15965 // Successfully deleted the old package; proceed with replace.
15967 // If deleted package lived in a container, give users a chance to
15968 // relinquish resources before killing.
15969 if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
15970 if (DEBUG_INSTALL) {
15971 Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
15973 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
15974 final ArrayList<String> pkgList = new ArrayList<String>(1);
15975 pkgList.add(deletedPackage.applicationInfo.packageName);
15976 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
15979 clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
15980 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
15981 clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
15984 final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags,
15985 scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
15986 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
15989 // Update the in-memory copy of the previous code paths.
15990 PackageSetting ps = mSettings.mPackages.get(pkgName);
15992 if (ps.oldCodePaths == null) {
15993 ps.oldCodePaths = new ArraySet<>();
15995 Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
15996 if (deletedPackage.splitCodePaths != null) {
15997 Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
16000 ps.oldCodePaths = null;
16002 if (ps.childPackageNames != null) {
16003 for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
16004 final String childPkgName = ps.childPackageNames.get(i);
16005 final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
16006 childPs.oldCodePaths = ps.oldCodePaths;
16009 // set instant app status, but, only if it's explicitly specified
16010 final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
16011 final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
16012 setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp);
16013 prepareAppDataAfterInstallLIF(newPackage);
16015 mDexManager.notifyPackageUpdated(newPackage.packageName,
16016 newPackage.baseCodePath, newPackage.splitCodePaths);
16017 } catch (PackageManagerException e) {
16018 res.setError("Package couldn't be installed in " + pkg.codePath, e);
16022 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16023 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
16025 // Revert all internal state mutations and added folders for the failed install
16027 deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
16028 res.removedInfo, true, null);
16031 // Restore the old package
16033 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
16034 File restoreFile = new File(deletedPackage.codePath);
16035 // Parse old package
16036 boolean oldExternal = isExternal(deletedPackage);
16037 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY |
16038 (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
16039 (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
16040 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
16042 scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
16044 } catch (PackageManagerException e) {
16045 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
16050 synchronized (mPackages) {
16051 // Ensure the installer package name up to date
16052 setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16054 // Update permissions for restored package
16055 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
16057 mSettings.writeLPr();
16060 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
16063 synchronized (mPackages) {
16064 PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);
16066 res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
16067 if (res.removedInfo.removedChildPackages != null) {
16068 final int childCount = res.removedInfo.removedChildPackages.size();
16069 // Iterate in reverse as we may modify the collection
16070 for (int i = childCount - 1; i >= 0; i--) {
16071 String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
16072 if (res.addedChildPackages.containsKey(childPackageName)) {
16073 res.removedInfo.removedChildPackages.removeAt(i);
16075 PackageRemovedInfo childInfo = res.removedInfo
16076 .removedChildPackages.valueAt(i);
16077 childInfo.removedForAllUsers = mPackages.get(
16078 childInfo.removedPackage) == null;
16087 private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
16088 PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
16089 int[] allUsers, String installerPackageName, PackageInstalledInfo res,
16090 int installReason) {
16091 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
16092 + ", old=" + deletedPackage);
16094 final boolean disabledSystem;
16096 // Remove existing system package
16097 removePackageLI(deletedPackage, true);
16099 synchronized (mPackages) {
16100 disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
16102 if (!disabledSystem) {
16103 // We didn't need to disable the .apk as a current system package,
16104 // which means we are replacing another update that is already
16105 // installed. We need to make sure to delete the older one's .apk.
16106 res.removedInfo.args = createInstallArgsForExisting(0,
16107 deletedPackage.applicationInfo.getCodePath(),
16108 deletedPackage.applicationInfo.getResourcePath(),
16109 getAppDexInstructionSets(deletedPackage.applicationInfo));
16111 res.removedInfo.args = null;
16114 // Successfully disabled the old package. Now proceed with re-installation
16115 clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
16116 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16117 clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
16119 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16120 pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
16121 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
16123 PackageParser.Package newPackage = null;
16125 // Add the package to the internal data structures
16126 newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user);
16128 // Set the update and install times
16129 PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
16130 setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
16131 System.currentTimeMillis());
16133 // Update the package dynamic state if succeeded
16134 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16135 // Now that the install succeeded make sure we remove data
16136 // directories for any child package the update removed.
16137 final int deletedChildCount = (deletedPackage.childPackages != null)
16138 ? deletedPackage.childPackages.size() : 0;
16139 final int newChildCount = (newPackage.childPackages != null)
16140 ? newPackage.childPackages.size() : 0;
16141 for (int i = 0; i < deletedChildCount; i++) {
16142 PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
16143 boolean childPackageDeleted = true;
16144 for (int j = 0; j < newChildCount; j++) {
16145 PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
16146 if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
16147 childPackageDeleted = false;
16151 if (childPackageDeleted) {
16152 PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
16153 deletedChildPkg.packageName);
16154 if (ps != null && res.removedInfo.removedChildPackages != null) {
16155 PackageRemovedInfo removedChildRes = res.removedInfo
16156 .removedChildPackages.get(deletedChildPkg.packageName);
16157 removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
16158 removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
16163 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16165 prepareAppDataAfterInstallLIF(newPackage);
16167 mDexManager.notifyPackageUpdated(newPackage.packageName,
16168 newPackage.baseCodePath, newPackage.splitCodePaths);
16170 } catch (PackageManagerException e) {
16171 res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
16172 res.setError("Package couldn't be installed in " + pkg.codePath, e);
16175 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16176 // Re installation failed. Restore old information
16177 // Remove new pkg information
16178 if (newPackage != null) {
16179 removeInstalledPackageLI(newPackage, true);
16181 // Add back the old system package
16183 scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user);
16184 } catch (PackageManagerException e) {
16185 Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
16188 synchronized (mPackages) {
16189 if (disabledSystem) {
16190 enableSystemPackageLPw(deletedPackage);
16193 // Ensure the installer package name up to date
16194 setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16196 // Update permissions for restored package
16197 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
16199 mSettings.writeLPr();
16202 Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
16203 + " after failed upgrade");
16208 * Checks whether the parent or any of the child packages have a change shared
16209 * user. For a package to be a valid update the shred users of the parent and
16210 * the children should match. We may later support changing child shared users.
16211 * @param oldPkg The updated package.
16212 * @param newPkg The update package.
16213 * @return The shared user that change between the versions.
16215 private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
16216 PackageParser.Package newPkg) {
16217 // Check parent shared user
16218 if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
16219 return newPkg.packageName;
16221 // Check child shared users
16222 final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16223 final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
16224 for (int i = 0; i < newChildCount; i++) {
16225 PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
16226 // If this child was present, did it have the same shared user?
16227 for (int j = 0; j < oldChildCount; j++) {
16228 PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
16229 if (newChildPkg.packageName.equals(oldChildPkg.packageName)
16230 && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
16231 return newChildPkg.packageName;
16238 private void removeNativeBinariesLI(PackageSetting ps) {
16239 // Remove the lib path for the parent package
16241 NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
16242 // Remove the lib path for the child packages
16243 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
16244 for (int i = 0; i < childCount; i++) {
16245 PackageSetting childPs = null;
16246 synchronized (mPackages) {
16247 childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
16249 if (childPs != null) {
16250 NativeLibraryHelper.removeNativeBinariesLI(childPs
16251 .legacyNativeLibraryPathString);
16257 private void enableSystemPackageLPw(PackageParser.Package pkg) {
16258 // Enable the parent package
16259 mSettings.enableSystemPackageLPw(pkg.packageName);
16260 // Enable the child packages
16261 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16262 for (int i = 0; i < childCount; i++) {
16263 PackageParser.Package childPkg = pkg.childPackages.get(i);
16264 mSettings.enableSystemPackageLPw(childPkg.packageName);
16268 private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
16269 PackageParser.Package newPkg) {
16270 // Disable the parent package (parent always replaced)
16271 boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
16272 // Disable the child packages
16273 final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16274 for (int i = 0; i < childCount; i++) {
16275 PackageParser.Package childPkg = oldPkg.childPackages.get(i);
16276 final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
16277 disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
16282 private void setInstallerPackageNameLPw(PackageParser.Package pkg,
16283 String installerPackageName) {
16284 // Enable the parent package
16285 mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
16286 // Enable the child packages
16287 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16288 for (int i = 0; i < childCount; i++) {
16289 PackageParser.Package childPkg = pkg.childPackages.get(i);
16290 mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
16294 private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
16295 // Collect all used permissions in the UID
16296 ArraySet<String> usedPermissions = new ArraySet<>();
16297 final int packageCount = su.packages.size();
16298 for (int i = 0; i < packageCount; i++) {
16299 PackageSetting ps = su.packages.valueAt(i);
16300 if (ps.pkg == null) {
16303 final int requestedPermCount = ps.pkg.requestedPermissions.size();
16304 for (int j = 0; j < requestedPermCount; j++) {
16305 String permission = ps.pkg.requestedPermissions.get(j);
16306 BasePermission bp = mSettings.mPermissions.get(permission);
16308 usedPermissions.add(permission);
16313 PermissionsState permissionsState = su.getPermissionsState();
16314 // Prune install permissions
16315 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
16316 final int installPermCount = installPermStates.size();
16317 for (int i = installPermCount - 1; i >= 0; i--) {
16318 PermissionState permissionState = installPermStates.get(i);
16319 if (!usedPermissions.contains(permissionState.getName())) {
16320 BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
16322 permissionsState.revokeInstallPermission(bp);
16323 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
16324 PackageManager.MASK_PERMISSION_FLAGS, 0);
16329 int[] runtimePermissionChangedUserIds = EmptyArray.INT;
16331 // Prune runtime permissions
16332 for (int userId : allUserIds) {
16333 List<PermissionState> runtimePermStates = permissionsState
16334 .getRuntimePermissionStates(userId);
16335 final int runtimePermCount = runtimePermStates.size();
16336 for (int i = runtimePermCount - 1; i >= 0; i--) {
16337 PermissionState permissionState = runtimePermStates.get(i);
16338 if (!usedPermissions.contains(permissionState.getName())) {
16339 BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
16341 permissionsState.revokeRuntimePermission(bp, userId);
16342 permissionsState.updatePermissionFlags(bp, userId,
16343 PackageManager.MASK_PERMISSION_FLAGS, 0);
16344 runtimePermissionChangedUserIds = ArrayUtils.appendInt(
16345 runtimePermissionChangedUserIds, userId);
16351 return runtimePermissionChangedUserIds;
16354 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
16355 int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
16356 // Update the parent package setting
16357 updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
16358 res, user, installReason);
16359 // Update the child packages setting
16360 final int childCount = (newPackage.childPackages != null)
16361 ? newPackage.childPackages.size() : 0;
16362 for (int i = 0; i < childCount; i++) {
16363 PackageParser.Package childPackage = newPackage.childPackages.get(i);
16364 PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
16365 updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
16366 childRes.origUsers, childRes, user, installReason);
16370 private void updateSettingsInternalLI(PackageParser.Package newPackage,
16371 String installerPackageName, int[] allUsers, int[] installedForUsers,
16372 PackageInstalledInfo res, UserHandle user, int installReason) {
16373 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
16375 String pkgName = newPackage.packageName;
16376 synchronized (mPackages) {
16377 //write settings. the installStatus will be incomplete at this stage.
16378 //note that the new package setting would have already been
16379 //added to mPackages. It hasn't been persisted yet.
16380 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
16381 // TODO: Remove this write? It's also written at the end of this method
16382 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
16383 mSettings.writeLPr();
16384 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16387 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
16388 synchronized (mPackages) {
16389 updatePermissionsLPw(newPackage.packageName, newPackage,
16390 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
16391 ? UPDATE_PERMISSIONS_ALL : 0));
16392 // For system-bundled packages, we assume that installing an upgraded version
16393 // of the package implies that the user actually wants to run that new code,
16394 // so we enable the package.
16395 PackageSetting ps = mSettings.mPackages.get(pkgName);
16396 final int userId = user.getIdentifier();
16398 if (isSystemApp(newPackage)) {
16399 if (DEBUG_INSTALL) {
16400 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
16402 // Enable system package for requested users
16403 if (res.origUsers != null) {
16404 for (int origUserId : res.origUsers) {
16405 if (userId == UserHandle.USER_ALL || userId == origUserId) {
16406 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
16407 origUserId, installerPackageName);
16411 // Also convey the prior install/uninstall state
16412 if (allUsers != null && installedForUsers != null) {
16413 for (int currentUserId : allUsers) {
16414 final boolean installed = ArrayUtils.contains(
16415 installedForUsers, currentUserId);
16416 if (DEBUG_INSTALL) {
16417 Slog.d(TAG, " user " + currentUserId + " => " + installed);
16419 ps.setInstalled(installed, currentUserId);
16421 // these install state changes will be persisted in the
16422 // upcoming call to mSettings.writeLPr().
16425 // It's implied that when a user requests installation, they want the app to be
16426 // installed and enabled.
16427 if (userId != UserHandle.USER_ALL) {
16428 ps.setInstalled(true, userId);
16429 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
16432 // When replacing an existing package, preserve the original install reason for all
16433 // users that had the package installed before.
16434 final Set<Integer> previousUserIds = new ArraySet<>();
16435 if (res.removedInfo != null && res.removedInfo.installReasons != null) {
16436 final int installReasonCount = res.removedInfo.installReasons.size();
16437 for (int i = 0; i < installReasonCount; i++) {
16438 final int previousUserId = res.removedInfo.installReasons.keyAt(i);
16439 final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
16440 ps.setInstallReason(previousInstallReason, previousUserId);
16441 previousUserIds.add(previousUserId);
16445 // Set install reason for users that are having the package newly installed.
16446 if (userId == UserHandle.USER_ALL) {
16447 for (int currentUserId : sUserManager.getUserIds()) {
16448 if (!previousUserIds.contains(currentUserId)) {
16449 ps.setInstallReason(installReason, currentUserId);
16452 } else if (!previousUserIds.contains(userId)) {
16453 ps.setInstallReason(installReason, userId);
16455 mSettings.writeKernelMappingLPr(ps);
16457 res.name = pkgName;
16458 res.uid = newPackage.applicationInfo.uid;
16459 res.pkg = newPackage;
16460 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
16461 mSettings.setInstallerPackageName(pkgName, installerPackageName);
16462 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16463 //to update install status
16464 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
16465 mSettings.writeLPr();
16466 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16469 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16472 private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
16474 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
16475 installPackageLI(args, res);
16477 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16481 private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
16482 final int installFlags = args.installFlags;
16483 final String installerPackageName = args.installerPackageName;
16484 final String volumeUuid = args.volumeUuid;
16485 final File tmpPackageFile = new File(args.getCodePath());
16486 final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
16487 final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
16488 || (args.volumeUuid != null));
16489 final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
16490 final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
16491 final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
16492 boolean replace = false;
16493 int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
16494 if (args.move != null) {
16495 // moving a complete application; perform an initial scan on the new install location
16496 scanFlags |= SCAN_INITIAL;
16498 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
16499 scanFlags |= SCAN_DONT_KILL_APP;
16502 scanFlags |= SCAN_AS_INSTANT_APP;
16505 scanFlags |= SCAN_AS_FULL_APP;
16508 // Result object to be returned
16509 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16511 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
16514 if (instantApp && (forwardLocked || onExternal)) {
16515 Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
16516 + " external=" + onExternal);
16517 res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16521 // Retrieve PackageSettings and parse package
16522 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
16523 | PackageParser.PARSE_ENFORCE_CODE
16524 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
16525 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
16526 | (instantApp ? PackageParser.PARSE_IS_EPHEMERAL : 0)
16527 | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
16528 PackageParser pp = new PackageParser();
16529 pp.setSeparateProcesses(mSeparateProcesses);
16530 pp.setDisplayMetrics(mMetrics);
16531 pp.setCallback(mPackageParserCallback);
16533 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
16534 final PackageParser.Package pkg;
16536 pkg = pp.parsePackage(tmpPackageFile, parseFlags);
16537 } catch (PackageParserException e) {
16538 res.setError("Failed parse during installPackageLI", e);
16541 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16544 // Instant apps must have target SDK >= O and have targetSanboxVersion >= 2
16545 if (instantApp && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
16546 Slog.w(TAG, "Instant app package " + pkg.packageName
16547 + " does not target O, this will be a fatal error.");
16548 // STOPSHIP: Make this a fatal error
16549 pkg.applicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
16551 if (instantApp && pkg.applicationInfo.targetSandboxVersion != 2) {
16552 Slog.w(TAG, "Instant app package " + pkg.packageName
16553 + " does not target targetSandboxVersion 2, this will be a fatal error.");
16554 // STOPSHIP: Make this a fatal error
16555 pkg.applicationInfo.targetSandboxVersion = 2;
16558 if (pkg.applicationInfo.isStaticSharedLibrary()) {
16559 // Static shared libraries have synthetic package names
16560 renameStaticSharedLibraryPackage(pkg);
16562 // No static shared libs on external storage
16564 Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
16565 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
16566 "Packages declaring static-shared libs cannot be updated");
16571 // If we are installing a clustered package add results for the children
16572 if (pkg.childPackages != null) {
16573 synchronized (mPackages) {
16574 final int childCount = pkg.childPackages.size();
16575 for (int i = 0; i < childCount; i++) {
16576 PackageParser.Package childPkg = pkg.childPackages.get(i);
16577 PackageInstalledInfo childRes = new PackageInstalledInfo();
16578 childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16579 childRes.pkg = childPkg;
16580 childRes.name = childPkg.packageName;
16581 PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16582 if (childPs != null) {
16583 childRes.origUsers = childPs.queryInstalledUsers(
16584 sUserManager.getUserIds(), true);
16586 if ((mPackages.containsKey(childPkg.packageName))) {
16587 childRes.removedInfo = new PackageRemovedInfo();
16588 childRes.removedInfo.removedPackage = childPkg.packageName;
16590 if (res.addedChildPackages == null) {
16591 res.addedChildPackages = new ArrayMap<>();
16593 res.addedChildPackages.put(childPkg.packageName, childRes);
16598 // If package doesn't declare API override, mark that we have an install
16599 // time CPU ABI override.
16600 if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
16601 pkg.cpuAbiOverride = args.abiOverride;
16604 String pkgName = res.name = pkg.packageName;
16605 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
16606 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
16607 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
16613 // either use what we've been given or parse directly from the APK
16614 if (args.certificates != null) {
16616 PackageParser.populateCertificates(pkg, args.certificates);
16617 } catch (PackageParserException e) {
16618 // there was something wrong with the certificates we were given;
16619 // try to pull them from the APK
16620 PackageParser.collectCertificates(pkg, parseFlags);
16623 PackageParser.collectCertificates(pkg, parseFlags);
16625 } catch (PackageParserException e) {
16626 res.setError("Failed collect during installPackageLI", e);
16630 // Get rid of all references to package scan path via parser.
16632 String oldCodePath = null;
16633 boolean systemApp = false;
16634 synchronized (mPackages) {
16635 // Check if installing already existing package
16636 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
16637 String oldName = mSettings.getRenamedPackageLPr(pkgName);
16638 if (pkg.mOriginalPackages != null
16639 && pkg.mOriginalPackages.contains(oldName)
16640 && mPackages.containsKey(oldName)) {
16641 // This package is derived from an original package,
16642 // and this device has been updating from that original
16643 // name. We must continue using the original name, so
16644 // rename the new package here.
16645 pkg.setPackageName(oldName);
16646 pkgName = pkg.packageName;
16648 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
16649 + oldName + " pkgName=" + pkgName);
16650 } else if (mPackages.containsKey(pkgName)) {
16651 // This package, under its official name, already exists
16652 // on the device; we should replace it.
16654 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
16657 // Child packages are installed through the parent package
16658 if (pkg.parentPackage != null) {
16659 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
16660 "Package " + pkg.packageName + " is child of package "
16661 + pkg.parentPackage.parentPackage + ". Child packages "
16662 + "can be updated only through the parent package.");
16667 // Prevent apps opting out from runtime permissions
16668 PackageParser.Package oldPackage = mPackages.get(pkgName);
16669 final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
16670 final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
16671 if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
16672 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
16673 res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
16674 "Package " + pkg.packageName + " new target SDK " + newTargetSdk
16675 + " doesn't support runtime permissions but the old"
16676 + " target SDK " + oldTargetSdk + " does.");
16679 // Prevent apps from downgrading their targetSandbox.
16680 final int oldTargetSandbox = oldPackage.applicationInfo.targetSandboxVersion;
16681 final int newTargetSandbox = pkg.applicationInfo.targetSandboxVersion;
16682 if (oldTargetSandbox == 2 && newTargetSandbox != 2) {
16683 res.setError(PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
16684 "Package " + pkg.packageName + " new target sandbox "
16685 + newTargetSandbox + " is incompatible with the previous value of"
16686 + oldTargetSandbox + ".");
16690 // Prevent installing of child packages
16691 if (oldPackage.parentPackage != null) {
16692 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
16693 "Package " + pkg.packageName + " is child of package "
16694 + oldPackage.parentPackage + ". Child packages "
16695 + "can be updated only through the parent package.");
16701 PackageSetting ps = mSettings.mPackages.get(pkgName);
16703 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
16705 // Static shared libs have same package with different versions where
16706 // we internally use a synthetic package name to allow multiple versions
16707 // of the same package, therefore we need to compare signatures against
16708 // the package setting for the latest library version.
16709 PackageSetting signatureCheckPs = ps;
16710 if (pkg.applicationInfo.isStaticSharedLibrary()) {
16711 SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
16712 if (libraryEntry != null) {
16713 signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
16717 // Quick sanity check that we're signed correctly if updating;
16718 // we'll check this again later when scanning, but we want to
16719 // bail early here before tripping over redefined permissions.
16720 if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
16721 if (!checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
16722 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
16723 + pkg.packageName + " upgrade keys do not match the "
16724 + "previously installed version");
16729 verifySignaturesLP(signatureCheckPs, pkg);
16730 } catch (PackageManagerException e) {
16731 res.setError(e.error, e.getMessage());
16736 oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
16737 if (ps.pkg != null && ps.pkg.applicationInfo != null) {
16738 systemApp = (ps.pkg.applicationInfo.flags &
16739 ApplicationInfo.FLAG_SYSTEM) != 0;
16741 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
16744 int N = pkg.permissions.size();
16745 for (int i = N-1; i >= 0; i--) {
16746 PackageParser.Permission perm = pkg.permissions.get(i);
16747 BasePermission bp = mSettings.mPermissions.get(perm.info.name);
16749 // Don't allow anyone but the platform to define ephemeral permissions.
16750 if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_EPHEMERAL) != 0
16751 && !PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
16752 Slog.w(TAG, "Package " + pkg.packageName
16753 + " attempting to delcare ephemeral permission "
16754 + perm.info.name + "; Removing ephemeral.");
16755 perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_EPHEMERAL;
16757 // Check whether the newly-scanned package wants to define an already-defined perm
16759 // If the defining package is signed with our cert, it's okay. This
16760 // also includes the "updating the same package" case, of course.
16761 // "updating same package" could also involve key-rotation.
16762 final boolean sigsOk;
16763 if (bp.sourcePackage.equals(pkg.packageName)
16764 && (bp.packageSetting instanceof PackageSetting)
16765 && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting,
16767 sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
16769 sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
16770 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
16773 // If the owning package is the system itself, we log but allow
16774 // install to proceed; we fail the install on all other permission
16776 if (!bp.sourcePackage.equals("android")) {
16777 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
16778 + pkg.packageName + " attempting to redeclare permission "
16779 + perm.info.name + " already owned by " + bp.sourcePackage);
16780 res.origPermission = perm.info.name;
16781 res.origPackage = bp.sourcePackage;
16784 Slog.w(TAG, "Package " + pkg.packageName
16785 + " attempting to redeclare system permission "
16786 + perm.info.name + "; ignoring new declaration");
16787 pkg.permissions.remove(i);
16789 } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
16790 // Prevent apps to change protection level to dangerous from any other
16791 // type as this would allow a privilege escalation where an app adds a
16792 // normal/signature permission in other app's group and later redefines
16793 // it as dangerous leading to the group auto-grant.
16794 if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
16795 == PermissionInfo.PROTECTION_DANGEROUS) {
16796 if (bp != null && !bp.isRuntime()) {
16797 Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
16798 + "non-runtime permission " + perm.info.name
16799 + " to runtime; keeping old protection level");
16800 perm.info.protectionLevel = bp.protectionLevel;
16810 // Abort update; system app can't be replaced with app on sdcard
16811 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
16812 "Cannot install updates to system apps on sdcard");
16814 } else if (instantApp) {
16815 // Abort update; system app can't be replaced with an instant app
16816 res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
16817 "Cannot update a system app with an instant app");
16822 if (args.move != null) {
16823 // We did an in-place move, so dex is ready to roll
16824 scanFlags |= SCAN_NO_DEX;
16825 scanFlags |= SCAN_MOVE;
16827 synchronized (mPackages) {
16828 final PackageSetting ps = mSettings.mPackages.get(pkgName);
16830 res.setError(INSTALL_FAILED_INTERNAL_ERROR,
16831 "Missing settings for moved package " + pkgName);
16834 // We moved the entire application as-is, so bring over the
16835 // previously derived ABI information.
16836 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
16837 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
16840 } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
16841 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
16842 scanFlags |= SCAN_NO_DEX;
16845 String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
16846 args.abiOverride : pkg.cpuAbiOverride);
16847 derivePackageAbi(pkg, new File(pkg.codePath), abiOverride,
16848 true /*extractLibs*/, mAppLib32InstallDir);
16849 } catch (PackageManagerException pme) {
16850 Slog.e(TAG, "Error deriving application ABI", pme);
16851 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
16855 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
16856 // Do not run PackageDexOptimizer through the local performDexOpt
16857 // method because `pkg` may not be in `mPackages` yet.
16859 // Also, don't fail application installs if the dexopt step fails.
16860 mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
16861 null /* instructionSets */, false /* checkProfiles */,
16862 getCompilerFilterForReason(REASON_INSTALL),
16863 getOrCreateCompilerPackageStats(pkg),
16864 mDexManager.isUsedByOtherApps(pkg.packageName));
16865 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16867 // Notify BackgroundDexOptService that the package has been changed.
16868 // If this is an update of a package which used to fail to compile,
16869 // BDOS will remove it from its blacklist.
16870 // TODO: Layering violation
16871 BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
16874 if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
16875 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
16879 startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
16881 try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
16882 "installPackageLI")) {
16884 if (pkg.applicationInfo.isStaticSharedLibrary()) {
16885 // Static libs have a synthetic package name containing the version
16886 // and cannot be updated as an update would get a new package name,
16887 // unless this is the exact same version code which is useful for
16889 PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
16890 if (existingPkg != null && existingPkg.mVersionCode != pkg.mVersionCode) {
16891 res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
16892 + "static-shared libs cannot be updated");
16896 replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
16897 installerPackageName, res, args.installReason);
16899 installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
16900 args.user, installerPackageName, volumeUuid, res, args.installReason);
16903 synchronized (mPackages) {
16904 final PackageSetting ps = mSettings.mPackages.get(pkgName);
16906 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
16907 ps.setUpdateAvailable(false /*updateAvailable*/);
16910 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16911 for (int i = 0; i < childCount; i++) {
16912 PackageParser.Package childPkg = pkg.childPackages.get(i);
16913 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
16914 PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16915 if (childPs != null) {
16916 childRes.newUsers = childPs.queryInstalledUsers(
16917 sUserManager.getUserIds(), true);
16921 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16922 updateSequenceNumberLP(pkgName, res.newUsers);
16923 updateInstantAppInstallerLocked();
16928 private void startIntentFilterVerifications(int userId, boolean replacing,
16929 PackageParser.Package pkg) {
16930 if (mIntentFilterVerifierComponent == null) {
16931 Slog.w(TAG, "No IntentFilter verification will not be done as "
16932 + "there is no IntentFilterVerifier available!");
16936 final int verifierUid = getPackageUid(
16937 mIntentFilterVerifierComponent.getPackageName(),
16938 MATCH_DEBUG_TRIAGED_MISSING,
16939 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
16941 Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
16942 msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
16943 mHandler.sendMessage(msg);
16945 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16946 for (int i = 0; i < childCount; i++) {
16947 PackageParser.Package childPkg = pkg.childPackages.get(i);
16948 msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
16949 msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
16950 mHandler.sendMessage(msg);
16954 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
16955 PackageParser.Package pkg) {
16956 int size = pkg.activities.size();
16958 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
16959 "No activity, so no need to verify any IntentFilter!");
16963 final boolean hasDomainURLs = hasDomainURLs(pkg);
16964 if (!hasDomainURLs) {
16965 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
16966 "No domain URLs, so no need to verify any IntentFilter!");
16970 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
16971 + " if any IntentFilter from the " + size
16972 + " Activities needs verification ...");
16975 final String packageName = pkg.packageName;
16977 synchronized (mPackages) {
16978 // If this is a new install and we see that we've already run verification for this
16979 // package, we have nothing to do: it means the state was restored from backup.
16981 IntentFilterVerificationInfo ivi =
16982 mSettings.getIntentFilterVerificationLPr(packageName);
16984 if (DEBUG_DOMAIN_VERIFICATION) {
16985 Slog.i(TAG, "Package " + packageName+ " already verified: status="
16986 + ivi.getStatusString());
16992 // If any filters need to be verified, then all need to be.
16993 boolean needToVerify = false;
16994 for (PackageParser.Activity a : pkg.activities) {
16995 for (ActivityIntentInfo filter : a.intents) {
16996 if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
16997 if (DEBUG_DOMAIN_VERIFICATION) {
16998 Slog.d(TAG, "Intent filter needs verification, so processing all filters");
17000 needToVerify = true;
17006 if (needToVerify) {
17007 final int verificationId = mIntentFilterVerificationToken++;
17008 for (PackageParser.Activity a : pkg.activities) {
17009 for (ActivityIntentInfo filter : a.intents) {
17010 if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
17011 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17012 "Verification needed for IntentFilter:" + filter.toString());
17013 mIntentFilterVerifier.addOneIntentFilterVerification(
17014 verifierUid, userId, verificationId, filter, packageName);
17023 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
17024 + " IntentFilter verification" + (count > 1 ? "s" : "")
17025 + " for userId:" + userId);
17026 mIntentFilterVerifier.startVerifications(userId);
17028 if (DEBUG_DOMAIN_VERIFICATION) {
17029 Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
17034 private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
17035 final ComponentName cn = filter.activity.getComponentName();
17036 final String packageName = cn.getPackageName();
17038 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
17043 int status = ivi.getStatus();
17045 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
17046 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
17055 private static boolean isMultiArch(ApplicationInfo info) {
17056 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
17059 private static boolean isExternal(PackageParser.Package pkg) {
17060 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17063 private static boolean isExternal(PackageSetting ps) {
17064 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17067 private static boolean isSystemApp(PackageParser.Package pkg) {
17068 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
17071 private static boolean isPrivilegedApp(PackageParser.Package pkg) {
17072 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
17075 private static boolean hasDomainURLs(PackageParser.Package pkg) {
17076 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
17079 private static boolean isSystemApp(PackageSetting ps) {
17080 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
17083 private static boolean isUpdatedSystemApp(PackageSetting ps) {
17084 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
17087 private int packageFlagsToInstallFlags(PackageSetting ps) {
17088 int installFlags = 0;
17089 if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
17090 // This existing package was an external ASEC install when we have
17091 // the external flag without a UUID
17092 installFlags |= PackageManager.INSTALL_EXTERNAL;
17094 if (ps.isForwardLocked()) {
17095 installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
17097 return installFlags;
17100 private String getVolumeUuidForPackage(PackageParser.Package pkg) {
17101 if (isExternal(pkg)) {
17102 if (TextUtils.isEmpty(pkg.volumeUuid)) {
17103 return StorageManager.UUID_PRIMARY_PHYSICAL;
17105 return pkg.volumeUuid;
17108 return StorageManager.UUID_PRIVATE_INTERNAL;
17112 private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
17113 if (isExternal(pkg)) {
17114 if (TextUtils.isEmpty(pkg.volumeUuid)) {
17115 return mSettings.getExternalVersion();
17117 return mSettings.findOrCreateVersion(pkg.volumeUuid);
17120 return mSettings.getInternalVersion();
17124 private void deleteTempPackageFiles() {
17125 final FilenameFilter filter = new FilenameFilter() {
17126 public boolean accept(File dir, String name) {
17127 return name.startsWith("vmdl") && name.endsWith(".tmp");
17130 for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
17136 public void deletePackageAsUser(String packageName, int versionCode,
17137 IPackageDeleteObserver observer, int userId, int flags) {
17138 deletePackageVersioned(new VersionedPackage(packageName, versionCode),
17139 new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
17143 public void deletePackageVersioned(VersionedPackage versionedPackage,
17144 final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
17145 mContext.enforceCallingOrSelfPermission(
17146 android.Manifest.permission.DELETE_PACKAGES, null);
17147 Preconditions.checkNotNull(versionedPackage);
17148 Preconditions.checkNotNull(observer);
17149 Preconditions.checkArgumentInRange(versionedPackage.getVersionCode(),
17150 PackageManager.VERSION_CODE_HIGHEST,
17151 Integer.MAX_VALUE, "versionCode must be >= -1");
17153 final String packageName = versionedPackage.getPackageName();
17154 // TODO: We will change version code to long, so in the new API it is long
17155 final int versionCode = (int) versionedPackage.getVersionCode();
17156 final String internalPackageName;
17157 synchronized (mPackages) {
17158 // Normalize package name to handle renamed packages and static libs
17159 internalPackageName = resolveInternalPackageNameLPr(versionedPackage.getPackageName(),
17160 // TODO: We will change version code to long, so in the new API it is long
17161 (int) versionedPackage.getVersionCode());
17164 final int uid = Binder.getCallingUid();
17165 if (!isOrphaned(internalPackageName)
17166 && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
17168 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
17169 intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
17170 intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
17171 observer.onUserActionRequired(intent);
17172 } catch (RemoteException re) {
17176 final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
17177 final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
17178 if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
17179 mContext.enforceCallingOrSelfPermission(
17180 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
17181 "deletePackage for user " + userId);
17184 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
17186 observer.onPackageDeleted(packageName,
17187 PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
17188 } catch (RemoteException re) {
17193 if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
17195 observer.onPackageDeleted(packageName,
17196 PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
17197 } catch (RemoteException re) {
17202 if (DEBUG_REMOVE) {
17203 Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
17204 + " deleteAllUsers: " + deleteAllUsers + " version="
17205 + (versionCode == PackageManager.VERSION_CODE_HIGHEST
17206 ? "VERSION_CODE_HIGHEST" : versionCode));
17208 // Queue up an async operation since the package deletion may take a little while.
17209 mHandler.post(new Runnable() {
17210 public void run() {
17211 mHandler.removeCallbacks(this);
17213 if (!deleteAllUsers) {
17214 returnCode = deletePackageX(internalPackageName, versionCode,
17215 userId, deleteFlags);
17217 int[] blockUninstallUserIds = getBlockUninstallForUsers(
17218 internalPackageName, users);
17219 // If nobody is blocking uninstall, proceed with delete for all users
17220 if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
17221 returnCode = deletePackageX(internalPackageName, versionCode,
17222 userId, deleteFlags);
17224 // Otherwise uninstall individually for users with blockUninstalls=false
17225 final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
17226 for (int userId : users) {
17227 if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
17228 returnCode = deletePackageX(internalPackageName, versionCode,
17229 userId, userFlags);
17230 if (returnCode != PackageManager.DELETE_SUCCEEDED) {
17231 Slog.w(TAG, "Package delete failed for user " + userId
17232 + ", returnCode " + returnCode);
17236 // The app has only been marked uninstalled for certain users.
17237 // We still need to report that delete was blocked
17238 returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
17242 observer.onPackageDeleted(packageName, returnCode, null);
17243 } catch (RemoteException e) {
17244 Log.i(TAG, "Observer no longer exists.");
17250 private String resolveExternalPackageNameLPr(PackageParser.Package pkg) {
17251 if (pkg.staticSharedLibName != null) {
17252 return pkg.manifestPackageName;
17254 return pkg.packageName;
17257 private String resolveInternalPackageNameLPr(String packageName, int versionCode) {
17258 // Handle renamed packages
17259 String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
17260 packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
17262 // Is this a static library?
17263 SparseArray<SharedLibraryEntry> versionedLib =
17264 mStaticLibsByDeclaringPackage.get(packageName);
17265 if (versionedLib == null || versionedLib.size() <= 0) {
17266 return packageName;
17269 // Figure out which lib versions the caller can see
17270 SparseIntArray versionsCallerCanSee = null;
17271 final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
17272 if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
17273 && callingAppId != Process.ROOT_UID) {
17274 versionsCallerCanSee = new SparseIntArray();
17275 String libName = versionedLib.valueAt(0).info.getName();
17276 String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
17277 if (uidPackages != null) {
17278 for (String uidPackage : uidPackages) {
17279 PackageSetting ps = mSettings.getPackageLPr(uidPackage);
17280 final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
17282 final int libVersion = ps.usesStaticLibrariesVersions[libIdx];
17283 versionsCallerCanSee.append(libVersion, libVersion);
17289 // Caller can see nothing - done
17290 if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
17291 return packageName;
17294 // Find the version the caller can see and the app version code
17295 SharedLibraryEntry highestVersion = null;
17296 final int versionCount = versionedLib.size();
17297 for (int i = 0; i < versionCount; i++) {
17298 SharedLibraryEntry libEntry = versionedLib.valueAt(i);
17299 if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
17300 libEntry.info.getVersion()) < 0) {
17303 // TODO: We will change version code to long, so in the new API it is long
17304 final int libVersionCode = (int) libEntry.info.getDeclaringPackage().getVersionCode();
17305 if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
17306 if (libVersionCode == versionCode) {
17307 return libEntry.apk;
17309 } else if (highestVersion == null) {
17310 highestVersion = libEntry;
17311 } else if (libVersionCode > highestVersion.info
17312 .getDeclaringPackage().getVersionCode()) {
17313 highestVersion = libEntry;
17317 if (highestVersion != null) {
17318 return highestVersion.apk;
17321 return packageName;
17324 private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
17325 if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
17326 || callingUid == Process.SYSTEM_UID) {
17329 final int callingUserId = UserHandle.getUserId(callingUid);
17330 // If the caller installed the pkgName, then allow it to silently uninstall.
17331 if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
17335 // Allow package verifier to silently uninstall.
17336 if (mRequiredVerifierPackage != null &&
17337 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
17341 // Allow package uninstaller to silently uninstall.
17342 if (mRequiredUninstallerPackage != null &&
17343 callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
17347 // Allow storage manager to silently uninstall.
17348 if (mStorageManagerPackage != null &&
17349 callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
17355 private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
17356 int[] result = EMPTY_INT_ARRAY;
17357 for (int userId : userIds) {
17358 if (getBlockUninstallForUser(packageName, userId)) {
17359 result = ArrayUtils.appendInt(result, userId);
17366 public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
17367 return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
17370 private boolean isPackageDeviceAdmin(String packageName, int userId) {
17371 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
17372 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
17375 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
17376 /* callingUserOnly =*/ false);
17377 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
17378 : deviceOwnerComponentName.getPackageName();
17379 // Does the package contains the device owner?
17380 // TODO Do we have to do it even if userId != UserHandle.USER_ALL? Otherwise,
17381 // this check is probably not needed, since DO should be registered as a device
17382 // admin on some user too. (Original bug for this: b/17657954)
17383 if (packageName.equals(deviceOwnerPackageName)) {
17386 // Does it contain a device admin for any user?
17388 if (userId == UserHandle.USER_ALL) {
17389 users = sUserManager.getUserIds();
17391 users = new int[]{userId};
17393 for (int i = 0; i < users.length; ++i) {
17394 if (dpm.packageHasActiveAdmins(packageName, users[i])) {
17399 } catch (RemoteException e) {
17404 private boolean shouldKeepUninstalledPackageLPr(String packageName) {
17405 return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
17409 * This method is an internal method that could be get invoked either
17410 * to delete an installed package or to clean up a failed installation.
17411 * After deleting an installed package, a broadcast is sent to notify any
17412 * listeners that the package has been removed. For cleaning up a failed
17413 * installation, the broadcast is not necessary since the package's
17414 * installation wouldn't have sent the initial broadcast either
17415 * The key steps in deleting a package are
17416 * deleting the package information in internal structures like mPackages,
17417 * deleting the packages base directories through installd
17418 * updating mSettings to reflect current status
17419 * persisting settings for later use
17420 * sending a broadcast if necessary
17422 private int deletePackageX(String packageName, int versionCode, int userId, int deleteFlags) {
17423 final PackageRemovedInfo info = new PackageRemovedInfo();
17426 final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
17427 ? UserHandle.USER_ALL : userId;
17429 if (isPackageDeviceAdmin(packageName, removeUser)) {
17430 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
17431 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
17434 PackageSetting uninstalledPs = null;
17435 PackageParser.Package pkg = null;
17437 // for the uninstall-updates case and restricted profiles, remember the per-
17438 // user handle installed state
17440 synchronized (mPackages) {
17441 uninstalledPs = mSettings.mPackages.get(packageName);
17442 if (uninstalledPs == null) {
17443 Slog.w(TAG, "Not removing non-existent package " + packageName);
17444 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17447 if (versionCode != PackageManager.VERSION_CODE_HIGHEST
17448 && uninstalledPs.versionCode != versionCode) {
17449 Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
17450 + uninstalledPs.versionCode + " != " + versionCode);
17451 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17454 // Static shared libs can be declared by any package, so let us not
17455 // allow removing a package if it provides a lib others depend on.
17456 pkg = mPackages.get(packageName);
17457 if (pkg != null && pkg.staticSharedLibName != null) {
17458 SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName,
17459 pkg.staticSharedLibVersion);
17460 if (libEntry != null) {
17461 List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
17462 libEntry.info, 0, userId);
17463 if (!ArrayUtils.isEmpty(libClientPackages)) {
17464 Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
17465 + " hosting lib " + libEntry.info.getName() + " version "
17466 + libEntry.info.getVersion() + " used by " + libClientPackages);
17467 return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
17472 allUsers = sUserManager.getUserIds();
17473 info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
17476 final int freezeUser;
17477 if (isUpdatedSystemApp(uninstalledPs)
17478 && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
17479 // We're downgrading a system app, which will apply to all users, so
17480 // freeze them all during the downgrade
17481 freezeUser = UserHandle.USER_ALL;
17483 freezeUser = removeUser;
17486 synchronized (mInstallLock) {
17487 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
17488 try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
17489 deleteFlags, "deletePackageX")) {
17490 res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
17491 deleteFlags | FLAGS_REMOVE_CHATTY, info, true, null);
17493 synchronized (mPackages) {
17496 mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
17498 updateSequenceNumberLP(packageName, info.removedUsers);
17499 updateInstantAppInstallerLocked();
17505 final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
17506 info.sendPackageRemovedBroadcasts(killApp);
17507 info.sendSystemPackageUpdatedBroadcasts();
17508 info.sendSystemPackageAppearedBroadcasts();
17510 // Force a gc here.
17511 Runtime.getRuntime().gc();
17512 // Delete the resources here after sending the broadcast to let
17513 // other processes clean up before deleting resources.
17514 if (info.args != null) {
17515 synchronized (mInstallLock) {
17516 info.args.doPostDeleteLI(true);
17520 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17523 class PackageRemovedInfo {
17524 String removedPackage;
17526 int removedAppId = -1;
17528 int[] removedUsers = null;
17529 SparseArray<Integer> installReasons;
17530 boolean isRemovedPackageSystemUpdate = false;
17532 boolean dataRemoved;
17533 boolean removedForAllUsers;
17534 boolean isStaticSharedLib;
17535 // Clean up resources deleted packages.
17536 InstallArgs args = null;
17537 ArrayMap<String, PackageRemovedInfo> removedChildPackages;
17538 ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
17540 void sendPackageRemovedBroadcasts(boolean killApp) {
17541 sendPackageRemovedBroadcastInternal(killApp);
17542 final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
17543 for (int i = 0; i < childCount; i++) {
17544 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
17545 childInfo.sendPackageRemovedBroadcastInternal(killApp);
17549 void sendSystemPackageUpdatedBroadcasts() {
17550 if (isRemovedPackageSystemUpdate) {
17551 sendSystemPackageUpdatedBroadcastsInternal();
17552 final int childCount = (removedChildPackages != null)
17553 ? removedChildPackages.size() : 0;
17554 for (int i = 0; i < childCount; i++) {
17555 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
17556 if (childInfo.isRemovedPackageSystemUpdate) {
17557 childInfo.sendSystemPackageUpdatedBroadcastsInternal();
17563 void sendSystemPackageAppearedBroadcasts() {
17564 final int packageCount = (appearedChildPackages != null)
17565 ? appearedChildPackages.size() : 0;
17566 for (int i = 0; i < packageCount; i++) {
17567 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
17568 sendPackageAddedForNewUsers(installedInfo.name, true,
17569 UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers);
17573 private void sendSystemPackageUpdatedBroadcastsInternal() {
17574 Bundle extras = new Bundle(2);
17575 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
17576 extras.putBoolean(Intent.EXTRA_REPLACING, true);
17577 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage,
17578 extras, 0, null, null, null);
17579 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage,
17580 extras, 0, null, null, null);
17581 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
17582 null, 0, removedPackage, null, null);
17585 private void sendPackageRemovedBroadcastInternal(boolean killApp) {
17586 // Don't send static shared library removal broadcasts as these
17587 // libs are visible only the the apps that depend on them an one
17588 // cannot remove the library if it has a dependency.
17589 if (isStaticSharedLib) {
17592 Bundle extras = new Bundle(2);
17593 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
17594 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
17595 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
17596 if (isUpdate || isRemovedPackageSystemUpdate) {
17597 extras.putBoolean(Intent.EXTRA_REPLACING, true);
17599 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
17600 if (removedPackage != null) {
17601 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
17602 extras, 0, null, null, removedUsers);
17603 if (dataRemoved && !isRemovedPackageSystemUpdate) {
17604 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
17605 removedPackage, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
17606 null, null, removedUsers);
17609 if (removedAppId >= 0) {
17610 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, 0, null, null,
17617 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
17618 * flag is not set, the data directory is removed as well.
17619 * make sure this flag is set for partially installed apps. If not its meaningless to
17620 * delete a partially installed application.
17622 private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
17623 PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
17624 String packageName = ps.name;
17625 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
17626 // Retrieve object to delete permissions for shared user later on
17627 final PackageParser.Package deletedPkg;
17628 final PackageSetting deletedPs;
17630 synchronized (mPackages) {
17631 deletedPkg = mPackages.get(packageName);
17632 deletedPs = mSettings.mPackages.get(packageName);
17633 if (outInfo != null) {
17634 outInfo.removedPackage = packageName;
17635 outInfo.isStaticSharedLib = deletedPkg != null
17636 && deletedPkg.staticSharedLibName != null;
17637 outInfo.removedUsers = deletedPs != null
17638 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
17643 removePackageLI(ps, (flags & FLAGS_REMOVE_CHATTY) != 0);
17645 if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
17646 final PackageParser.Package resolvedPkg;
17647 if (deletedPkg != null) {
17648 resolvedPkg = deletedPkg;
17650 // We don't have a parsed package when it lives on an ejected
17651 // adopted storage device, so fake something together
17652 resolvedPkg = new PackageParser.Package(ps.name);
17653 resolvedPkg.setVolumeUuid(ps.volumeUuid);
17655 destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
17656 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
17657 destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
17658 if (outInfo != null) {
17659 outInfo.dataRemoved = true;
17661 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
17664 int removedAppId = -1;
17667 synchronized (mPackages) {
17668 boolean installedStateChanged = false;
17669 if (deletedPs != null) {
17670 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
17671 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
17672 clearDefaultBrowserIfNeeded(packageName);
17673 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
17674 removedAppId = mSettings.removePackageLPw(packageName);
17675 if (outInfo != null) {
17676 outInfo.removedAppId = removedAppId;
17678 updatePermissionsLPw(deletedPs.name, null, 0);
17679 if (deletedPs.sharedUser != null) {
17680 // Remove permissions associated with package. Since runtime
17681 // permissions are per user we have to kill the removed package
17682 // or packages running under the shared user of the removed
17683 // package if revoking the permissions requested only by the removed
17684 // package is successful and this causes a change in gids.
17685 for (int userId : UserManagerService.getInstance().getUserIds()) {
17686 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
17688 if (userIdToKill == UserHandle.USER_ALL
17689 || userIdToKill >= UserHandle.USER_SYSTEM) {
17690 // If gids changed for this user, kill all affected packages.
17691 mHandler.post(new Runnable() {
17693 public void run() {
17694 // This has to happen with no lock held.
17695 killApplication(deletedPs.name, deletedPs.appId,
17696 KILL_APP_REASON_GIDS_CHANGED);
17703 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
17705 // make sure to preserve per-user disabled state if this removal was just
17706 // a downgrade of a system app to the factory package
17707 if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
17708 if (DEBUG_REMOVE) {
17709 Slog.d(TAG, "Propagating install state across downgrade");
17711 for (int userId : allUserHandles) {
17712 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
17713 if (DEBUG_REMOVE) {
17714 Slog.d(TAG, " user " + userId + " => " + installed);
17716 if (installed != ps.getInstalled(userId)) {
17717 installedStateChanged = true;
17719 ps.setInstalled(installed, userId);
17723 // can downgrade to reader
17724 if (writeSettings) {
17725 // Save settings now
17726 mSettings.writeLPr();
17728 if (installedStateChanged) {
17729 mSettings.writeKernelMappingLPr(ps);
17732 if (removedAppId != -1) {
17733 // A user ID was deleted here. Go through all users and remove it
17735 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId);
17739 static boolean locationIsPrivileged(File path) {
17741 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
17742 .getCanonicalPath();
17743 return path.getCanonicalPath().startsWith(privilegedAppDir);
17744 } catch (IOException e) {
17745 Slog.e(TAG, "Unable to access code path " + path);
17751 * Tries to delete system package.
17753 private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
17754 PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
17755 boolean writeSettings) {
17756 if (deletedPs.parentPackageName != null) {
17757 Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
17761 final boolean applyUserRestrictions
17762 = (allUserHandles != null) && (outInfo.origUsers != null);
17763 final PackageSetting disabledPs;
17764 // Confirm if the system package has been updated
17765 // An updated system app can be deleted. This will also have to restore
17766 // the system pkg from system partition
17768 synchronized (mPackages) {
17769 disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
17772 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
17773 + " disabledPs=" + disabledPs);
17775 if (disabledPs == null) {
17776 Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
17778 } else if (DEBUG_REMOVE) {
17779 Slog.d(TAG, "Deleting system pkg from data partition");
17782 if (DEBUG_REMOVE) {
17783 if (applyUserRestrictions) {
17784 Slog.d(TAG, "Remembering install states:");
17785 for (int userId : allUserHandles) {
17786 final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
17787 Slog.d(TAG, " u=" + userId + " inst=" + finstalled);
17792 // Delete the updated package
17793 outInfo.isRemovedPackageSystemUpdate = true;
17794 if (outInfo.removedChildPackages != null) {
17795 final int childCount = (deletedPs.childPackageNames != null)
17796 ? deletedPs.childPackageNames.size() : 0;
17797 for (int i = 0; i < childCount; i++) {
17798 String childPackageName = deletedPs.childPackageNames.get(i);
17799 if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
17800 .contains(childPackageName)) {
17801 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
17803 if (childInfo != null) {
17804 childInfo.isRemovedPackageSystemUpdate = true;
17810 if (disabledPs.versionCode < deletedPs.versionCode) {
17811 // Delete data for downgrades
17812 flags &= ~PackageManager.DELETE_KEEP_DATA;
17814 // Preserve data by setting flag
17815 flags |= PackageManager.DELETE_KEEP_DATA;
17818 boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
17819 outInfo, writeSettings, disabledPs.pkg);
17825 synchronized (mPackages) {
17826 // Reinstate the old system package
17827 enableSystemPackageLPw(disabledPs.pkg);
17828 // Remove any native libraries from the upgraded package.
17829 removeNativeBinariesLI(deletedPs);
17832 // Install the system package
17833 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
17834 int parseFlags = mDefParseFlags
17835 | PackageParser.PARSE_MUST_BE_APK
17836 | PackageParser.PARSE_IS_SYSTEM
17837 | PackageParser.PARSE_IS_SYSTEM_DIR;
17838 if (locationIsPrivileged(disabledPs.codePath)) {
17839 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
17842 final PackageParser.Package newPkg;
17844 newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, 0 /* scanFlags */,
17845 0 /* currentTime */, null);
17846 } catch (PackageManagerException e) {
17847 Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
17853 // update shared libraries for the newly re-installed system package
17854 updateSharedLibrariesLPr(newPkg, null);
17855 } catch (PackageManagerException e) {
17856 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
17859 prepareAppDataAfterInstallLIF(newPkg);
17862 synchronized (mPackages) {
17863 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
17865 // Propagate the permissions state as we do not want to drop on the floor
17866 // runtime permissions. The update permissions method below will take
17867 // care of removing obsolete permissions and grant install permissions.
17868 ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState());
17869 updatePermissionsLPw(newPkg.packageName, newPkg,
17870 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
17872 if (applyUserRestrictions) {
17873 boolean installedStateChanged = false;
17874 if (DEBUG_REMOVE) {
17875 Slog.d(TAG, "Propagating install state across reinstall");
17877 for (int userId : allUserHandles) {
17878 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
17879 if (DEBUG_REMOVE) {
17880 Slog.d(TAG, " user " + userId + " => " + installed);
17882 if (installed != ps.getInstalled(userId)) {
17883 installedStateChanged = true;
17885 ps.setInstalled(installed, userId);
17887 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
17889 // Regardless of writeSettings we need to ensure that this restriction
17890 // state propagation is persisted
17891 mSettings.writeAllUsersPackageRestrictionsLPr();
17892 if (installedStateChanged) {
17893 mSettings.writeKernelMappingLPr(ps);
17896 // can downgrade to reader here
17897 if (writeSettings) {
17898 mSettings.writeLPr();
17904 private boolean deleteInstalledPackageLIF(PackageSetting ps,
17905 boolean deleteCodeAndResources, int flags, int[] allUserHandles,
17906 PackageRemovedInfo outInfo, boolean writeSettings,
17907 PackageParser.Package replacingPackage) {
17908 synchronized (mPackages) {
17909 if (outInfo != null) {
17910 outInfo.uid = ps.appId;
17913 if (outInfo != null && outInfo.removedChildPackages != null) {
17914 final int childCount = (ps.childPackageNames != null)
17915 ? ps.childPackageNames.size() : 0;
17916 for (int i = 0; i < childCount; i++) {
17917 String childPackageName = ps.childPackageNames.get(i);
17918 PackageSetting childPs = mSettings.mPackages.get(childPackageName);
17919 if (childPs == null) {
17922 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
17924 if (childInfo != null) {
17925 childInfo.uid = childPs.appId;
17931 // Delete package data from internal structures and also remove data if flag is set
17932 removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
17934 // Delete the child packages data
17935 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
17936 for (int i = 0; i < childCount; i++) {
17937 PackageSetting childPs;
17938 synchronized (mPackages) {
17939 childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
17941 if (childPs != null) {
17942 PackageRemovedInfo childOutInfo = (outInfo != null
17943 && outInfo.removedChildPackages != null)
17944 ? outInfo.removedChildPackages.get(childPs.name) : null;
17945 final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
17946 && (replacingPackage != null
17947 && !replacingPackage.hasChildPackage(childPs.name))
17948 ? flags & ~DELETE_KEEP_DATA : flags;
17949 removePackageDataLIF(childPs, allUserHandles, childOutInfo,
17950 deleteFlags, writeSettings);
17954 // Delete application code and resources only for parent packages
17955 if (ps.parentPackageName == null) {
17956 if (deleteCodeAndResources && (outInfo != null)) {
17957 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
17958 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
17959 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
17967 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
17969 mContext.enforceCallingOrSelfPermission(
17970 android.Manifest.permission.DELETE_PACKAGES, null);
17971 synchronized (mPackages) {
17972 PackageSetting ps = mSettings.mPackages.get(packageName);
17974 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName);
17977 // Cannot block uninstall of static shared libs as they are
17978 // considered a part of the using app (emulating static linking).
17979 // Also static libs are installed always on internal storage.
17980 PackageParser.Package pkg = mPackages.get(packageName);
17981 if (pkg != null && pkg.staticSharedLibName != null) {
17982 Slog.w(TAG, "Cannot block uninstall of package: " + packageName
17983 + " providing static shared library: " + pkg.staticSharedLibName);
17986 if (!ps.getInstalled(userId)) {
17987 // Can't block uninstall for an app that is not installed or enabled.
17988 Log.i(TAG, "Package not installed in set block uninstall " + packageName);
17991 ps.setBlockUninstall(blockUninstall, userId);
17992 mSettings.writePackageRestrictionsLPr(userId);
17998 public boolean getBlockUninstallForUser(String packageName, int userId) {
17999 synchronized (mPackages) {
18000 PackageSetting ps = mSettings.mPackages.get(packageName);
18002 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName);
18005 return ps.getBlockUninstall(userId);
18010 public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
18011 int callingUid = Binder.getCallingUid();
18012 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
18013 throw new SecurityException(
18014 "setRequiredForSystemUser can only be run by the system or root");
18016 synchronized (mPackages) {
18017 PackageSetting ps = mSettings.mPackages.get(packageName);
18019 Log.w(TAG, "Package doesn't exist: " + packageName);
18022 if (systemUserApp) {
18023 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18025 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18027 mSettings.writeLPr();
18033 * This method handles package deletion in general
18035 private boolean deletePackageLIF(String packageName, UserHandle user,
18036 boolean deleteCodeAndResources, int[] allUserHandles, int flags,
18037 PackageRemovedInfo outInfo, boolean writeSettings,
18038 PackageParser.Package replacingPackage) {
18039 if (packageName == null) {
18040 Slog.w(TAG, "Attempt to delete null packageName.");
18044 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
18047 synchronized (mPackages) {
18048 ps = mSettings.mPackages.get(packageName);
18050 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18054 if (ps.parentPackageName != null && (!isSystemApp(ps)
18055 || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
18056 if (DEBUG_REMOVE) {
18057 Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
18058 + ((user == null) ? UserHandle.USER_ALL : user));
18060 final int removedUserId = (user != null) ? user.getIdentifier()
18061 : UserHandle.USER_ALL;
18062 if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
18065 markPackageUninstalledForUserLPw(ps, user);
18066 scheduleWritePackageRestrictionsLocked(user);
18071 if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
18072 && user.getIdentifier() != UserHandle.USER_ALL)) {
18073 // The caller is asking that the package only be deleted for a single
18074 // user. To do this, we just mark its uninstalled state and delete
18075 // its data. If this is a system app, we only allow this to happen if
18076 // they have set the special DELETE_SYSTEM_APP which requests different
18077 // semantics than normal for uninstalling system apps.
18078 markPackageUninstalledForUserLPw(ps, user);
18080 if (!isSystemApp(ps)) {
18081 // Do not uninstall the APK if an app should be cached
18082 boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
18083 if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
18084 // Other user still have this package installed, so all
18085 // we need to do is clear this user's data and save that
18086 // it is uninstalled.
18087 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
18088 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18091 scheduleWritePackageRestrictionsLocked(user);
18094 // We need to set it back to 'installed' so the uninstall
18095 // broadcasts will be sent correctly.
18096 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
18097 ps.setInstalled(true, user.getIdentifier());
18098 mSettings.writeKernelMappingLPr(ps);
18101 // This is a system app, so we assume that the
18102 // other users still have this package installed, so all
18103 // we need to do is clear this user's data and save that
18104 // it is uninstalled.
18105 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
18106 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18109 scheduleWritePackageRestrictionsLocked(user);
18114 // If we are deleting a composite package for all users, keep track
18115 // of result for each child.
18116 if (ps.childPackageNames != null && outInfo != null) {
18117 synchronized (mPackages) {
18118 final int childCount = ps.childPackageNames.size();
18119 outInfo.removedChildPackages = new ArrayMap<>(childCount);
18120 for (int i = 0; i < childCount; i++) {
18121 String childPackageName = ps.childPackageNames.get(i);
18122 PackageRemovedInfo childInfo = new PackageRemovedInfo();
18123 childInfo.removedPackage = childPackageName;
18124 outInfo.removedChildPackages.put(childPackageName, childInfo);
18125 PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18126 if (childPs != null) {
18127 childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
18133 boolean ret = false;
18134 if (isSystemApp(ps)) {
18135 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
18136 // When an updated system application is deleted we delete the existing resources
18137 // as well and fall back to existing code in system partition
18138 ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
18140 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
18141 ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
18142 outInfo, writeSettings, replacingPackage);
18145 // Take a note whether we deleted the package for all users
18146 if (outInfo != null) {
18147 outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
18148 if (outInfo.removedChildPackages != null) {
18149 synchronized (mPackages) {
18150 final int childCount = outInfo.removedChildPackages.size();
18151 for (int i = 0; i < childCount; i++) {
18152 PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
18153 if (childInfo != null) {
18154 childInfo.removedForAllUsers = mPackages.get(
18155 childInfo.removedPackage) == null;
18160 // If we uninstalled an update to a system app there may be some
18161 // child packages that appeared as they are declared in the system
18162 // app but were not declared in the update.
18163 if (isSystemApp(ps)) {
18164 synchronized (mPackages) {
18165 PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
18166 final int childCount = (updatedPs.childPackageNames != null)
18167 ? updatedPs.childPackageNames.size() : 0;
18168 for (int i = 0; i < childCount; i++) {
18169 String childPackageName = updatedPs.childPackageNames.get(i);
18170 if (outInfo.removedChildPackages == null
18171 || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
18172 PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18173 if (childPs == null) {
18176 PackageInstalledInfo installRes = new PackageInstalledInfo();
18177 installRes.name = childPackageName;
18178 installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
18179 installRes.pkg = mPackages.get(childPackageName);
18180 installRes.uid = childPs.pkg.applicationInfo.uid;
18181 if (outInfo.appearedChildPackages == null) {
18182 outInfo.appearedChildPackages = new ArrayMap<>();
18184 outInfo.appearedChildPackages.put(childPackageName, installRes);
18194 private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
18195 final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
18196 ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
18197 for (int nextUserId : userIds) {
18198 if (DEBUG_REMOVE) {
18199 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
18201 ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
18202 false /*installed*/,
18204 true /*notLaunched*/,
18206 false /*suspended*/,
18207 false /*instantApp*/,
18208 null /*lastDisableAppCaller*/,
18209 null /*enabledComponents*/,
18210 null /*disabledComponents*/,
18211 false /*blockUninstall*/,
18212 ps.readUserState(nextUserId).domainVerificationStatus,
18213 0, PackageManager.INSTALL_REASON_UNKNOWN);
18215 mSettings.writeKernelMappingLPr(ps);
18218 private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
18219 PackageRemovedInfo outInfo) {
18220 final PackageParser.Package pkg;
18221 synchronized (mPackages) {
18222 pkg = mPackages.get(ps.name);
18225 final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
18226 : new int[] {userId};
18227 for (int nextUserId : userIds) {
18228 if (DEBUG_REMOVE) {
18229 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
18233 destroyAppDataLIF(pkg, userId,
18234 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18235 destroyAppProfilesLIF(pkg, userId);
18236 removeKeystoreDataIfNeeded(nextUserId, ps.appId);
18237 schedulePackageCleaning(ps.name, nextUserId, false);
18238 synchronized (mPackages) {
18239 if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
18240 scheduleWritePackageRestrictionsLocked(nextUserId);
18242 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
18246 if (outInfo != null) {
18247 outInfo.removedPackage = ps.name;
18248 outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
18249 outInfo.removedAppId = ps.appId;
18250 outInfo.removedUsers = userIds;
18256 private final class ClearStorageConnection implements ServiceConnection {
18257 IMediaContainerService mContainerService;
18260 public void onServiceConnected(ComponentName name, IBinder service) {
18261 synchronized (this) {
18262 mContainerService = IMediaContainerService.Stub
18263 .asInterface(Binder.allowBlocking(service));
18269 public void onServiceDisconnected(ComponentName name) {
18273 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
18274 if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
18276 final boolean mounted;
18277 if (Environment.isExternalStorageEmulated()) {
18280 final String status = Environment.getExternalStorageState();
18282 mounted = status.equals(Environment.MEDIA_MOUNTED)
18283 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
18290 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
18292 if (userId == UserHandle.USER_ALL) {
18293 users = sUserManager.getUserIds();
18295 users = new int[] { userId };
18297 final ClearStorageConnection conn = new ClearStorageConnection();
18298 if (mContext.bindServiceAsUser(
18299 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
18301 for (int curUser : users) {
18302 long timeout = SystemClock.uptimeMillis() + 5000;
18303 synchronized (conn) {
18305 while (conn.mContainerService == null &&
18306 (now = SystemClock.uptimeMillis()) < timeout) {
18308 conn.wait(timeout - now);
18309 } catch (InterruptedException e) {
18313 if (conn.mContainerService == null) {
18317 final UserEnvironment userEnv = new UserEnvironment(curUser);
18318 clearDirectory(conn.mContainerService,
18319 userEnv.buildExternalStorageAppCacheDirs(packageName));
18321 clearDirectory(conn.mContainerService,
18322 userEnv.buildExternalStorageAppDataDirs(packageName));
18323 clearDirectory(conn.mContainerService,
18324 userEnv.buildExternalStorageAppMediaDirs(packageName));
18328 mContext.unbindService(conn);
18334 public void clearApplicationProfileData(String packageName) {
18335 enforceSystemOrRoot("Only the system can clear all profile data");
18337 final PackageParser.Package pkg;
18338 synchronized (mPackages) {
18339 pkg = mPackages.get(packageName);
18342 try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
18343 synchronized (mInstallLock) {
18344 clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
18350 public void clearApplicationUserData(final String packageName,
18351 final IPackageDataObserver observer, final int userId) {
18352 mContext.enforceCallingOrSelfPermission(
18353 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
18355 enforceCrossUserPermission(Binder.getCallingUid(), userId,
18356 true /* requireFullPermission */, false /* checkShell */, "clear application data");
18358 if (mProtectedPackages.isPackageDataProtected(userId, packageName)) {
18359 throw new SecurityException("Cannot clear data for a protected package: "
18362 // Queue up an async operation since the package deletion may take a little while.
18363 mHandler.post(new Runnable() {
18364 public void run() {
18365 mHandler.removeCallbacks(this);
18366 final boolean succeeded;
18367 try (PackageFreezer freezer = freezePackage(packageName,
18368 "clearApplicationUserData")) {
18369 synchronized (mInstallLock) {
18370 succeeded = clearApplicationUserDataLIF(packageName, userId);
18372 clearExternalStorageDataSync(packageName, userId, true);
18373 synchronized (mPackages) {
18374 mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
18375 packageName, userId);
18379 // invoke DeviceStorageMonitor's update method to clear any notifications
18380 DeviceStorageMonitorInternal dsm = LocalServices
18381 .getService(DeviceStorageMonitorInternal.class);
18386 if(observer != null) {
18388 observer.onRemoveCompleted(packageName, succeeded);
18389 } catch (RemoteException e) {
18390 Log.i(TAG, "Observer no longer exists.");
18392 } //end if observer
18397 private boolean clearApplicationUserDataLIF(String packageName, int userId) {
18398 if (packageName == null) {
18399 Slog.w(TAG, "Attempt to delete null packageName.");
18403 // Try finding details about the requested package
18404 PackageParser.Package pkg;
18405 synchronized (mPackages) {
18406 pkg = mPackages.get(packageName);
18408 final PackageSetting ps = mSettings.mPackages.get(packageName);
18415 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18419 PackageSetting ps = (PackageSetting) pkg.mExtras;
18420 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
18423 clearAppDataLIF(pkg, userId,
18424 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18426 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
18427 removeKeystoreDataIfNeeded(userId, appId);
18429 UserManagerInternal umInternal = getUserManagerInternal();
18431 if (umInternal.isUserUnlockingOrUnlocked(userId)) {
18432 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
18433 } else if (umInternal.isUserRunning(userId)) {
18434 flags = StorageManager.FLAG_STORAGE_DE;
18438 prepareAppDataContentsLIF(pkg, userId, flags);
18444 * Reverts user permission state changes (permissions and flags) in
18445 * all packages for a given user.
18447 * @param userId The device user for which to do a reset.
18449 private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
18450 final int packageCount = mPackages.size();
18451 for (int i = 0; i < packageCount; i++) {
18452 PackageParser.Package pkg = mPackages.valueAt(i);
18453 PackageSetting ps = (PackageSetting) pkg.mExtras;
18454 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
18458 private void resetNetworkPolicies(int userId) {
18459 LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
18463 * Reverts user permission state changes (permissions and flags).
18465 * @param ps The package for which to reset.
18466 * @param userId The device user for which to do a reset.
18468 private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
18469 final PackageSetting ps, final int userId) {
18470 if (ps.pkg == null) {
18474 // These are flags that can change base on user actions.
18475 final int userSettableMask = FLAG_PERMISSION_USER_SET
18476 | FLAG_PERMISSION_USER_FIXED
18477 | FLAG_PERMISSION_REVOKE_ON_UPGRADE
18478 | FLAG_PERMISSION_REVIEW_REQUIRED;
18480 final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
18481 | FLAG_PERMISSION_POLICY_FIXED;
18483 boolean writeInstallPermissions = false;
18484 boolean writeRuntimePermissions = false;
18486 final int permissionCount = ps.pkg.requestedPermissions.size();
18487 for (int i = 0; i < permissionCount; i++) {
18488 String permission = ps.pkg.requestedPermissions.get(i);
18490 BasePermission bp = mSettings.mPermissions.get(permission);
18495 // If shared user we just reset the state to which only this app contributed.
18496 if (ps.sharedUser != null) {
18497 boolean used = false;
18498 final int packageCount = ps.sharedUser.packages.size();
18499 for (int j = 0; j < packageCount; j++) {
18500 PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
18501 if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
18502 && pkg.pkg.requestedPermissions.contains(permission)) {
18512 PermissionsState permissionsState = ps.getPermissionsState();
18514 final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
18516 // Always clear the user settable flags.
18517 final boolean hasInstallState = permissionsState.getInstallPermissionState(
18519 // If permission review is enabled and this is a legacy app, mark the
18520 // permission as requiring a review as this is the initial state.
18522 if (mPermissionReviewRequired
18523 && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
18524 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
18526 if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
18527 if (hasInstallState) {
18528 writeInstallPermissions = true;
18530 writeRuntimePermissions = true;
18534 // Below is only runtime permission handling.
18535 if (!bp.isRuntime()) {
18539 // Never clobber system or policy.
18540 if ((oldFlags & policyOrSystemFlags) != 0) {
18544 // If this permission was granted by default, make sure it is.
18545 if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
18546 if (permissionsState.grantRuntimePermission(bp, userId)
18547 != PERMISSION_OPERATION_FAILURE) {
18548 writeRuntimePermissions = true;
18550 // If permission review is enabled the permissions for a legacy apps
18551 // are represented as constantly granted runtime ones, so don't revoke.
18552 } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
18553 // Otherwise, reset the permission.
18554 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
18555 switch (revokeResult) {
18556 case PERMISSION_OPERATION_SUCCESS:
18557 case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
18558 writeRuntimePermissions = true;
18559 final int appId = ps.appId;
18560 mHandler.post(new Runnable() {
18562 public void run() {
18563 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
18571 // Synchronously write as we are taking permissions away.
18572 if (writeRuntimePermissions) {
18573 mSettings.writeRuntimePermissionsForUserLPr(userId, true);
18576 // Synchronously write as we are taking permissions away.
18577 if (writeInstallPermissions) {
18578 mSettings.writeLPr();
18583 * Remove entries from the keystore daemon. Will only remove it if the
18584 * {@code appId} is valid.
18586 private static void removeKeystoreDataIfNeeded(int userId, int appId) {
18591 final KeyStore keyStore = KeyStore.getInstance();
18592 if (keyStore != null) {
18593 if (userId == UserHandle.USER_ALL) {
18594 for (final int individual : sUserManager.getUserIds()) {
18595 keyStore.clearUid(UserHandle.getUid(individual, appId));
18598 keyStore.clearUid(UserHandle.getUid(userId, appId));
18601 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
18606 public void deleteApplicationCacheFiles(final String packageName,
18607 final IPackageDataObserver observer) {
18608 final int userId = UserHandle.getCallingUserId();
18609 deleteApplicationCacheFilesAsUser(packageName, userId, observer);
18613 public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
18614 final IPackageDataObserver observer) {
18615 mContext.enforceCallingOrSelfPermission(
18616 android.Manifest.permission.DELETE_CACHE_FILES, null);
18617 enforceCrossUserPermission(Binder.getCallingUid(), userId,
18618 /* requireFullPermission= */ true, /* checkShell= */ false,
18619 "delete application cache files");
18621 final PackageParser.Package pkg;
18622 synchronized (mPackages) {
18623 pkg = mPackages.get(packageName);
18626 // Queue up an async operation since the package deletion may take a little while.
18627 mHandler.post(new Runnable() {
18628 public void run() {
18629 synchronized (mInstallLock) {
18630 final int flags = StorageManager.FLAG_STORAGE_DE
18631 | StorageManager.FLAG_STORAGE_CE;
18632 // We're only clearing cache files, so we don't care if the
18633 // app is unfrozen and still able to run
18634 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
18635 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
18637 clearExternalStorageDataSync(packageName, userId, false);
18638 if (observer != null) {
18640 observer.onRemoveCompleted(packageName, true);
18641 } catch (RemoteException e) {
18642 Log.i(TAG, "Observer no longer exists.");
18650 public void getPackageSizeInfo(final String packageName, int userHandle,
18651 final IPackageStatsObserver observer) {
18652 throw new UnsupportedOperationException(
18653 "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
18656 private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
18657 final PackageSetting ps;
18658 synchronized (mPackages) {
18659 ps = mSettings.mPackages.get(packageName);
18661 Slog.w(TAG, "Failed to find settings for " + packageName);
18666 final String[] packageNames = { packageName };
18667 final long[] ceDataInodes = { ps.getCeDataInode(userId) };
18668 final String[] codePaths = { ps.codePathString };
18671 mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
18672 ps.appId, ceDataInodes, codePaths, stats);
18674 // For now, ignore code size of packages on system partition
18675 if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
18676 stats.codeSize = 0;
18679 // External clients expect these to be tracked separately
18680 stats.dataSize -= stats.cacheSize;
18682 } catch (InstallerException e) {
18683 Slog.w(TAG, String.valueOf(e));
18690 private int getUidTargetSdkVersionLockedLPr(int uid) {
18691 Object obj = mSettings.getUserIdLPr(uid);
18692 if (obj instanceof SharedUserSetting) {
18693 final SharedUserSetting sus = (SharedUserSetting) obj;
18694 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
18695 final Iterator<PackageSetting> it = sus.packages.iterator();
18696 while (it.hasNext()) {
18697 final PackageSetting ps = it.next();
18698 if (ps.pkg != null) {
18699 int v = ps.pkg.applicationInfo.targetSdkVersion;
18700 if (v < vers) vers = v;
18704 } else if (obj instanceof PackageSetting) {
18705 final PackageSetting ps = (PackageSetting) obj;
18706 if (ps.pkg != null) {
18707 return ps.pkg.applicationInfo.targetSdkVersion;
18710 return Build.VERSION_CODES.CUR_DEVELOPMENT;
18714 public void addPreferredActivity(IntentFilter filter, int match,
18715 ComponentName[] set, ComponentName activity, int userId) {
18716 addPreferredActivityInternal(filter, match, set, activity, true, userId,
18717 "Adding preferred");
18720 private void addPreferredActivityInternal(IntentFilter filter, int match,
18721 ComponentName[] set, ComponentName activity, boolean always, int userId,
18724 int callingUid = Binder.getCallingUid();
18725 enforceCrossUserPermission(callingUid, userId,
18726 true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
18727 if (filter.countActions() == 0) {
18728 Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
18731 synchronized (mPackages) {
18732 if (mContext.checkCallingOrSelfPermission(
18733 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
18734 != PackageManager.PERMISSION_GRANTED) {
18735 if (getUidTargetSdkVersionLockedLPr(callingUid)
18736 < Build.VERSION_CODES.FROYO) {
18737 Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
18741 mContext.enforceCallingOrSelfPermission(
18742 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
18745 PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
18746 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
18748 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
18749 pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
18750 scheduleWritePackageRestrictionsLocked(userId);
18751 postPreferredActivityChangedBroadcast(userId);
18755 private void postPreferredActivityChangedBroadcast(int userId) {
18756 mHandler.post(() -> {
18757 final IActivityManager am = ActivityManager.getService();
18762 final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
18763 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18765 am.broadcastIntent(null, intent, null, null,
18766 0, null, null, null, android.app.AppOpsManager.OP_NONE,
18767 null, false, false, userId);
18768 } catch (RemoteException e) {
18774 public void replacePreferredActivity(IntentFilter filter, int match,
18775 ComponentName[] set, ComponentName activity, int userId) {
18776 if (filter.countActions() != 1) {
18777 throw new IllegalArgumentException(
18778 "replacePreferredActivity expects filter to have only 1 action.");
18780 if (filter.countDataAuthorities() != 0
18781 || filter.countDataPaths() != 0
18782 || filter.countDataSchemes() > 1
18783 || filter.countDataTypes() != 0) {
18784 throw new IllegalArgumentException(
18785 "replacePreferredActivity expects filter to have no data authorities, " +
18786 "paths, or types; and at most one scheme.");
18789 final int callingUid = Binder.getCallingUid();
18790 enforceCrossUserPermission(callingUid, userId,
18791 true /* requireFullPermission */, false /* checkShell */,
18792 "replace preferred activity");
18793 synchronized (mPackages) {
18794 if (mContext.checkCallingOrSelfPermission(
18795 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
18796 != PackageManager.PERMISSION_GRANTED) {
18797 if (getUidTargetSdkVersionLockedLPr(callingUid)
18798 < Build.VERSION_CODES.FROYO) {
18799 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
18800 + Binder.getCallingUid());
18803 mContext.enforceCallingOrSelfPermission(
18804 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
18807 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
18809 // Get all of the existing entries that exactly match this filter.
18810 ArrayList<PreferredActivity> existing = pir.findFilters(filter);
18811 if (existing != null && existing.size() == 1) {
18812 PreferredActivity cur = existing.get(0);
18813 if (DEBUG_PREFERRED) {
18814 Slog.i(TAG, "Checking replace of preferred:");
18815 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
18816 if (!cur.mPref.mAlways) {
18817 Slog.i(TAG, " -- CUR; not mAlways!");
18819 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch);
18820 Slog.i(TAG, " -- CUR: mSet="
18821 + Arrays.toString(cur.mPref.mSetComponents));
18822 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent);
18823 Slog.i(TAG, " -- NEW: mMatch="
18824 + (match&IntentFilter.MATCH_CATEGORY_MASK));
18825 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set));
18826 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString());
18829 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
18830 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
18831 && cur.mPref.sameSet(set)) {
18832 // Setting the preferred activity to what it happens to be already
18833 if (DEBUG_PREFERRED) {
18834 Slog.i(TAG, "Replacing with same preferred activity "
18835 + cur.mPref.mShortComponent + " for user "
18837 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
18843 if (existing != null) {
18844 if (DEBUG_PREFERRED) {
18845 Slog.i(TAG, existing.size() + " existing preferred matches for:");
18846 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
18848 for (int i = 0; i < existing.size(); i++) {
18849 PreferredActivity pa = existing.get(i);
18850 if (DEBUG_PREFERRED) {
18851 Slog.i(TAG, "Removing existing preferred activity "
18852 + pa.mPref.mComponent + ":");
18853 pa.dump(new LogPrinter(Log.INFO, TAG), " ");
18855 pir.removeFilter(pa);
18859 addPreferredActivityInternal(filter, match, set, activity, true, userId,
18860 "Replacing preferred");
18865 public void clearPackagePreferredActivities(String packageName) {
18866 final int uid = Binder.getCallingUid();
18868 synchronized (mPackages) {
18869 PackageParser.Package pkg = mPackages.get(packageName);
18870 if (pkg == null || pkg.applicationInfo.uid != uid) {
18871 if (mContext.checkCallingOrSelfPermission(
18872 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
18873 != PackageManager.PERMISSION_GRANTED) {
18874 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
18875 < Build.VERSION_CODES.FROYO) {
18876 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
18877 + Binder.getCallingUid());
18880 mContext.enforceCallingOrSelfPermission(
18881 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
18885 int user = UserHandle.getCallingUserId();
18886 if (clearPackagePreferredActivitiesLPw(packageName, user)) {
18887 scheduleWritePackageRestrictionsLocked(user);
18892 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
18893 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
18894 ArrayList<PreferredActivity> removed = null;
18895 boolean changed = false;
18896 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
18897 final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
18898 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
18899 if (userId != UserHandle.USER_ALL && userId != thisUserId) {
18902 Iterator<PreferredActivity> it = pir.filterIterator();
18903 while (it.hasNext()) {
18904 PreferredActivity pa = it.next();
18905 // Mark entry for removal only if it matches the package name
18906 // and the entry is of type "always".
18907 if (packageName == null ||
18908 (pa.mPref.mComponent.getPackageName().equals(packageName)
18909 && pa.mPref.mAlways)) {
18910 if (removed == null) {
18911 removed = new ArrayList<PreferredActivity>();
18916 if (removed != null) {
18917 for (int j=0; j<removed.size(); j++) {
18918 PreferredActivity pa = removed.get(j);
18919 pir.removeFilter(pa);
18925 postPreferredActivityChangedBroadcast(userId);
18930 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
18931 private void clearIntentFilterVerificationsLPw(int userId) {
18932 final int packageCount = mPackages.size();
18933 for (int i = 0; i < packageCount; i++) {
18934 PackageParser.Package pkg = mPackages.valueAt(i);
18935 clearIntentFilterVerificationsLPw(pkg.packageName, userId);
18939 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
18940 void clearIntentFilterVerificationsLPw(String packageName, int userId) {
18941 if (userId == UserHandle.USER_ALL) {
18942 if (mSettings.removeIntentFilterVerificationLPw(packageName,
18943 sUserManager.getUserIds())) {
18944 for (int oneUserId : sUserManager.getUserIds()) {
18945 scheduleWritePackageRestrictionsLocked(oneUserId);
18949 if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
18950 scheduleWritePackageRestrictionsLocked(userId);
18955 void clearDefaultBrowserIfNeeded(String packageName) {
18956 for (int oneUserId : sUserManager.getUserIds()) {
18957 String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId);
18958 if (TextUtils.isEmpty(defaultBrowserPackageName)) continue;
18959 if (packageName.equals(defaultBrowserPackageName)) {
18960 setDefaultBrowserPackageName(null, oneUserId);
18966 public void resetApplicationPreferences(int userId) {
18967 mContext.enforceCallingOrSelfPermission(
18968 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
18969 final long identity = Binder.clearCallingIdentity();
18972 synchronized (mPackages) {
18973 clearPackagePreferredActivitiesLPw(null, userId);
18974 mSettings.applyDefaultPreferredAppsLPw(this, userId);
18975 // TODO: We have to reset the default SMS and Phone. This requires
18976 // significant refactoring to keep all default apps in the package
18977 // manager (cleaner but more work) or have the services provide
18978 // callbacks to the package manager to request a default app reset.
18979 applyFactoryDefaultBrowserLPw(userId);
18980 clearIntentFilterVerificationsLPw(userId);
18981 primeDomainVerificationsLPw(userId);
18982 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
18983 scheduleWritePackageRestrictionsLocked(userId);
18985 resetNetworkPolicies(userId);
18987 Binder.restoreCallingIdentity(identity);
18992 public int getPreferredActivities(List<IntentFilter> outFilters,
18993 List<ComponentName> outActivities, String packageName) {
18996 final int userId = UserHandle.getCallingUserId();
18998 synchronized (mPackages) {
18999 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19001 final Iterator<PreferredActivity> it = pir.filterIterator();
19002 while (it.hasNext()) {
19003 final PreferredActivity pa = it.next();
19004 if (packageName == null
19005 || (pa.mPref.mComponent.getPackageName().equals(packageName)
19006 && pa.mPref.mAlways)) {
19007 if (outFilters != null) {
19008 outFilters.add(new IntentFilter(pa));
19010 if (outActivities != null) {
19011 outActivities.add(pa.mPref.mComponent);
19022 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
19024 int callingUid = Binder.getCallingUid();
19025 if (callingUid != Process.SYSTEM_UID) {
19026 throw new SecurityException(
19027 "addPersistentPreferredActivity can only be run by the system");
19029 if (filter.countActions() == 0) {
19030 Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19033 synchronized (mPackages) {
19034 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
19036 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
19037 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
19038 new PersistentPreferredActivity(filter, activity));
19039 scheduleWritePackageRestrictionsLocked(userId);
19040 postPreferredActivityChangedBroadcast(userId);
19045 public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
19046 int callingUid = Binder.getCallingUid();
19047 if (callingUid != Process.SYSTEM_UID) {
19048 throw new SecurityException(
19049 "clearPackagePersistentPreferredActivities can only be run by the system");
19051 ArrayList<PersistentPreferredActivity> removed = null;
19052 boolean changed = false;
19053 synchronized (mPackages) {
19054 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
19055 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
19056 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
19058 if (userId != thisUserId) {
19061 Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
19062 while (it.hasNext()) {
19063 PersistentPreferredActivity ppa = it.next();
19064 // Mark entry for removal only if it matches the package name.
19065 if (ppa.mComponent.getPackageName().equals(packageName)) {
19066 if (removed == null) {
19067 removed = new ArrayList<PersistentPreferredActivity>();
19072 if (removed != null) {
19073 for (int j=0; j<removed.size(); j++) {
19074 PersistentPreferredActivity ppa = removed.get(j);
19075 ppir.removeFilter(ppa);
19082 scheduleWritePackageRestrictionsLocked(userId);
19083 postPreferredActivityChangedBroadcast(userId);
19089 * Common machinery for picking apart a restored XML blob and passing
19090 * it to a caller-supplied functor to be applied to the running system.
19092 private void restoreFromXml(XmlPullParser parser, int userId,
19093 String expectedStartTag, BlobXmlRestorer functor)
19094 throws IOException, XmlPullParserException {
19096 while ((type = parser.next()) != XmlPullParser.START_TAG
19097 && type != XmlPullParser.END_DOCUMENT) {
19099 if (type != XmlPullParser.START_TAG) {
19100 // oops didn't find a start tag?!
19101 if (DEBUG_BACKUP) {
19102 Slog.e(TAG, "Didn't find start tag during restore");
19106 Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
19107 // this is supposed to be TAG_PREFERRED_BACKUP
19108 if (!expectedStartTag.equals(parser.getName())) {
19109 if (DEBUG_BACKUP) {
19110 Slog.e(TAG, "Found unexpected tag " + parser.getName());
19115 // skip interfering stuff, then we're aligned with the backing implementation
19116 while ((type = parser.next()) == XmlPullParser.TEXT) { }
19117 Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
19118 functor.apply(parser, userId);
19121 private interface BlobXmlRestorer {
19122 public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
19126 * Non-Binder method, support for the backup/restore mechanism: write the
19127 * full set of preferred activities in its canonical XML format. Returns the
19128 * XML output as a byte array, or null if there is none.
19131 public byte[] getPreferredActivityBackup(int userId) {
19132 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19133 throw new SecurityException("Only the system may call getPreferredActivityBackup()");
19136 ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19138 final XmlSerializer serializer = new FastXmlSerializer();
19139 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19140 serializer.startDocument(null, true);
19141 serializer.startTag(null, TAG_PREFERRED_BACKUP);
19143 synchronized (mPackages) {
19144 mSettings.writePreferredActivitiesLPr(serializer, userId, true);
19147 serializer.endTag(null, TAG_PREFERRED_BACKUP);
19148 serializer.endDocument();
19149 serializer.flush();
19150 } catch (Exception e) {
19151 if (DEBUG_BACKUP) {
19152 Slog.e(TAG, "Unable to write preferred activities for backup", e);
19157 return dataStream.toByteArray();
19161 public void restorePreferredActivities(byte[] backup, int userId) {
19162 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19163 throw new SecurityException("Only the system may call restorePreferredActivities()");
19167 final XmlPullParser parser = Xml.newPullParser();
19168 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19169 restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
19170 new BlobXmlRestorer() {
19172 public void apply(XmlPullParser parser, int userId)
19173 throws XmlPullParserException, IOException {
19174 synchronized (mPackages) {
19175 mSettings.readPreferredActivitiesLPw(parser, userId);
19179 } catch (Exception e) {
19180 if (DEBUG_BACKUP) {
19181 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19187 * Non-Binder method, support for the backup/restore mechanism: write the
19188 * default browser (etc) settings in its canonical XML format. Returns the default
19189 * browser XML representation as a byte array, or null if there is none.
19192 public byte[] getDefaultAppsBackup(int userId) {
19193 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19194 throw new SecurityException("Only the system may call getDefaultAppsBackup()");
19197 ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19199 final XmlSerializer serializer = new FastXmlSerializer();
19200 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19201 serializer.startDocument(null, true);
19202 serializer.startTag(null, TAG_DEFAULT_APPS);
19204 synchronized (mPackages) {
19205 mSettings.writeDefaultAppsLPr(serializer, userId);
19208 serializer.endTag(null, TAG_DEFAULT_APPS);
19209 serializer.endDocument();
19210 serializer.flush();
19211 } catch (Exception e) {
19212 if (DEBUG_BACKUP) {
19213 Slog.e(TAG, "Unable to write default apps for backup", e);
19218 return dataStream.toByteArray();
19222 public void restoreDefaultApps(byte[] backup, int userId) {
19223 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19224 throw new SecurityException("Only the system may call restoreDefaultApps()");
19228 final XmlPullParser parser = Xml.newPullParser();
19229 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19230 restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
19231 new BlobXmlRestorer() {
19233 public void apply(XmlPullParser parser, int userId)
19234 throws XmlPullParserException, IOException {
19235 synchronized (mPackages) {
19236 mSettings.readDefaultAppsLPw(parser, userId);
19240 } catch (Exception e) {
19241 if (DEBUG_BACKUP) {
19242 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
19248 public byte[] getIntentFilterVerificationBackup(int userId) {
19249 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19250 throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
19253 ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19255 final XmlSerializer serializer = new FastXmlSerializer();
19256 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19257 serializer.startDocument(null, true);
19258 serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
19260 synchronized (mPackages) {
19261 mSettings.writeAllDomainVerificationsLPr(serializer, userId);
19264 serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
19265 serializer.endDocument();
19266 serializer.flush();
19267 } catch (Exception e) {
19268 if (DEBUG_BACKUP) {
19269 Slog.e(TAG, "Unable to write default apps for backup", e);
19274 return dataStream.toByteArray();
19278 public void restoreIntentFilterVerification(byte[] backup, int userId) {
19279 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19280 throw new SecurityException("Only the system may call restorePreferredActivities()");
19284 final XmlPullParser parser = Xml.newPullParser();
19285 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19286 restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
19287 new BlobXmlRestorer() {
19289 public void apply(XmlPullParser parser, int userId)
19290 throws XmlPullParserException, IOException {
19291 synchronized (mPackages) {
19292 mSettings.readAllDomainVerificationsLPr(parser, userId);
19293 mSettings.writeLPr();
19297 } catch (Exception e) {
19298 if (DEBUG_BACKUP) {
19299 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19305 public byte[] getPermissionGrantBackup(int userId) {
19306 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19307 throw new SecurityException("Only the system may call getPermissionGrantBackup()");
19310 ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19312 final XmlSerializer serializer = new FastXmlSerializer();
19313 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19314 serializer.startDocument(null, true);
19315 serializer.startTag(null, TAG_PERMISSION_BACKUP);
19317 synchronized (mPackages) {
19318 serializeRuntimePermissionGrantsLPr(serializer, userId);
19321 serializer.endTag(null, TAG_PERMISSION_BACKUP);
19322 serializer.endDocument();
19323 serializer.flush();
19324 } catch (Exception e) {
19325 if (DEBUG_BACKUP) {
19326 Slog.e(TAG, "Unable to write default apps for backup", e);
19331 return dataStream.toByteArray();
19335 public void restorePermissionGrants(byte[] backup, int userId) {
19336 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19337 throw new SecurityException("Only the system may call restorePermissionGrants()");
19341 final XmlPullParser parser = Xml.newPullParser();
19342 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19343 restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
19344 new BlobXmlRestorer() {
19346 public void apply(XmlPullParser parser, int userId)
19347 throws XmlPullParserException, IOException {
19348 synchronized (mPackages) {
19349 processRestoredPermissionGrantsLPr(parser, userId);
19353 } catch (Exception e) {
19354 if (DEBUG_BACKUP) {
19355 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19360 private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
19361 throws IOException {
19362 serializer.startTag(null, TAG_ALL_GRANTS);
19364 final int N = mSettings.mPackages.size();
19365 for (int i = 0; i < N; i++) {
19366 final PackageSetting ps = mSettings.mPackages.valueAt(i);
19367 boolean pkgGrantsKnown = false;
19369 PermissionsState packagePerms = ps.getPermissionsState();
19371 for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
19372 final int grantFlags = state.getFlags();
19373 // only look at grants that are not system/policy fixed
19374 if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
19375 final boolean isGranted = state.isGranted();
19376 // And only back up the user-twiddled state bits
19377 if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
19378 final String packageName = mSettings.mPackages.keyAt(i);
19379 if (!pkgGrantsKnown) {
19380 serializer.startTag(null, TAG_GRANT);
19381 serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
19382 pkgGrantsKnown = true;
19385 final boolean userSet =
19386 (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
19387 final boolean userFixed =
19388 (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
19389 final boolean revoke =
19390 (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
19392 serializer.startTag(null, TAG_PERMISSION);
19393 serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
19395 serializer.attribute(null, ATTR_IS_GRANTED, "true");
19398 serializer.attribute(null, ATTR_USER_SET, "true");
19401 serializer.attribute(null, ATTR_USER_FIXED, "true");
19404 serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
19406 serializer.endTag(null, TAG_PERMISSION);
19411 if (pkgGrantsKnown) {
19412 serializer.endTag(null, TAG_GRANT);
19416 serializer.endTag(null, TAG_ALL_GRANTS);
19419 private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
19420 throws XmlPullParserException, IOException {
19421 String pkgName = null;
19422 int outerDepth = parser.getDepth();
19424 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
19425 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
19426 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
19430 final String tagName = parser.getName();
19431 if (tagName.equals(TAG_GRANT)) {
19432 pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
19433 if (DEBUG_BACKUP) {
19434 Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
19436 } else if (tagName.equals(TAG_PERMISSION)) {
19438 final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
19439 final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
19441 int newFlagSet = 0;
19442 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
19443 newFlagSet |= FLAG_PERMISSION_USER_SET;
19445 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
19446 newFlagSet |= FLAG_PERMISSION_USER_FIXED;
19448 if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
19449 newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
19451 if (DEBUG_BACKUP) {
19452 Slog.v(TAG, " + Restoring grant: pkg=" + pkgName + " perm=" + permName
19453 + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet));
19455 final PackageSetting ps = mSettings.mPackages.get(pkgName);
19457 // Already installed so we apply the grant immediately
19458 if (DEBUG_BACKUP) {
19459 Slog.v(TAG, " + already installed; applying");
19461 PermissionsState perms = ps.getPermissionsState();
19462 BasePermission bp = mSettings.mPermissions.get(permName);
19465 perms.grantRuntimePermission(bp, userId);
19467 if (newFlagSet != 0) {
19468 perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
19472 // Need to wait for post-restore install to apply the grant
19473 if (DEBUG_BACKUP) {
19474 Slog.v(TAG, " - not yet installed; saving for later");
19476 mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
19477 isGranted, newFlagSet, userId);
19480 PackageManagerService.reportSettingsProblem(Log.WARN,
19481 "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
19482 XmlUtils.skipCurrentTag(parser);
19486 scheduleWriteSettingsLocked();
19487 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
19491 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
19492 int sourceUserId, int targetUserId, int flags) {
19493 mContext.enforceCallingOrSelfPermission(
19494 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
19495 int callingUid = Binder.getCallingUid();
19496 enforceOwnerRights(ownerPackage, callingUid);
19497 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
19498 if (intentFilter.countActions() == 0) {
19499 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
19502 synchronized (mPackages) {
19503 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
19504 ownerPackage, targetUserId, flags);
19505 CrossProfileIntentResolver resolver =
19506 mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
19507 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
19508 // We have all those whose filter is equal. Now checking if the rest is equal as well.
19509 if (existing != null) {
19510 int size = existing.size();
19511 for (int i = 0; i < size; i++) {
19512 if (newFilter.equalsIgnoreFilter(existing.get(i))) {
19517 resolver.addFilter(newFilter);
19518 scheduleWritePackageRestrictionsLocked(sourceUserId);
19523 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
19524 mContext.enforceCallingOrSelfPermission(
19525 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
19526 int callingUid = Binder.getCallingUid();
19527 enforceOwnerRights(ownerPackage, callingUid);
19528 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
19529 synchronized (mPackages) {
19530 CrossProfileIntentResolver resolver =
19531 mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
19532 ArraySet<CrossProfileIntentFilter> set =
19533 new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
19534 for (CrossProfileIntentFilter filter : set) {
19535 if (filter.getOwnerPackage().equals(ownerPackage)) {
19536 resolver.removeFilter(filter);
19539 scheduleWritePackageRestrictionsLocked(sourceUserId);
19543 // Enforcing that callingUid is owning pkg on userId
19544 private void enforceOwnerRights(String pkg, int callingUid) {
19545 // The system owns everything.
19546 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
19549 int callingUserId = UserHandle.getUserId(callingUid);
19550 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
19552 throw new IllegalArgumentException("Unknown package " + pkg + " on user "
19555 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
19556 throw new SecurityException("Calling uid " + callingUid
19557 + " does not own package " + pkg);
19562 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
19563 return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
19567 * Report the 'Home' activity which is currently set as "always use this one". If non is set
19568 * then reports the most likely home activity or null if there are more than one.
19570 public ComponentName getDefaultHomeActivity(int userId) {
19571 List<ResolveInfo> allHomeCandidates = new ArrayList<>();
19572 ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
19577 // Find the launcher with the highest priority and return that component if there are no
19578 // other home activity with the same priority.
19579 int lastPriority = Integer.MIN_VALUE;
19580 ComponentName lastComponent = null;
19581 final int size = allHomeCandidates.size();
19582 for (int i = 0; i < size; i++) {
19583 final ResolveInfo ri = allHomeCandidates.get(i);
19584 if (ri.priority > lastPriority) {
19585 lastComponent = ri.activityInfo.getComponentName();
19586 lastPriority = ri.priority;
19587 } else if (ri.priority == lastPriority) {
19588 // Two components found with same priority.
19589 lastComponent = null;
19592 return lastComponent;
19595 private Intent getHomeIntent() {
19596 Intent intent = new Intent(Intent.ACTION_MAIN);
19597 intent.addCategory(Intent.CATEGORY_HOME);
19598 intent.addCategory(Intent.CATEGORY_DEFAULT);
19602 private IntentFilter getHomeFilter() {
19603 IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
19604 filter.addCategory(Intent.CATEGORY_HOME);
19605 filter.addCategory(Intent.CATEGORY_DEFAULT);
19609 ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
19611 Intent intent = getHomeIntent();
19612 List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
19613 PackageManager.GET_META_DATA, userId);
19614 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
19615 true, false, false, userId);
19617 allHomeCandidates.clear();
19618 if (list != null) {
19619 for (ResolveInfo ri : list) {
19620 allHomeCandidates.add(ri);
19623 return (preferred == null || preferred.activityInfo == null)
19625 : new ComponentName(preferred.activityInfo.packageName,
19626 preferred.activityInfo.name);
19630 public void setHomeActivity(ComponentName comp, int userId) {
19631 ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
19632 getHomeActivitiesAsUser(homeActivities, userId);
19634 boolean found = false;
19636 final int size = homeActivities.size();
19637 final ComponentName[] set = new ComponentName[size];
19638 for (int i = 0; i < size; i++) {
19639 final ResolveInfo candidate = homeActivities.get(i);
19640 final ActivityInfo info = candidate.activityInfo;
19641 final ComponentName activityName = new ComponentName(info.packageName, info.name);
19642 set[i] = activityName;
19643 if (!found && activityName.equals(comp)) {
19648 throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
19651 replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
19652 set, comp, userId);
19655 private @Nullable String getSetupWizardPackageName() {
19656 final Intent intent = new Intent(Intent.ACTION_MAIN);
19657 intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
19659 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
19660 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
19661 | MATCH_DISABLED_COMPONENTS,
19662 UserHandle.myUserId());
19663 if (matches.size() == 1) {
19664 return matches.get(0).getComponentInfo().packageName;
19666 Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
19667 + ": matches=" + matches);
19672 private @Nullable String getStorageManagerPackageName() {
19673 final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
19675 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
19676 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
19677 | MATCH_DISABLED_COMPONENTS,
19678 UserHandle.myUserId());
19679 if (matches.size() == 1) {
19680 return matches.get(0).getComponentInfo().packageName;
19682 Slog.e(TAG, "There should probably be exactly one storage manager; found "
19683 + matches.size() + ": matches=" + matches);
19689 public void setApplicationEnabledSetting(String appPackageName,
19690 int newState, int flags, int userId, String callingPackage) {
19691 if (!sUserManager.exists(userId)) return;
19692 if (callingPackage == null) {
19693 callingPackage = Integer.toString(Binder.getCallingUid());
19695 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
19699 public void setUpdateAvailable(String packageName, boolean updateAvailable) {
19700 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
19701 synchronized (mPackages) {
19702 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
19703 if (pkgSetting != null) {
19704 pkgSetting.setUpdateAvailable(updateAvailable);
19710 public void setComponentEnabledSetting(ComponentName componentName,
19711 int newState, int flags, int userId) {
19712 if (!sUserManager.exists(userId)) return;
19713 setEnabledSetting(componentName.getPackageName(),
19714 componentName.getClassName(), newState, flags, userId, null);
19717 private void setEnabledSetting(final String packageName, String className, int newState,
19718 final int flags, int userId, String callingPackage) {
19719 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
19720 || newState == COMPONENT_ENABLED_STATE_ENABLED
19721 || newState == COMPONENT_ENABLED_STATE_DISABLED
19722 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
19723 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
19724 throw new IllegalArgumentException("Invalid new component state: "
19727 PackageSetting pkgSetting;
19728 final int uid = Binder.getCallingUid();
19729 final int permission;
19730 if (uid == Process.SYSTEM_UID) {
19731 permission = PackageManager.PERMISSION_GRANTED;
19733 permission = mContext.checkCallingOrSelfPermission(
19734 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
19736 enforceCrossUserPermission(uid, userId,
19737 false /* requireFullPermission */, true /* checkShell */, "set enabled");
19738 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
19739 boolean sendNow = false;
19740 boolean isApp = (className == null);
19741 String componentName = isApp ? packageName : className;
19742 int packageUid = -1;
19743 ArrayList<String> components;
19746 synchronized (mPackages) {
19747 pkgSetting = mSettings.mPackages.get(packageName);
19748 if (pkgSetting == null) {
19749 if (className == null) {
19750 throw new IllegalArgumentException("Unknown package: " + packageName);
19752 throw new IllegalArgumentException(
19753 "Unknown component: " + packageName + "/" + className);
19757 // Limit who can change which apps
19758 if (!UserHandle.isSameApp(uid, pkgSetting.appId)) {
19759 // Don't allow apps that don't have permission to modify other apps
19760 if (!allowedByPermission) {
19761 throw new SecurityException(
19762 "Permission Denial: attempt to change component state from pid="
19763 + Binder.getCallingPid()
19764 + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
19766 // Don't allow changing protected packages.
19767 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
19768 throw new SecurityException("Cannot disable a protected package: " + packageName);
19772 synchronized (mPackages) {
19773 if (uid == Process.SHELL_UID
19774 && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
19775 // Shell can only change whole packages between ENABLED and DISABLED_USER states
19776 // unless it is a test package.
19777 int oldState = pkgSetting.getEnabled(userId);
19778 if (className == null
19780 (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
19781 || oldState == COMPONENT_ENABLED_STATE_DEFAULT
19782 || oldState == COMPONENT_ENABLED_STATE_ENABLED)
19784 (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
19785 || newState == COMPONENT_ENABLED_STATE_DEFAULT
19786 || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
19789 throw new SecurityException(
19790 "Shell cannot change component state for " + packageName + "/"
19791 + className + " to " + newState);
19794 if (className == null) {
19795 // We're dealing with an application/package level state change
19796 if (pkgSetting.getEnabled(userId) == newState) {
19800 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
19801 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
19802 // Don't care about who enables an app.
19803 callingPackage = null;
19805 pkgSetting.setEnabled(newState, userId, callingPackage);
19806 // pkgSetting.pkg.mSetEnabled = newState;
19808 // We're dealing with a component level state change
19809 // First, verify that this is a valid class name.
19810 PackageParser.Package pkg = pkgSetting.pkg;
19811 if (pkg == null || !pkg.hasComponentClassName(className)) {
19813 pkg.applicationInfo.targetSdkVersion >=
19814 Build.VERSION_CODES.JELLY_BEAN) {
19815 throw new IllegalArgumentException("Component class " + className
19816 + " does not exist in " + packageName);
19818 Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
19819 + className + " does not exist in " + packageName);
19822 switch (newState) {
19823 case COMPONENT_ENABLED_STATE_ENABLED:
19824 if (!pkgSetting.enableComponentLPw(className, userId)) {
19828 case COMPONENT_ENABLED_STATE_DISABLED:
19829 if (!pkgSetting.disableComponentLPw(className, userId)) {
19833 case COMPONENT_ENABLED_STATE_DEFAULT:
19834 if (!pkgSetting.restoreComponentLPw(className, userId)) {
19839 Slog.e(TAG, "Invalid new component state: " + newState);
19843 scheduleWritePackageRestrictionsLocked(userId);
19844 updateSequenceNumberLP(packageName, new int[] { userId });
19845 final long callingId = Binder.clearCallingIdentity();
19847 updateInstantAppInstallerLocked();
19849 Binder.restoreCallingIdentity(callingId);
19851 components = mPendingBroadcasts.get(userId, packageName);
19852 final boolean newPackage = components == null;
19854 components = new ArrayList<String>();
19856 if (!components.contains(componentName)) {
19857 components.add(componentName);
19859 if ((flags&PackageManager.DONT_KILL_APP) == 0) {
19861 // Purge entry from pending broadcast list if another one exists already
19862 // since we are sending one right away.
19863 mPendingBroadcasts.remove(userId, packageName);
19866 mPendingBroadcasts.put(userId, packageName, components);
19868 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
19869 // Schedule a message
19870 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
19875 long callingId = Binder.clearCallingIdentity();
19878 packageUid = UserHandle.getUid(userId, pkgSetting.appId);
19879 sendPackageChangedBroadcast(packageName,
19880 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
19883 Binder.restoreCallingIdentity(callingId);
19888 public void flushPackageRestrictionsAsUser(int userId) {
19889 if (!sUserManager.exists(userId)) {
19892 enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
19893 false /* checkShell */, "flushPackageRestrictions");
19894 synchronized (mPackages) {
19895 mSettings.writePackageRestrictionsLPr(userId);
19896 mDirtyUsers.remove(userId);
19897 if (mDirtyUsers.isEmpty()) {
19898 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
19903 private void sendPackageChangedBroadcast(String packageName,
19904 boolean killFlag, ArrayList<String> componentNames, int packageUid) {
19906 Log.v(TAG, "Sending package changed: package=" + packageName + " components="
19908 Bundle extras = new Bundle(4);
19909 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
19910 String nameList[] = new String[componentNames.size()];
19911 componentNames.toArray(nameList);
19912 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
19913 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
19914 extras.putInt(Intent.EXTRA_UID, packageUid);
19915 // If this is not reporting a change of the overall package, then only send it
19916 // to registered receivers. We don't want to launch a swath of apps for every
19917 // little component state change.
19918 final int flags = !componentNames.contains(packageName)
19919 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
19920 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, flags, null, null,
19921 new int[] {UserHandle.getUserId(packageUid)});
19925 public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
19926 if (!sUserManager.exists(userId)) return;
19927 final int uid = Binder.getCallingUid();
19928 final int permission = mContext.checkCallingOrSelfPermission(
19929 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
19930 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
19931 enforceCrossUserPermission(uid, userId,
19932 true /* requireFullPermission */, true /* checkShell */, "stop package");
19934 synchronized (mPackages) {
19935 if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
19936 allowedByPermission, uid, userId)) {
19937 scheduleWritePackageRestrictionsLocked(userId);
19943 public String getInstallerPackageName(String packageName) {
19945 synchronized (mPackages) {
19946 return mSettings.getInstallerPackageNameLPr(packageName);
19950 public boolean isOrphaned(String packageName) {
19952 synchronized (mPackages) {
19953 return mSettings.isOrphaned(packageName);
19958 public int getApplicationEnabledSetting(String packageName, int userId) {
19959 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
19960 int uid = Binder.getCallingUid();
19961 enforceCrossUserPermission(uid, userId,
19962 false /* requireFullPermission */, false /* checkShell */, "get enabled");
19964 synchronized (mPackages) {
19965 return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
19970 public int getComponentEnabledSetting(ComponentName componentName, int userId) {
19971 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
19972 int uid = Binder.getCallingUid();
19973 enforceCrossUserPermission(uid, userId,
19974 false /* requireFullPermission */, false /* checkShell */, "get component enabled");
19976 synchronized (mPackages) {
19977 return mSettings.getComponentEnabledSettingLPr(componentName, userId);
19982 public void enterSafeMode() {
19983 enforceSystemOrRoot("Only the system can request entering safe mode");
19985 if (!mSystemReady) {
19991 public void systemReady() {
19992 mSystemReady = true;
19994 // Disable any carrier apps. We do this very early in boot to prevent the apps from being
19995 // disabled after already being started.
19996 CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
19997 mContext.getContentResolver(), UserHandle.USER_SYSTEM);
19999 // Read the compatibilty setting when the system is ready.
20000 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
20001 mContext.getContentResolver(),
20002 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
20003 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
20004 if (DEBUG_SETTINGS) {
20005 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
20008 int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
20010 synchronized (mPackages) {
20011 // Verify that all of the preferred activity components actually
20012 // exist. It is possible for applications to be updated and at
20013 // that point remove a previously declared activity component that
20014 // had been set as a preferred activity. We try to clean this up
20015 // the next time we encounter that preferred activity, but it is
20016 // possible for the user flow to never be able to return to that
20017 // situation so here we do a sanity check to make sure we haven't
20018 // left any junk around.
20019 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
20020 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20021 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20023 for (PreferredActivity pa : pir.filterSet()) {
20024 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
20028 if (removed.size() > 0) {
20029 for (int r=0; r<removed.size(); r++) {
20030 PreferredActivity pa = removed.get(r);
20031 Slog.w(TAG, "Removing dangling preferred activity: "
20032 + pa.mPref.mComponent);
20033 pir.removeFilter(pa);
20035 mSettings.writePackageRestrictionsLPr(
20036 mSettings.mPreferredActivities.keyAt(i));
20040 for (int userId : UserManagerService.getInstance().getUserIds()) {
20041 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
20042 grantPermissionsUserIds = ArrayUtils.appendInt(
20043 grantPermissionsUserIds, userId);
20047 sUserManager.systemReady();
20049 // If we upgraded grant all default permissions before kicking off.
20050 for (int userId : grantPermissionsUserIds) {
20051 mDefaultPermissionPolicy.grantDefaultPermissions(userId);
20054 // If we did not grant default permissions, we preload from this the
20055 // default permission exceptions lazily to ensure we don't hit the
20056 // disk on a new user creation.
20057 if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
20058 mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
20061 // Kick off any messages waiting for system ready
20062 if (mPostSystemReadyMessages != null) {
20063 for (Message msg : mPostSystemReadyMessages) {
20064 msg.sendToTarget();
20066 mPostSystemReadyMessages = null;
20069 // Watch for external volumes that come and go over time
20070 final StorageManager storage = mContext.getSystemService(StorageManager.class);
20071 storage.registerListener(mStorageListener);
20073 mInstallerService.systemReady();
20074 mPackageDexOptimizer.systemReady();
20076 StorageManagerInternal StorageManagerInternal = LocalServices.getService(
20077 StorageManagerInternal.class);
20078 StorageManagerInternal.addExternalStoragePolicy(
20079 new StorageManagerInternal.ExternalStorageMountPolicy() {
20081 public int getMountMode(int uid, String packageName) {
20082 if (Process.isIsolated(uid)) {
20083 return Zygote.MOUNT_EXTERNAL_NONE;
20085 if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
20086 return Zygote.MOUNT_EXTERNAL_DEFAULT;
20088 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20089 return Zygote.MOUNT_EXTERNAL_DEFAULT;
20091 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20092 return Zygote.MOUNT_EXTERNAL_READ;
20094 return Zygote.MOUNT_EXTERNAL_WRITE;
20098 public boolean hasExternalStorage(int uid, String packageName) {
20103 // Now that we're mostly running, clean up stale users and apps
20104 sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
20105 reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
20107 if (mPrivappPermissionsViolations != null) {
20108 Slog.wtf(TAG,"Signature|privileged permissions not in "
20109 + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
20110 mPrivappPermissionsViolations = null;
20114 public void waitForAppDataPrepared() {
20115 if (mPrepareAppDataFuture == null) {
20118 ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
20119 mPrepareAppDataFuture = null;
20123 public boolean isSafeMode() {
20128 public boolean hasSystemUidErrors() {
20129 return mHasSystemUidErrors;
20132 static String arrayToString(int[] array) {
20133 StringBuffer buf = new StringBuffer(128);
20135 if (array != null) {
20136 for (int i=0; i<array.length; i++) {
20137 if (i > 0) buf.append(", ");
20138 buf.append(array[i]);
20142 return buf.toString();
20145 static class DumpState {
20146 public static final int DUMP_LIBS = 1 << 0;
20147 public static final int DUMP_FEATURES = 1 << 1;
20148 public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2;
20149 public static final int DUMP_SERVICE_RESOLVERS = 1 << 3;
20150 public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4;
20151 public static final int DUMP_CONTENT_RESOLVERS = 1 << 5;
20152 public static final int DUMP_PERMISSIONS = 1 << 6;
20153 public static final int DUMP_PACKAGES = 1 << 7;
20154 public static final int DUMP_SHARED_USERS = 1 << 8;
20155 public static final int DUMP_MESSAGES = 1 << 9;
20156 public static final int DUMP_PROVIDERS = 1 << 10;
20157 public static final int DUMP_VERIFIERS = 1 << 11;
20158 public static final int DUMP_PREFERRED = 1 << 12;
20159 public static final int DUMP_PREFERRED_XML = 1 << 13;
20160 public static final int DUMP_KEYSETS = 1 << 14;
20161 public static final int DUMP_VERSION = 1 << 15;
20162 public static final int DUMP_INSTALLS = 1 << 16;
20163 public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17;
20164 public static final int DUMP_DOMAIN_PREFERRED = 1 << 18;
20165 public static final int DUMP_FROZEN = 1 << 19;
20166 public static final int DUMP_DEXOPT = 1 << 20;
20167 public static final int DUMP_COMPILER_STATS = 1 << 21;
20168 public static final int DUMP_ENABLED_OVERLAYS = 1 << 22;
20170 public static final int OPTION_SHOW_FILTERS = 1 << 0;
20172 private int mTypes;
20174 private int mOptions;
20176 private boolean mTitlePrinted;
20178 private SharedUserSetting mSharedUser;
20180 public boolean isDumping(int type) {
20181 if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
20185 return (mTypes & type) != 0;
20188 public void setDump(int type) {
20192 public boolean isOptionEnabled(int option) {
20193 return (mOptions & option) != 0;
20196 public void setOptionEnabled(int option) {
20197 mOptions |= option;
20200 public boolean onTitlePrinted() {
20201 final boolean printed = mTitlePrinted;
20202 mTitlePrinted = true;
20206 public boolean getTitlePrinted() {
20207 return mTitlePrinted;
20210 public void setTitlePrinted(boolean enabled) {
20211 mTitlePrinted = enabled;
20214 public SharedUserSetting getSharedUser() {
20215 return mSharedUser;
20218 public void setSharedUser(SharedUserSetting user) {
20219 mSharedUser = user;
20224 public void onShellCommand(FileDescriptor in, FileDescriptor out,
20225 FileDescriptor err, String[] args, ShellCallback callback,
20226 ResultReceiver resultReceiver) {
20227 (new PackageManagerShellCommand(this)).exec(
20228 this, in, out, err, args, callback, resultReceiver);
20232 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
20233 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
20234 != PackageManager.PERMISSION_GRANTED) {
20235 pw.println("Permission Denial: can't dump ActivityManager from from pid="
20236 + Binder.getCallingPid()
20237 + ", uid=" + Binder.getCallingUid()
20238 + " without permission "
20239 + android.Manifest.permission.DUMP);
20243 DumpState dumpState = new DumpState();
20244 boolean fullPreferred = false;
20245 boolean checkin = false;
20247 String packageName = null;
20248 ArraySet<String> permissionNames = null;
20251 while (opti < args.length) {
20252 String opt = args[opti];
20253 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
20258 if ("-a".equals(opt)) {
20259 // Right now we only know how to print all.
20260 } else if ("-h".equals(opt)) {
20261 pw.println("Package manager dump options:");
20262 pw.println(" [-h] [-f] [--checkin] [cmd] ...");
20263 pw.println(" --checkin: dump for a checkin");
20264 pw.println(" -f: print details of intent filters");
20265 pw.println(" -h: print this help");
20266 pw.println(" cmd may be one of:");
20267 pw.println(" l[ibraries]: list known shared libraries");
20268 pw.println(" f[eatures]: list device features");
20269 pw.println(" k[eysets]: print known keysets");
20270 pw.println(" r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
20271 pw.println(" perm[issions]: dump permissions");
20272 pw.println(" permission [name ...]: dump declaration and use of given permission");
20273 pw.println(" pref[erred]: print preferred package settings");
20274 pw.println(" preferred-xml [--full]: print preferred package settings as xml");
20275 pw.println(" prov[iders]: dump content providers");
20276 pw.println(" p[ackages]: dump installed packages");
20277 pw.println(" s[hared-users]: dump shared user IDs");
20278 pw.println(" m[essages]: print collected runtime messages");
20279 pw.println(" v[erifiers]: print package verifier info");
20280 pw.println(" d[omain-preferred-apps]: print domains preferred apps");
20281 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
20282 pw.println(" version: print database version info");
20283 pw.println(" write: write current settings now");
20284 pw.println(" installs: details about install sessions");
20285 pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?");
20286 pw.println(" dexopt: dump dexopt state");
20287 pw.println(" compiler-stats: dump compiler statistics");
20288 pw.println(" enabled-overlays: dump list of enabled overlay packages");
20289 pw.println(" <package.name>: info about given package");
20291 } else if ("--checkin".equals(opt)) {
20293 } else if ("-f".equals(opt)) {
20294 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
20295 } else if ("--proto".equals(opt)) {
20299 pw.println("Unknown argument: " + opt + "; use -h for help");
20303 // Is the caller requesting to dump a particular piece of data?
20304 if (opti < args.length) {
20305 String cmd = args[opti];
20307 // Is this a package name?
20308 if ("android".equals(cmd) || cmd.contains(".")) {
20310 // When dumping a single package, we always dump all of its
20311 // filter information since the amount of data will be reasonable.
20312 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
20313 } else if ("check-permission".equals(cmd)) {
20314 if (opti >= args.length) {
20315 pw.println("Error: check-permission missing permission argument");
20318 String perm = args[opti];
20320 if (opti >= args.length) {
20321 pw.println("Error: check-permission missing package argument");
20325 String pkg = args[opti];
20327 int user = UserHandle.getUserId(Binder.getCallingUid());
20328 if (opti < args.length) {
20330 user = Integer.parseInt(args[opti]);
20331 } catch (NumberFormatException e) {
20332 pw.println("Error: check-permission user argument is not a number: "
20338 // Normalize package name to handle renamed packages and static libs
20339 pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
20341 pw.println(checkPermission(perm, pkg, user));
20343 } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
20344 dumpState.setDump(DumpState.DUMP_LIBS);
20345 } else if ("f".equals(cmd) || "features".equals(cmd)) {
20346 dumpState.setDump(DumpState.DUMP_FEATURES);
20347 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
20348 if (opti >= args.length) {
20349 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
20350 | DumpState.DUMP_SERVICE_RESOLVERS
20351 | DumpState.DUMP_RECEIVER_RESOLVERS
20352 | DumpState.DUMP_CONTENT_RESOLVERS);
20354 while (opti < args.length) {
20355 String name = args[opti];
20356 if ("a".equals(name) || "activity".equals(name)) {
20357 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
20358 } else if ("s".equals(name) || "service".equals(name)) {
20359 dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
20360 } else if ("r".equals(name) || "receiver".equals(name)) {
20361 dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
20362 } else if ("c".equals(name) || "content".equals(name)) {
20363 dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
20365 pw.println("Error: unknown resolver table type: " + name);
20371 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
20372 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
20373 } else if ("permission".equals(cmd)) {
20374 if (opti >= args.length) {
20375 pw.println("Error: permission requires permission name");
20378 permissionNames = new ArraySet<>();
20379 while (opti < args.length) {
20380 permissionNames.add(args[opti]);
20383 dumpState.setDump(DumpState.DUMP_PERMISSIONS
20384 | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
20385 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
20386 dumpState.setDump(DumpState.DUMP_PREFERRED);
20387 } else if ("preferred-xml".equals(cmd)) {
20388 dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
20389 if (opti < args.length && "--full".equals(args[opti])) {
20390 fullPreferred = true;
20393 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
20394 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
20395 } else if ("p".equals(cmd) || "packages".equals(cmd)) {
20396 dumpState.setDump(DumpState.DUMP_PACKAGES);
20397 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
20398 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
20399 } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
20400 dumpState.setDump(DumpState.DUMP_PROVIDERS);
20401 } else if ("m".equals(cmd) || "messages".equals(cmd)) {
20402 dumpState.setDump(DumpState.DUMP_MESSAGES);
20403 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
20404 dumpState.setDump(DumpState.DUMP_VERIFIERS);
20405 } else if ("i".equals(cmd) || "ifv".equals(cmd)
20406 || "intent-filter-verifiers".equals(cmd)) {
20407 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
20408 } else if ("version".equals(cmd)) {
20409 dumpState.setDump(DumpState.DUMP_VERSION);
20410 } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
20411 dumpState.setDump(DumpState.DUMP_KEYSETS);
20412 } else if ("installs".equals(cmd)) {
20413 dumpState.setDump(DumpState.DUMP_INSTALLS);
20414 } else if ("frozen".equals(cmd)) {
20415 dumpState.setDump(DumpState.DUMP_FROZEN);
20416 } else if ("dexopt".equals(cmd)) {
20417 dumpState.setDump(DumpState.DUMP_DEXOPT);
20418 } else if ("compiler-stats".equals(cmd)) {
20419 dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
20420 } else if ("enabled-overlays".equals(cmd)) {
20421 dumpState.setDump(DumpState.DUMP_ENABLED_OVERLAYS);
20422 } else if ("write".equals(cmd)) {
20423 synchronized (mPackages) {
20424 mSettings.writeLPr();
20425 pw.println("Settings written.");
20432 pw.println("vers,1");
20436 synchronized (mPackages) {
20437 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
20439 if (dumpState.onTitlePrinted())
20441 pw.println("Database versions:");
20442 mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, " "));
20446 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
20448 if (dumpState.onTitlePrinted())
20450 pw.println("Verifiers:");
20451 pw.print(" Required: ");
20452 pw.print(mRequiredVerifierPackage);
20453 pw.print(" (uid=");
20454 pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
20455 UserHandle.USER_SYSTEM));
20457 } else if (mRequiredVerifierPackage != null) {
20458 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
20460 pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
20461 UserHandle.USER_SYSTEM));
20465 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
20466 packageName == null) {
20467 if (mIntentFilterVerifierComponent != null) {
20468 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
20470 if (dumpState.onTitlePrinted())
20472 pw.println("Intent Filter Verifier:");
20473 pw.print(" Using: ");
20474 pw.print(verifierPackageName);
20475 pw.print(" (uid=");
20476 pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
20477 UserHandle.USER_SYSTEM));
20479 } else if (verifierPackageName != null) {
20480 pw.print("ifv,"); pw.print(verifierPackageName);
20482 pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
20483 UserHandle.USER_SYSTEM));
20487 pw.println("No Intent Filter Verifier available!");
20491 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
20492 boolean printedHeader = false;
20493 final Iterator<String> it = mSharedLibraries.keySet().iterator();
20494 while (it.hasNext()) {
20495 String libName = it.next();
20496 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
20497 if (versionedLib == null) {
20500 final int versionCount = versionedLib.size();
20501 for (int i = 0; i < versionCount; i++) {
20502 SharedLibraryEntry libEntry = versionedLib.valueAt(i);
20504 if (!printedHeader) {
20505 if (dumpState.onTitlePrinted())
20507 pw.println("Libraries:");
20508 printedHeader = true;
20514 pw.print(libEntry.info.getName());
20515 if (libEntry.info.isStatic()) {
20516 pw.print(" version=" + libEntry.info.getVersion());
20521 if (libEntry.path != null) {
20522 pw.print(" (jar) ");
20523 pw.print(libEntry.path);
20525 pw.print(" (apk) ");
20526 pw.print(libEntry.apk);
20533 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
20534 if (dumpState.onTitlePrinted())
20537 pw.println("Features:");
20540 synchronized (mAvailableFeatures) {
20541 for (FeatureInfo feat : mAvailableFeatures.values()) {
20544 pw.print(feat.name);
20546 pw.println(feat.version);
20549 pw.print(feat.name);
20550 if (feat.version > 0) {
20551 pw.print(" version=");
20552 pw.print(feat.version);
20560 if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
20561 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
20562 : "Activity Resolver Table:", " ", packageName,
20563 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20564 dumpState.setTitlePrinted(true);
20567 if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
20568 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
20569 : "Receiver Resolver Table:", " ", packageName,
20570 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20571 dumpState.setTitlePrinted(true);
20574 if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
20575 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
20576 : "Service Resolver Table:", " ", packageName,
20577 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20578 dumpState.setTitlePrinted(true);
20581 if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
20582 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
20583 : "Provider Resolver Table:", " ", packageName,
20584 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20585 dumpState.setTitlePrinted(true);
20589 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
20590 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20591 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20592 int user = mSettings.mPreferredActivities.keyAt(i);
20594 dumpState.getTitlePrinted()
20595 ? "\nPreferred Activities User " + user + ":"
20596 : "Preferred Activities User " + user + ":", " ",
20597 packageName, true, false)) {
20598 dumpState.setTitlePrinted(true);
20603 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
20605 FileOutputStream fout = new FileOutputStream(fd);
20606 BufferedOutputStream str = new BufferedOutputStream(fout);
20607 XmlSerializer serializer = new FastXmlSerializer();
20609 serializer.setOutput(str, StandardCharsets.UTF_8.name());
20610 serializer.startDocument(null, true);
20611 serializer.setFeature(
20612 "http://xmlpull.org/v1/doc/features.html#indent-output", true);
20613 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
20614 serializer.endDocument();
20615 serializer.flush();
20616 } catch (IllegalArgumentException e) {
20617 pw.println("Failed writing: " + e);
20618 } catch (IllegalStateException e) {
20619 pw.println("Failed writing: " + e);
20620 } catch (IOException e) {
20621 pw.println("Failed writing: " + e);
20626 && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
20627 && packageName == null) {
20629 int count = mSettings.mPackages.size();
20631 pw.println("No applications!");
20634 final String prefix = " ";
20635 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
20636 if (allPackageSettings.size() == 0) {
20637 pw.println("No domain preferred apps!");
20640 pw.println("App verification status:");
20643 for (PackageSetting ps : allPackageSettings) {
20644 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
20645 if (ivi == null || ivi.getPackageName() == null) continue;
20646 pw.println(prefix + "Package: " + ivi.getPackageName());
20647 pw.println(prefix + "Domains: " + ivi.getDomainsString());
20648 pw.println(prefix + "Status: " + ivi.getStatusString());
20653 pw.println(prefix + "No app verification established.");
20656 for (int userId : sUserManager.getUserIds()) {
20657 pw.println("App linkages for user " + userId + ":");
20660 for (PackageSetting ps : allPackageSettings) {
20661 final long status = ps.getDomainVerificationStatusForUser(userId);
20662 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
20663 && !DEBUG_DOMAIN_VERIFICATION) {
20666 pw.println(prefix + "Package: " + ps.name);
20667 pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
20668 String statusStr = IntentFilterVerificationInfo.
20669 getStatusStringFromValue(status);
20670 pw.println(prefix + "Status: " + statusStr);
20675 pw.println(prefix + "No configured app linkages.");
20683 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
20684 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
20685 if (packageName == null && permissionNames == null) {
20686 for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
20688 if (dumpState.onTitlePrinted())
20690 pw.println("AppOp Permissions:");
20692 pw.print(" AppOp Permission ");
20693 pw.print(mAppOpPermissionPackages.keyAt(iperm));
20695 ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
20696 for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
20697 pw.print(" "); pw.println(pkgs.valueAt(ipkg));
20703 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
20704 boolean printedSomething = false;
20705 for (PackageParser.Provider p : mProviders.mProviders.values()) {
20706 if (packageName != null && !packageName.equals(p.info.packageName)) {
20709 if (!printedSomething) {
20710 if (dumpState.onTitlePrinted())
20712 pw.println("Registered ContentProviders:");
20713 printedSomething = true;
20715 pw.print(" "); p.printComponentShortName(pw); pw.println(":");
20716 pw.print(" "); pw.println(p.toString());
20718 printedSomething = false;
20719 for (Map.Entry<String, PackageParser.Provider> entry :
20720 mProvidersByAuthority.entrySet()) {
20721 PackageParser.Provider p = entry.getValue();
20722 if (packageName != null && !packageName.equals(p.info.packageName)) {
20725 if (!printedSomething) {
20726 if (dumpState.onTitlePrinted())
20728 pw.println("ContentProvider Authorities:");
20729 printedSomething = true;
20731 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:");
20732 pw.print(" "); pw.println(p.toString());
20733 if (p.info != null && p.info.applicationInfo != null) {
20734 final String appInfo = p.info.applicationInfo.toString();
20735 pw.print(" applicationInfo="); pw.println(appInfo);
20740 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
20741 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
20744 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
20745 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
20748 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
20749 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
20752 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
20753 mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
20756 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
20757 // XXX should handle packageName != null by dumping only install data that
20758 // the given package is involved with.
20759 if (dumpState.onTitlePrinted()) pw.println();
20760 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120));
20763 if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
20764 // XXX should handle packageName != null by dumping only install data that
20765 // the given package is involved with.
20766 if (dumpState.onTitlePrinted()) pw.println();
20768 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120);
20770 ipw.println("Frozen packages:");
20771 ipw.increaseIndent();
20772 if (mFrozenPackages.size() == 0) {
20773 ipw.println("(none)");
20775 for (int i = 0; i < mFrozenPackages.size(); i++) {
20776 ipw.println(mFrozenPackages.valueAt(i));
20779 ipw.decreaseIndent();
20782 if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
20783 if (dumpState.onTitlePrinted()) pw.println();
20784 dumpDexoptStateLPr(pw, packageName);
20787 if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
20788 if (dumpState.onTitlePrinted()) pw.println();
20789 dumpCompilerStatsLPr(pw, packageName);
20792 if (!checkin && dumpState.isDumping(DumpState.DUMP_ENABLED_OVERLAYS)) {
20793 if (dumpState.onTitlePrinted()) pw.println();
20794 dumpEnabledOverlaysLPr(pw);
20797 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
20798 if (dumpState.onTitlePrinted()) pw.println();
20799 mSettings.dumpReadMessagesLPr(pw, dumpState);
20802 pw.println("Package warning messages:");
20803 BufferedReader in = null;
20804 String line = null;
20806 in = new BufferedReader(new FileReader(getSettingsProblemFile()));
20807 while ((line = in.readLine()) != null) {
20808 if (line.contains("ignored: updated version")) continue;
20811 } catch (IOException ignored) {
20813 IoUtils.closeQuietly(in);
20817 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
20818 BufferedReader in = null;
20819 String line = null;
20821 in = new BufferedReader(new FileReader(getSettingsProblemFile()));
20822 while ((line = in.readLine()) != null) {
20823 if (line.contains("ignored: updated version")) continue;
20827 } catch (IOException ignored) {
20829 IoUtils.closeQuietly(in);
20835 private void dumpProto(FileDescriptor fd) {
20836 final ProtoOutputStream proto = new ProtoOutputStream(fd);
20838 synchronized (mPackages) {
20839 final long requiredVerifierPackageToken =
20840 proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
20841 proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
20843 PackageServiceDumpProto.PackageShortProto.UID,
20845 mRequiredVerifierPackage,
20846 MATCH_DEBUG_TRIAGED_MISSING,
20847 UserHandle.USER_SYSTEM));
20848 proto.end(requiredVerifierPackageToken);
20850 if (mIntentFilterVerifierComponent != null) {
20851 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
20852 final long verifierPackageToken =
20853 proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
20854 proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
20856 PackageServiceDumpProto.PackageShortProto.UID,
20858 verifierPackageName,
20859 MATCH_DEBUG_TRIAGED_MISSING,
20860 UserHandle.USER_SYSTEM));
20861 proto.end(verifierPackageToken);
20864 dumpSharedLibrariesProto(proto);
20865 dumpFeaturesProto(proto);
20866 mSettings.dumpPackagesProto(proto);
20867 mSettings.dumpSharedUsersProto(proto);
20868 dumpMessagesProto(proto);
20873 private void dumpMessagesProto(ProtoOutputStream proto) {
20874 BufferedReader in = null;
20875 String line = null;
20877 in = new BufferedReader(new FileReader(getSettingsProblemFile()));
20878 while ((line = in.readLine()) != null) {
20879 if (line.contains("ignored: updated version")) continue;
20880 proto.write(PackageServiceDumpProto.MESSAGES, line);
20882 } catch (IOException ignored) {
20884 IoUtils.closeQuietly(in);
20888 private void dumpFeaturesProto(ProtoOutputStream proto) {
20889 synchronized (mAvailableFeatures) {
20890 final int count = mAvailableFeatures.size();
20891 for (int i = 0; i < count; i++) {
20892 final FeatureInfo feat = mAvailableFeatures.valueAt(i);
20893 final long featureToken = proto.start(PackageServiceDumpProto.FEATURES);
20894 proto.write(PackageServiceDumpProto.FeatureProto.NAME, feat.name);
20895 proto.write(PackageServiceDumpProto.FeatureProto.VERSION, feat.version);
20896 proto.end(featureToken);
20901 private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
20902 final int count = mSharedLibraries.size();
20903 for (int i = 0; i < count; i++) {
20904 final String libName = mSharedLibraries.keyAt(i);
20905 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
20906 if (versionedLib == null) {
20909 final int versionCount = versionedLib.size();
20910 for (int j = 0; j < versionCount; j++) {
20911 final SharedLibraryEntry libEntry = versionedLib.valueAt(j);
20912 final long sharedLibraryToken =
20913 proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
20914 proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libEntry.info.getName());
20915 final boolean isJar = (libEntry.path != null);
20916 proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
20918 proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH, libEntry.path);
20920 proto.write(PackageServiceDumpProto.SharedLibraryProto.APK, libEntry.apk);
20922 proto.end(sharedLibraryToken);
20927 private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
20928 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120);
20930 ipw.println("Dexopt state:");
20931 ipw.increaseIndent();
20932 Collection<PackageParser.Package> packages = null;
20933 if (packageName != null) {
20934 PackageParser.Package targetPackage = mPackages.get(packageName);
20935 if (targetPackage != null) {
20936 packages = Collections.singletonList(targetPackage);
20938 ipw.println("Unable to find package: " + packageName);
20942 packages = mPackages.values();
20945 for (PackageParser.Package pkg : packages) {
20946 ipw.println("[" + pkg.packageName + "]");
20947 ipw.increaseIndent();
20948 mPackageDexOptimizer.dumpDexoptState(ipw, pkg);
20949 ipw.decreaseIndent();
20953 private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
20954 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120);
20956 ipw.println("Compiler stats:");
20957 ipw.increaseIndent();
20958 Collection<PackageParser.Package> packages = null;
20959 if (packageName != null) {
20960 PackageParser.Package targetPackage = mPackages.get(packageName);
20961 if (targetPackage != null) {
20962 packages = Collections.singletonList(targetPackage);
20964 ipw.println("Unable to find package: " + packageName);
20968 packages = mPackages.values();
20971 for (PackageParser.Package pkg : packages) {
20972 ipw.println("[" + pkg.packageName + "]");
20973 ipw.increaseIndent();
20975 CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
20976 if (stats == null) {
20977 ipw.println("(No recorded stats)");
20981 ipw.decreaseIndent();
20985 private void dumpEnabledOverlaysLPr(PrintWriter pw) {
20986 pw.println("Enabled overlay paths:");
20987 final int N = mEnabledOverlayPaths.size();
20988 for (int i = 0; i < N; i++) {
20989 final int userId = mEnabledOverlayPaths.keyAt(i);
20990 pw.println(String.format(" User %d:", userId));
20991 final ArrayMap<String, ArrayList<String>> userSpecificOverlays =
20992 mEnabledOverlayPaths.valueAt(i);
20993 final int M = userSpecificOverlays.size();
20994 for (int j = 0; j < M; j++) {
20995 final String targetPackageName = userSpecificOverlays.keyAt(j);
20996 final ArrayList<String> overlayPackagePaths = userSpecificOverlays.valueAt(j);
20997 pw.println(String.format(" %s: %s", targetPackageName, overlayPackagePaths));
21002 private String dumpDomainString(String packageName) {
21003 List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
21005 List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
21007 ArraySet<String> result = new ArraySet<>();
21008 if (iviList.size() > 0) {
21009 for (IntentFilterVerificationInfo ivi : iviList) {
21010 for (String host : ivi.getDomains()) {
21015 if (filters != null && filters.size() > 0) {
21016 for (IntentFilter filter : filters) {
21017 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
21018 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
21019 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
21020 result.addAll(filter.getHostsList());
21025 StringBuilder sb = new StringBuilder(result.size() * 16);
21026 for (String domain : result) {
21027 if (sb.length() > 0) sb.append(" ");
21030 return sb.toString();
21033 // ------- apps on sdcard specific code -------
21034 static final boolean DEBUG_SD_INSTALL = false;
21036 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
21038 private static final String SD_ENCRYPTION_ALGORITHM = "AES";
21040 private boolean mMediaMounted = false;
21042 static String getEncryptKey() {
21044 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
21045 SD_ENCRYPTION_KEYSTORE_NAME);
21046 if (sdEncKey == null) {
21047 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
21048 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
21049 if (sdEncKey == null) {
21050 Slog.e(TAG, "Failed to create encryption keys");
21055 } catch (NoSuchAlgorithmException nsae) {
21056 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
21058 } catch (IOException ioe) {
21059 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
21065 * Update media status on PackageManager.
21068 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
21069 int callingUid = Binder.getCallingUid();
21070 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
21071 throw new SecurityException("Media status can only be updated by the system");
21073 // reader; this apparently protects mMediaMounted, but should probably
21074 // be a different lock in that case.
21075 synchronized (mPackages) {
21076 Log.i(TAG, "Updating external media status from "
21077 + (mMediaMounted ? "mounted" : "unmounted") + " to "
21078 + (mediaStatus ? "mounted" : "unmounted"));
21079 if (DEBUG_SD_INSTALL)
21080 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
21081 + ", mMediaMounted=" + mMediaMounted);
21082 if (mediaStatus == mMediaMounted) {
21083 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
21085 mHandler.sendMessage(msg);
21088 mMediaMounted = mediaStatus;
21090 // Queue up an async operation since the package installation may take a
21092 mHandler.post(new Runnable() {
21093 public void run() {
21094 updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
21100 * Called by StorageManagerService when the initial ASECs to scan are available.
21101 * Should block until all the ASEC containers are finished being scanned.
21103 public void scanAvailableAsecs() {
21104 updateExternalMediaStatusInner(true, false, false);
21108 * Collect information of applications on external media, map them against
21109 * existing containers and update information based on current mount status.
21110 * Please note that we always have to report status if reportStatus has been
21111 * set to true especially when unloading packages.
21113 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
21114 boolean externalStorage) {
21115 ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
21116 int[] uidArr = EmptyArray.INT;
21118 final String[] list = PackageHelper.getSecureContainerList();
21119 if (ArrayUtils.isEmpty(list)) {
21120 Log.i(TAG, "No secure containers found");
21122 // Process list of secure containers and categorize them
21123 // as active or stale based on their package internal state.
21126 synchronized (mPackages) {
21127 for (String cid : list) {
21128 // Leave stages untouched for now; installer service owns them
21129 if (PackageInstallerService.isStageName(cid)) continue;
21131 if (DEBUG_SD_INSTALL)
21132 Log.i(TAG, "Processing container " + cid);
21133 String pkgName = getAsecPackageName(cid);
21134 if (pkgName == null) {
21135 Slog.i(TAG, "Found stale container " + cid + " with no package name");
21138 if (DEBUG_SD_INSTALL)
21139 Log.i(TAG, "Looking for pkg : " + pkgName);
21141 final PackageSetting ps = mSettings.mPackages.get(pkgName);
21143 Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
21148 * Skip packages that are not external if we're unmounting
21149 * external storage.
21151 if (externalStorage && !isMounted && !isExternal(ps)) {
21155 final AsecInstallArgs args = new AsecInstallArgs(cid,
21156 getAppDexInstructionSets(ps), ps.isForwardLocked());
21157 // The package status is changed only if the code path
21158 // matches between settings and the container id.
21159 if (ps.codePathString != null
21160 && ps.codePathString.startsWith(args.getCodePath())) {
21161 if (DEBUG_SD_INSTALL) {
21162 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
21163 + " at code path: " + ps.codePathString);
21166 // We do have a valid package installed on sdcard
21167 processCids.put(args, ps.codePathString);
21168 final int uid = ps.appId;
21170 uidArr = ArrayUtils.appendInt(uidArr, uid);
21173 Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
21174 + ps.codePathString);
21179 Arrays.sort(uidArr);
21182 // Process packages with valid entries.
21184 if (DEBUG_SD_INSTALL)
21185 Log.i(TAG, "Loading packages");
21186 loadMediaPackages(processCids, uidArr, externalStorage);
21187 startCleaningPackages();
21188 mInstallerService.onSecureContainersAvailable();
21190 if (DEBUG_SD_INSTALL)
21191 Log.i(TAG, "Unloading packages");
21192 unloadMediaPackages(processCids, uidArr, reportStatus);
21196 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21197 ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
21198 final int size = infos.size();
21199 final String[] packageNames = new String[size];
21200 final int[] packageUids = new int[size];
21201 for (int i = 0; i < size; i++) {
21202 final ApplicationInfo info = infos.get(i);
21203 packageNames[i] = info.packageName;
21204 packageUids[i] = info.uid;
21206 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
21210 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21211 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21212 sendResourcesChangedBroadcast(mediaStatus, replacing,
21213 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
21216 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21217 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21218 int size = pkgList.length;
21220 // Send broadcasts here
21221 Bundle extras = new Bundle();
21222 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
21223 if (uidArr != null) {
21224 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
21227 extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
21229 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
21230 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
21231 sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null);
21236 * Look at potentially valid container ids from processCids If package
21237 * information doesn't match the one on record or package scanning fails,
21238 * the cid is added to list of removeCids. We currently don't delete stale
21241 private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr,
21242 boolean externalStorage) {
21243 ArrayList<String> pkgList = new ArrayList<String>();
21244 Set<AsecInstallArgs> keys = processCids.keySet();
21246 for (AsecInstallArgs args : keys) {
21247 String codePath = processCids.get(args);
21248 if (DEBUG_SD_INSTALL)
21249 Log.i(TAG, "Loading container : " + args.cid);
21250 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
21252 // Make sure there are no container errors first.
21253 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
21254 Slog.e(TAG, "Failed to mount cid : " + args.cid
21255 + " when installing from sdcard");
21258 // Check code path here.
21259 if (codePath == null || !codePath.startsWith(args.getCodePath())) {
21260 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
21261 + " does not match one in settings " + codePath);
21265 int parseFlags = mDefParseFlags;
21266 if (args.isExternalAsec()) {
21267 parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
21269 if (args.isFwdLocked()) {
21270 parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
21273 synchronized (mInstallLock) {
21274 PackageParser.Package pkg = null;
21276 // Sadly we don't know the package name yet to freeze it
21277 pkg = scanPackageTracedLI(new File(codePath), parseFlags,
21278 SCAN_IGNORE_FROZEN, 0, null);
21279 } catch (PackageManagerException e) {
21280 Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
21282 // Scan the package
21285 * TODO why is the lock being held? doPostInstall is
21286 * called in other places without the lock. This needs
21287 * to be straightened out.
21290 synchronized (mPackages) {
21291 retCode = PackageManager.INSTALL_SUCCEEDED;
21292 pkgList.add(pkg.packageName);
21293 // Post process args
21294 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
21295 pkg.applicationInfo.uid);
21298 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard");
21303 if (retCode != PackageManager.INSTALL_SUCCEEDED) {
21304 Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
21309 synchronized (mPackages) {
21310 // If the platform SDK has changed since the last time we booted,
21311 // we need to re-grant app permission to catch any new ones that
21312 // appear. This is really a hack, and means that apps can in some
21313 // cases get permissions that the user didn't initially explicitly
21314 // allow... it would be nice to have some better way to handle
21316 final VersionInfo ver = externalStorage ? mSettings.getExternalVersion()
21317 : mSettings.getInternalVersion();
21318 final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL
21319 : StorageManager.UUID_PRIVATE_INTERNAL;
21321 int updateFlags = UPDATE_PERMISSIONS_ALL;
21322 if (ver.sdkVersion != mSdkVersion) {
21323 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
21324 + mSdkVersion + "; regranting permissions for external");
21325 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
21327 updatePermissionsLPw(null, null, volumeUuid, updateFlags);
21329 // Yay, everything is now upgraded
21330 ver.forceCurrent();
21332 // can downgrade to reader
21333 // Persist settings
21334 mSettings.writeLPr();
21336 // Send a broadcast to let everyone know we are done processing
21337 if (pkgList.size() > 0) {
21338 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
21343 * Utility method to unload a list of specified containers
21345 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
21346 // Just unmount all valid containers.
21347 for (AsecInstallArgs arg : cidArgs) {
21348 synchronized (mInstallLock) {
21349 arg.doPostDeleteLI(false);
21355 * Unload packages mounted on external media. This involves deleting package
21356 * data from internal structures, sending broadcasts about disabled packages,
21357 * gc'ing to free up references, unmounting all secure containers
21358 * corresponding to packages on external media, and posting a
21359 * UPDATED_MEDIA_STATUS message if status has been requested. Please note
21360 * that we always have to post this message if status has been requested no
21363 private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
21364 final boolean reportStatus) {
21365 if (DEBUG_SD_INSTALL)
21366 Log.i(TAG, "unloading media packages");
21367 ArrayList<String> pkgList = new ArrayList<String>();
21368 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
21369 final Set<AsecInstallArgs> keys = processCids.keySet();
21370 for (AsecInstallArgs args : keys) {
21371 String pkgName = args.getPackageName();
21372 if (DEBUG_SD_INSTALL)
21373 Log.i(TAG, "Trying to unload pkg : " + pkgName);
21374 // Delete package internally
21375 PackageRemovedInfo outInfo = new PackageRemovedInfo();
21376 synchronized (mInstallLock) {
21377 final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
21379 try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags,
21380 "unloadMediaPackages")) {
21381 res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false,
21385 pkgList.add(pkgName);
21387 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
21388 failedList.add(args);
21394 synchronized (mPackages) {
21395 // We didn't update the settings after removing each package;
21396 // write them now for all packages.
21397 mSettings.writeLPr();
21400 // We have to absolutely send UPDATED_MEDIA_STATUS only
21401 // after confirming that all the receivers processed the ordered
21402 // broadcast when packages get disabled, force a gc to clean things up.
21403 // and unload all the containers.
21404 if (pkgList.size() > 0) {
21405 sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
21406 new IIntentReceiver.Stub() {
21407 public void performReceive(Intent intent, int resultCode, String data,
21408 Bundle extras, boolean ordered, boolean sticky,
21409 int sendingUser) throws RemoteException {
21410 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
21411 reportStatus ? 1 : 0, 1, keys);
21412 mHandler.sendMessage(msg);
21416 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
21418 mHandler.sendMessage(msg);
21422 private void loadPrivatePackages(final VolumeInfo vol) {
21423 mHandler.post(new Runnable() {
21425 public void run() {
21426 loadPrivatePackagesInner(vol);
21431 private void loadPrivatePackagesInner(VolumeInfo vol) {
21432 final String volumeUuid = vol.fsUuid;
21433 if (TextUtils.isEmpty(volumeUuid)) {
21434 Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
21438 final ArrayList<PackageFreezer> freezers = new ArrayList<>();
21439 final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
21440 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
21442 final VersionInfo ver;
21443 final List<PackageSetting> packages;
21444 synchronized (mPackages) {
21445 ver = mSettings.findOrCreateVersion(volumeUuid);
21446 packages = mSettings.getVolumePackagesLPr(volumeUuid);
21449 for (PackageSetting ps : packages) {
21450 freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
21451 synchronized (mInstallLock) {
21452 final PackageParser.Package pkg;
21454 pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
21455 loaded.add(pkg.applicationInfo);
21457 } catch (PackageManagerException e) {
21458 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
21461 if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
21462 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
21463 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
21464 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
21469 // Reconcile app data for all started/unlocked users
21470 final StorageManager sm = mContext.getSystemService(StorageManager.class);
21471 final UserManager um = mContext.getSystemService(UserManager.class);
21472 UserManagerInternal umInternal = getUserManagerInternal();
21473 for (UserInfo user : um.getUsers()) {
21475 if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
21476 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
21477 } else if (umInternal.isUserRunning(user.id)) {
21478 flags = StorageManager.FLAG_STORAGE_DE;
21484 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
21485 synchronized (mInstallLock) {
21486 reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
21488 } catch (IllegalStateException e) {
21489 // Device was probably ejected, and we'll process that event momentarily
21490 Slog.w(TAG, "Failed to prepare storage: " + e);
21494 synchronized (mPackages) {
21495 int updateFlags = UPDATE_PERMISSIONS_ALL;
21496 if (ver.sdkVersion != mSdkVersion) {
21497 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
21498 + mSdkVersion + "; regranting permissions for " + volumeUuid);
21499 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
21501 updatePermissionsLPw(null, null, volumeUuid, updateFlags);
21503 // Yay, everything is now upgraded
21504 ver.forceCurrent();
21506 mSettings.writeLPr();
21509 for (PackageFreezer freezer : freezers) {
21513 if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
21514 sendResourcesChangedBroadcast(true, false, loaded, null);
21517 private void unloadPrivatePackages(final VolumeInfo vol) {
21518 mHandler.post(new Runnable() {
21520 public void run() {
21521 unloadPrivatePackagesInner(vol);
21526 private void unloadPrivatePackagesInner(VolumeInfo vol) {
21527 final String volumeUuid = vol.fsUuid;
21528 if (TextUtils.isEmpty(volumeUuid)) {
21529 Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
21533 final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
21534 synchronized (mInstallLock) {
21535 synchronized (mPackages) {
21536 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
21537 for (PackageSetting ps : packages) {
21538 if (ps.pkg == null) continue;
21540 final ApplicationInfo info = ps.pkg.applicationInfo;
21541 final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
21542 final PackageRemovedInfo outInfo = new PackageRemovedInfo();
21544 try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
21545 "unloadPrivatePackagesInner")) {
21546 if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
21548 unloaded.add(info);
21550 Slog.w(TAG, "Failed to unload " + ps.codePath);
21554 // Try very hard to release any references to this package
21555 // so we don't risk the system server being killed due to
21557 AttributeCache.instance().removePackage(ps.name);
21560 mSettings.writeLPr();
21564 if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
21565 sendResourcesChangedBroadcast(false, false, unloaded, null);
21567 // Try very hard to release any references to this path so we don't risk
21568 // the system server being killed due to open FDs
21569 ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
21571 for (int i = 0; i < 3; i++) {
21573 System.runFinalization();
21577 private void assertPackageKnown(String volumeUuid, String packageName)
21578 throws PackageManagerException {
21579 synchronized (mPackages) {
21580 // Normalize package name to handle renamed packages
21581 packageName = normalizePackageNameLPr(packageName);
21583 final PackageSetting ps = mSettings.mPackages.get(packageName);
21585 throw new PackageManagerException("Package " + packageName + " is unknown");
21586 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
21587 throw new PackageManagerException(
21588 "Package " + packageName + " found on unknown volume " + volumeUuid
21589 + "; expected volume " + ps.volumeUuid);
21594 private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
21595 throws PackageManagerException {
21596 synchronized (mPackages) {
21597 // Normalize package name to handle renamed packages
21598 packageName = normalizePackageNameLPr(packageName);
21600 final PackageSetting ps = mSettings.mPackages.get(packageName);
21602 throw new PackageManagerException("Package " + packageName + " is unknown");
21603 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
21604 throw new PackageManagerException(
21605 "Package " + packageName + " found on unknown volume " + volumeUuid
21606 + "; expected volume " + ps.volumeUuid);
21607 } else if (!ps.getInstalled(userId)) {
21608 throw new PackageManagerException(
21609 "Package " + packageName + " not installed for user " + userId);
21614 private List<String> collectAbsoluteCodePaths() {
21615 synchronized (mPackages) {
21616 List<String> codePaths = new ArrayList<>();
21617 final int packageCount = mSettings.mPackages.size();
21618 for (int i = 0; i < packageCount; i++) {
21619 final PackageSetting ps = mSettings.mPackages.valueAt(i);
21620 codePaths.add(ps.codePath.getAbsolutePath());
21627 * Examine all apps present on given mounted volume, and destroy apps that
21628 * aren't expected, either due to uninstallation or reinstallation on
21631 private void reconcileApps(String volumeUuid) {
21632 List<String> absoluteCodePaths = collectAbsoluteCodePaths();
21633 List<File> filesToDelete = null;
21635 final File[] files = FileUtils.listFilesOrEmpty(
21636 Environment.getDataAppDirectory(volumeUuid));
21637 for (File file : files) {
21638 final boolean isPackage = (isApkFile(file) || file.isDirectory())
21639 && !PackageInstallerService.isStageName(file.getName());
21641 // Ignore entries which are not packages
21645 String absolutePath = file.getAbsolutePath();
21647 boolean pathValid = false;
21648 final int absoluteCodePathCount = absoluteCodePaths.size();
21649 for (int i = 0; i < absoluteCodePathCount; i++) {
21650 String absoluteCodePath = absoluteCodePaths.get(i);
21651 if (absolutePath.startsWith(absoluteCodePath)) {
21658 if (filesToDelete == null) {
21659 filesToDelete = new ArrayList<>();
21661 filesToDelete.add(file);
21665 if (filesToDelete != null) {
21666 final int fileToDeleteCount = filesToDelete.size();
21667 for (int i = 0; i < fileToDeleteCount; i++) {
21668 File fileToDelete = filesToDelete.get(i);
21669 logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
21670 synchronized (mInstallLock) {
21671 removeCodePathLI(fileToDelete);
21678 * Reconcile all app data for the given user.
21680 * Verifies that directories exist and that ownership and labeling is
21681 * correct for all installed apps on all mounted volumes.
21683 void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
21684 final StorageManager storage = mContext.getSystemService(StorageManager.class);
21685 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
21686 final String volumeUuid = vol.getFsUuid();
21687 synchronized (mInstallLock) {
21688 reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
21693 private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
21694 boolean migrateAppData) {
21695 reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
21699 * Reconcile all app data on given mounted volume.
21701 * Destroys app data that isn't expected, either due to uninstallation or
21702 * reinstallation on another volume.
21704 * Verifies that directories exist and that ownership and labeling is
21705 * correct for all installed apps.
21706 * @returns list of skipped non-core packages (if {@code onlyCoreApps} is true)
21708 private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
21709 boolean migrateAppData, boolean onlyCoreApps) {
21710 Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
21711 + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
21712 List<String> result = onlyCoreApps ? new ArrayList<>() : null;
21714 final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
21715 final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
21717 // First look for stale data that doesn't belong, and check if things
21718 // have changed since we did our last restorecon
21719 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
21720 if (StorageManager.isFileEncryptedNativeOrEmulated()
21721 && !StorageManager.isUserKeyUnlocked(userId)) {
21722 throw new RuntimeException(
21723 "Yikes, someone asked us to reconcile CE storage while " + userId
21724 + " was still locked; this would have caused massive data loss!");
21727 final File[] files = FileUtils.listFilesOrEmpty(ceDir);
21728 for (File file : files) {
21729 final String packageName = file.getName();
21731 assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
21732 } catch (PackageManagerException e) {
21733 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
21735 mInstaller.destroyAppData(volumeUuid, packageName, userId,
21736 StorageManager.FLAG_STORAGE_CE, 0);
21737 } catch (InstallerException e2) {
21738 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
21743 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
21744 final File[] files = FileUtils.listFilesOrEmpty(deDir);
21745 for (File file : files) {
21746 final String packageName = file.getName();
21748 assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
21749 } catch (PackageManagerException e) {
21750 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
21752 mInstaller.destroyAppData(volumeUuid, packageName, userId,
21753 StorageManager.FLAG_STORAGE_DE, 0);
21754 } catch (InstallerException e2) {
21755 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
21761 // Ensure that data directories are ready to roll for all packages
21762 // installed for this volume and user
21763 final List<PackageSetting> packages;
21764 synchronized (mPackages) {
21765 packages = mSettings.getVolumePackagesLPr(volumeUuid);
21767 int preparedCount = 0;
21768 for (PackageSetting ps : packages) {
21769 final String packageName = ps.name;
21770 if (ps.pkg == null) {
21771 Slog.w(TAG, "Odd, missing scanned package " + packageName);
21772 // TODO: might be due to legacy ASEC apps; we should circle back
21773 // and reconcile again once they're scanned
21776 // Skip non-core apps if requested
21777 if (onlyCoreApps && !ps.pkg.coreApp) {
21778 result.add(packageName);
21782 if (ps.getInstalled(userId)) {
21783 prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
21788 Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
21793 * Prepare app data for the given app just after it was installed or
21794 * upgraded. This method carefully only touches users that it's installed
21795 * for, and it forces a restorecon to handle any seinfo changes.
21797 * Verifies that directories exist and that ownership and labeling is
21798 * correct for all installed apps. If there is an ownership mismatch, it
21799 * will try recovering system apps by wiping data; third-party app data is
21802 * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
21804 private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
21805 final PackageSetting ps;
21806 synchronized (mPackages) {
21807 ps = mSettings.mPackages.get(pkg.packageName);
21808 mSettings.writeKernelMappingLPr(ps);
21811 final UserManager um = mContext.getSystemService(UserManager.class);
21812 UserManagerInternal umInternal = getUserManagerInternal();
21813 for (UserInfo user : um.getUsers()) {
21815 if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
21816 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
21817 } else if (umInternal.isUserRunning(user.id)) {
21818 flags = StorageManager.FLAG_STORAGE_DE;
21823 if (ps.getInstalled(user.id)) {
21824 // TODO: when user data is locked, mark that we're still dirty
21825 prepareAppDataLIF(pkg, user.id, flags);
21831 * Prepare app data for the given app.
21833 * Verifies that directories exist and that ownership and labeling is
21834 * correct for all installed apps. If there is an ownership mismatch, this
21835 * will try recovering system apps by wiping data; third-party app data is
21838 private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
21840 Slog.wtf(TAG, "Package was null!", new Throwable());
21843 prepareAppDataLeafLIF(pkg, userId, flags);
21844 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
21845 for (int i = 0; i < childCount; i++) {
21846 prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
21850 private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags,
21851 boolean maybeMigrateAppData) {
21852 prepareAppDataLIF(pkg, userId, flags);
21854 if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
21855 // We may have just shuffled around app data directories, so
21856 // prepare them one more time
21857 prepareAppDataLIF(pkg, userId, flags);
21861 private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
21862 if (DEBUG_APP_DATA) {
21863 Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
21864 + Integer.toHexString(flags));
21867 final String volumeUuid = pkg.volumeUuid;
21868 final String packageName = pkg.packageName;
21869 final ApplicationInfo app = pkg.applicationInfo;
21870 final int appId = UserHandle.getAppId(app.uid);
21872 Preconditions.checkNotNull(app.seInfo);
21874 long ceDataInode = -1;
21876 ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
21877 appId, app.seInfo, app.targetSdkVersion);
21878 } catch (InstallerException e) {
21879 if (app.isSystemApp()) {
21880 logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
21881 + ", but trying to recover: " + e);
21882 destroyAppDataLeafLIF(pkg, userId, flags);
21884 ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
21885 appId, app.seInfo, app.targetSdkVersion);
21886 logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
21887 } catch (InstallerException e2) {
21888 logCriticalInfo(Log.DEBUG, "Recovery failed!");
21891 Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
21895 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
21896 // TODO: mark this structure as dirty so we persist it!
21897 synchronized (mPackages) {
21898 final PackageSetting ps = mSettings.mPackages.get(packageName);
21900 ps.setCeDataInode(ceDataInode, userId);
21905 prepareAppDataContentsLeafLIF(pkg, userId, flags);
21908 private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
21910 Slog.wtf(TAG, "Package was null!", new Throwable());
21913 prepareAppDataContentsLeafLIF(pkg, userId, flags);
21914 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
21915 for (int i = 0; i < childCount; i++) {
21916 prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
21920 private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
21921 final String volumeUuid = pkg.volumeUuid;
21922 final String packageName = pkg.packageName;
21923 final ApplicationInfo app = pkg.applicationInfo;
21925 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
21926 // Create a native library symlink only if we have native libraries
21927 // and if the native libraries are 32 bit libraries. We do not provide
21928 // this symlink for 64 bit libraries.
21929 if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
21930 final String nativeLibPath = app.nativeLibraryDir;
21932 mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
21933 nativeLibPath, userId);
21934 } catch (InstallerException e) {
21935 Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
21942 * For system apps on non-FBE devices, this method migrates any existing
21943 * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
21944 * requested by the app.
21946 private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
21947 if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated()
21948 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
21949 final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
21950 ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
21952 mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
21954 } catch (InstallerException e) {
21955 logCriticalInfo(Log.WARN,
21956 "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
21964 public PackageFreezer freezePackage(String packageName, String killReason) {
21965 return freezePackage(packageName, UserHandle.USER_ALL, killReason);
21968 public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
21969 return new PackageFreezer(packageName, userId, killReason);
21972 public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
21973 String killReason) {
21974 return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
21977 public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
21978 String killReason) {
21979 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
21980 return new PackageFreezer();
21982 return freezePackage(packageName, userId, killReason);
21986 public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
21987 String killReason) {
21988 return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
21991 public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
21992 String killReason) {
21993 if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
21994 return new PackageFreezer();
21996 return freezePackage(packageName, userId, killReason);
22001 * Class that freezes and kills the given package upon creation, and
22002 * unfreezes it upon closing. This is typically used when doing surgery on
22003 * app code/data to prevent the app from running while you're working.
22005 private class PackageFreezer implements AutoCloseable {
22006 private final String mPackageName;
22007 private final PackageFreezer[] mChildren;
22009 private final boolean mWeFroze;
22011 private final AtomicBoolean mClosed = new AtomicBoolean();
22012 private final CloseGuard mCloseGuard = CloseGuard.get();
22015 * Create and return a stub freezer that doesn't actually do anything,
22016 * typically used when someone requested
22017 * {@link PackageManager#INSTALL_DONT_KILL_APP} or
22018 * {@link PackageManager#DELETE_DONT_KILL_APP}.
22020 public PackageFreezer() {
22021 mPackageName = null;
22024 mCloseGuard.open("close");
22027 public PackageFreezer(String packageName, int userId, String killReason) {
22028 synchronized (mPackages) {
22029 mPackageName = packageName;
22030 mWeFroze = mFrozenPackages.add(mPackageName);
22032 final PackageSetting ps = mSettings.mPackages.get(mPackageName);
22034 killApplication(ps.name, ps.appId, userId, killReason);
22037 final PackageParser.Package p = mPackages.get(packageName);
22038 if (p != null && p.childPackages != null) {
22039 final int N = p.childPackages.size();
22040 mChildren = new PackageFreezer[N];
22041 for (int i = 0; i < N; i++) {
22042 mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
22043 userId, killReason);
22049 mCloseGuard.open("close");
22053 protected void finalize() throws Throwable {
22055 mCloseGuard.warnIfOpen();
22063 public void close() {
22064 mCloseGuard.close();
22065 if (mClosed.compareAndSet(false, true)) {
22066 synchronized (mPackages) {
22068 mFrozenPackages.remove(mPackageName);
22071 if (mChildren != null) {
22072 for (PackageFreezer freezer : mChildren) {
22082 * Verify that given package is currently frozen.
22084 private void checkPackageFrozen(String packageName) {
22085 synchronized (mPackages) {
22086 if (!mFrozenPackages.contains(packageName)) {
22087 Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
22093 public int movePackage(final String packageName, final String volumeUuid) {
22094 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22096 final UserHandle user = new UserHandle(UserHandle.getCallingUserId());
22097 final int moveId = mNextMoveId.getAndIncrement();
22098 mHandler.post(new Runnable() {
22100 public void run() {
22102 movePackageInternal(packageName, volumeUuid, moveId, user);
22103 } catch (PackageManagerException e) {
22104 Slog.w(TAG, "Failed to move " + packageName, e);
22105 mMoveCallbacks.notifyStatusChanged(moveId,
22106 PackageManager.MOVE_FAILED_INTERNAL_ERROR);
22113 private void movePackageInternal(final String packageName, final String volumeUuid,
22114 final int moveId, UserHandle user) throws PackageManagerException {
22115 final StorageManager storage = mContext.getSystemService(StorageManager.class);
22116 final PackageManager pm = mContext.getPackageManager();
22118 final boolean currentAsec;
22119 final String currentVolumeUuid;
22120 final File codeFile;
22121 final String installerPackageName;
22122 final String packageAbiOverride;
22124 final String seinfo;
22125 final String label;
22126 final int targetSdkVersion;
22127 final PackageFreezer freezer;
22128 final int[] installedUserIds;
22131 synchronized (mPackages) {
22132 final PackageParser.Package pkg = mPackages.get(packageName);
22133 final PackageSetting ps = mSettings.mPackages.get(packageName);
22134 if (pkg == null || ps == null) {
22135 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
22138 if (pkg.applicationInfo.isSystemApp()) {
22139 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
22140 "Cannot move system application");
22143 final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
22144 final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
22145 com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
22146 if (isInternalStorage && !allow3rdPartyOnInternal) {
22147 throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
22148 "3rd party apps are not allowed on internal storage");
22151 if (pkg.applicationInfo.isExternalAsec()) {
22152 currentAsec = true;
22153 currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
22154 } else if (pkg.applicationInfo.isForwardLocked()) {
22155 currentAsec = true;
22156 currentVolumeUuid = "forward_locked";
22158 currentAsec = false;
22159 currentVolumeUuid = ps.volumeUuid;
22161 final File probe = new File(pkg.codePath);
22162 final File probeOat = new File(probe, "oat");
22163 if (!probe.isDirectory() || !probeOat.isDirectory()) {
22164 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22165 "Move only supported for modern cluster style installs");
22169 if (Objects.equals(currentVolumeUuid, volumeUuid)) {
22170 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22171 "Package already moved to " + volumeUuid);
22173 if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
22174 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
22175 "Device admin cannot be moved");
22178 if (mFrozenPackages.contains(packageName)) {
22179 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
22180 "Failed to move already frozen package");
22183 codeFile = new File(pkg.codePath);
22184 installerPackageName = ps.installerPackageName;
22185 packageAbiOverride = ps.cpuAbiOverrideString;
22186 appId = UserHandle.getAppId(pkg.applicationInfo.uid);
22187 seinfo = pkg.applicationInfo.seInfo;
22188 label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
22189 targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
22190 freezer = freezePackage(packageName, "movePackageInternal");
22191 installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
22194 final Bundle extras = new Bundle();
22195 extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
22196 extras.putString(Intent.EXTRA_TITLE, label);
22197 mMoveCallbacks.notifyCreated(moveId, extras);
22200 final boolean moveCompleteApp;
22201 final File measurePath;
22203 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
22204 installFlags = INSTALL_INTERNAL;
22205 moveCompleteApp = !currentAsec;
22206 measurePath = Environment.getDataAppDirectory(volumeUuid);
22207 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
22208 installFlags = INSTALL_EXTERNAL;
22209 moveCompleteApp = false;
22210 measurePath = storage.getPrimaryPhysicalVolume().getPath();
22212 final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
22213 if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
22214 || !volume.isMountedWritable()) {
22216 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22217 "Move location not mounted private volume");
22220 Preconditions.checkState(!currentAsec);
22222 installFlags = INSTALL_INTERNAL;
22223 moveCompleteApp = true;
22224 measurePath = Environment.getDataAppDirectory(volumeUuid);
22227 final PackageStats stats = new PackageStats(null, -1);
22228 synchronized (mInstaller) {
22229 for (int userId : installedUserIds) {
22230 if (!getPackageSizeInfoLI(packageName, userId, stats)) {
22232 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22233 "Failed to measure package size");
22238 if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
22241 final long startFreeBytes = measurePath.getFreeSpace();
22242 final long sizeBytes;
22243 if (moveCompleteApp) {
22244 sizeBytes = stats.codeSize + stats.dataSize;
22246 sizeBytes = stats.codeSize;
22249 if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
22251 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22252 "Not enough free space to move");
22255 mMoveCallbacks.notifyStatusChanged(moveId, 10);
22257 final CountDownLatch installedLatch = new CountDownLatch(1);
22258 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
22260 public void onUserActionRequired(Intent intent) throws RemoteException {
22261 throw new IllegalStateException();
22265 public void onPackageInstalled(String basePackageName, int returnCode, String msg,
22266 Bundle extras) throws RemoteException {
22267 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
22268 + PackageManager.installStatusToString(returnCode, msg));
22270 installedLatch.countDown();
22273 final int status = PackageManager.installStatusToPublicStatus(returnCode);
22275 case PackageInstaller.STATUS_SUCCESS:
22276 mMoveCallbacks.notifyStatusChanged(moveId,
22277 PackageManager.MOVE_SUCCEEDED);
22279 case PackageInstaller.STATUS_FAILURE_STORAGE:
22280 mMoveCallbacks.notifyStatusChanged(moveId,
22281 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
22284 mMoveCallbacks.notifyStatusChanged(moveId,
22285 PackageManager.MOVE_FAILED_INTERNAL_ERROR);
22291 final MoveInfo move;
22292 if (moveCompleteApp) {
22293 // Kick off a thread to report progress estimates
22296 public void run() {
22299 if (installedLatch.await(1, TimeUnit.SECONDS)) {
22302 } catch (InterruptedException ignored) {
22305 final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace();
22306 final int progress = 10 + (int) MathUtils.constrain(
22307 ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
22308 mMoveCallbacks.notifyStatusChanged(moveId, progress);
22313 final String dataAppName = codeFile.getName();
22314 move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
22315 dataAppName, appId, seinfo, targetSdkVersion);
22320 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
22322 final Message msg = mHandler.obtainMessage(INIT_COPY);
22323 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
22324 final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
22325 installerPackageName, volumeUuid, null /*verificationInfo*/, user,
22326 packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/,
22327 PackageManager.INSTALL_REASON_UNKNOWN);
22328 params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
22331 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
22332 System.identityHashCode(msg.obj));
22333 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
22334 System.identityHashCode(msg.obj));
22336 mHandler.sendMessage(msg);
22340 public int movePrimaryStorage(String volumeUuid) throws RemoteException {
22341 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22343 final int realMoveId = mNextMoveId.getAndIncrement();
22344 final Bundle extras = new Bundle();
22345 extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
22346 mMoveCallbacks.notifyCreated(realMoveId, extras);
22348 final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
22350 public void onCreated(int moveId, Bundle extras) {
22355 public void onStatusChanged(int moveId, int status, long estMillis) {
22356 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
22360 final StorageManager storage = mContext.getSystemService(StorageManager.class);
22361 storage.setPrimaryStorageUuid(volumeUuid, callback);
22366 public int getMoveStatus(int moveId) {
22367 mContext.enforceCallingOrSelfPermission(
22368 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22369 return mMoveCallbacks.mLastStatus.get(moveId);
22373 public void registerMoveCallback(IPackageMoveObserver callback) {
22374 mContext.enforceCallingOrSelfPermission(
22375 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22376 mMoveCallbacks.register(callback);
22380 public void unregisterMoveCallback(IPackageMoveObserver callback) {
22381 mContext.enforceCallingOrSelfPermission(
22382 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22383 mMoveCallbacks.unregister(callback);
22387 public boolean setInstallLocation(int loc) {
22388 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
22390 if (getInstallLocation() == loc) {
22393 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
22394 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
22395 android.provider.Settings.Global.putInt(mContext.getContentResolver(),
22396 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
22403 public int getInstallLocation() {
22404 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
22405 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
22406 PackageHelper.APP_INSTALL_AUTO);
22409 /** Called by UserManagerService */
22410 void cleanUpUser(UserManagerService userManager, int userHandle) {
22411 synchronized (mPackages) {
22412 mDirtyUsers.remove(userHandle);
22413 mUserNeedsBadging.delete(userHandle);
22414 mSettings.removeUserLPw(userHandle);
22415 mPendingBroadcasts.remove(userHandle);
22416 mInstantAppRegistry.onUserRemovedLPw(userHandle);
22417 removeUnusedPackagesLPw(userManager, userHandle);
22422 * We're removing userHandle and would like to remove any downloaded packages
22423 * that are no longer in use by any other user.
22424 * @param userHandle the user being removed
22426 private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
22427 final boolean DEBUG_CLEAN_APKS = false;
22428 int [] users = userManager.getUserIds();
22429 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
22430 while (psit.hasNext()) {
22431 PackageSetting ps = psit.next();
22432 if (ps.pkg == null) {
22435 final String packageName = ps.pkg.packageName;
22436 // Skip over if system app
22437 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
22440 if (DEBUG_CLEAN_APKS) {
22441 Slog.i(TAG, "Checking package " + packageName);
22443 boolean keep = shouldKeepUninstalledPackageLPr(packageName);
22445 if (DEBUG_CLEAN_APKS) {
22446 Slog.i(TAG, " Keeping package " + packageName + " - requested by DO");
22449 for (int i = 0; i < users.length; i++) {
22450 if (users[i] != userHandle && ps.getInstalled(users[i])) {
22452 if (DEBUG_CLEAN_APKS) {
22453 Slog.i(TAG, " Keeping package " + packageName + " for user "
22461 if (DEBUG_CLEAN_APKS) {
22462 Slog.i(TAG, " Removing package " + packageName);
22464 mHandler.post(new Runnable() {
22465 public void run() {
22466 deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
22474 /** Called by UserManagerService */
22475 void createNewUser(int userId, String[] disallowedPackages) {
22476 synchronized (mInstallLock) {
22477 mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages);
22479 synchronized (mPackages) {
22480 scheduleWritePackageRestrictionsLocked(userId);
22481 scheduleWritePackageListLocked(userId);
22482 applyFactoryDefaultBrowserLPw(userId);
22483 primeDomainVerificationsLPw(userId);
22487 void onNewUserCreated(final int userId) {
22488 mDefaultPermissionPolicy.grantDefaultPermissions(userId);
22489 // If permission review for legacy apps is required, we represent
22490 // dagerous permissions for such apps as always granted runtime
22491 // permissions to keep per user flag state whether review is needed.
22492 // Hence, if a new user is added we have to propagate dangerous
22493 // permission grants for these legacy apps.
22494 if (mPermissionReviewRequired) {
22495 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
22496 | UPDATE_PERMISSIONS_REPLACE_ALL);
22501 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
22502 mContext.enforceCallingOrSelfPermission(
22503 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
22504 "Only package verification agents can read the verifier device identity");
22506 synchronized (mPackages) {
22507 return mSettings.getVerifierDeviceIdentityLPw();
22512 public void setPermissionEnforced(String permission, boolean enforced) {
22513 // TODO: Now that we no longer change GID for storage, this should to away.
22514 mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
22515 "setPermissionEnforced");
22516 if (READ_EXTERNAL_STORAGE.equals(permission)) {
22517 synchronized (mPackages) {
22518 if (mSettings.mReadExternalStorageEnforced == null
22519 || mSettings.mReadExternalStorageEnforced != enforced) {
22520 mSettings.mReadExternalStorageEnforced = enforced;
22521 mSettings.writeLPr();
22524 // kill any non-foreground processes so we restart them and
22525 // grant/revoke the GID.
22526 final IActivityManager am = ActivityManager.getService();
22528 final long token = Binder.clearCallingIdentity();
22530 am.killProcessesBelowForeground("setPermissionEnforcement");
22531 } catch (RemoteException e) {
22533 Binder.restoreCallingIdentity(token);
22537 throw new IllegalArgumentException("No selective enforcement for " + permission);
22543 public boolean isPermissionEnforced(String permission) {
22548 public boolean isStorageLow() {
22549 final long token = Binder.clearCallingIdentity();
22551 final DeviceStorageMonitorInternal
22552 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
22554 return dsm.isMemoryLow();
22559 Binder.restoreCallingIdentity(token);
22564 public IPackageInstaller getPackageInstaller() {
22565 return mInstallerService;
22568 private boolean userNeedsBadging(int userId) {
22569 int index = mUserNeedsBadging.indexOfKey(userId);
22571 final UserInfo userInfo;
22572 final long token = Binder.clearCallingIdentity();
22574 userInfo = sUserManager.getUserInfo(userId);
22576 Binder.restoreCallingIdentity(token);
22579 if (userInfo != null && userInfo.isManagedProfile()) {
22584 mUserNeedsBadging.put(userId, b);
22587 return mUserNeedsBadging.valueAt(index);
22591 public KeySet getKeySetByAlias(String packageName, String alias) {
22592 if (packageName == null || alias == null) {
22595 synchronized(mPackages) {
22596 final PackageParser.Package pkg = mPackages.get(packageName);
22598 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22599 throw new IllegalArgumentException("Unknown package: " + packageName);
22601 KeySetManagerService ksms = mSettings.mKeySetManagerService;
22602 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
22607 public KeySet getSigningKeySet(String packageName) {
22608 if (packageName == null) {
22611 synchronized(mPackages) {
22612 final PackageParser.Package pkg = mPackages.get(packageName);
22614 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22615 throw new IllegalArgumentException("Unknown package: " + packageName);
22617 if (pkg.applicationInfo.uid != Binder.getCallingUid()
22618 && Process.SYSTEM_UID != Binder.getCallingUid()) {
22619 throw new SecurityException("May not access signing KeySet of other apps.");
22621 KeySetManagerService ksms = mSettings.mKeySetManagerService;
22622 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
22627 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
22628 if (packageName == null || ks == null) {
22631 synchronized(mPackages) {
22632 final PackageParser.Package pkg = mPackages.get(packageName);
22634 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22635 throw new IllegalArgumentException("Unknown package: " + packageName);
22637 IBinder ksh = ks.getToken();
22638 if (ksh instanceof KeySetHandle) {
22639 KeySetManagerService ksms = mSettings.mKeySetManagerService;
22640 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
22647 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
22648 if (packageName == null || ks == null) {
22651 synchronized(mPackages) {
22652 final PackageParser.Package pkg = mPackages.get(packageName);
22654 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22655 throw new IllegalArgumentException("Unknown package: " + packageName);
22657 IBinder ksh = ks.getToken();
22658 if (ksh instanceof KeySetHandle) {
22659 KeySetManagerService ksms = mSettings.mKeySetManagerService;
22660 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
22666 private void deletePackageIfUnusedLPr(final String packageName) {
22667 PackageSetting ps = mSettings.mPackages.get(packageName);
22671 if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
22672 // TODO Implement atomic delete if package is unused
22673 // It is currently possible that the package will be deleted even if it is installed
22674 // after this method returns.
22675 mHandler.post(new Runnable() {
22676 public void run() {
22677 deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
22678 0, PackageManager.DELETE_ALL_USERS);
22685 * Check and throw if the given before/after packages would be considered a
22688 private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
22689 throws PackageManagerException {
22690 if (after.versionCode < before.mVersionCode) {
22691 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
22692 "Update version code " + after.versionCode + " is older than current "
22693 + before.mVersionCode);
22694 } else if (after.versionCode == before.mVersionCode) {
22695 if (after.baseRevisionCode < before.baseRevisionCode) {
22696 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
22697 "Update base revision code " + after.baseRevisionCode
22698 + " is older than current " + before.baseRevisionCode);
22701 if (!ArrayUtils.isEmpty(after.splitNames)) {
22702 for (int i = 0; i < after.splitNames.length; i++) {
22703 final String splitName = after.splitNames[i];
22704 final int j = ArrayUtils.indexOf(before.splitNames, splitName);
22706 if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
22707 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
22708 "Update split " + splitName + " revision code "
22709 + after.splitRevisionCodes[i] + " is older than current "
22710 + before.splitRevisionCodes[j]);
22718 private static class MoveCallbacks extends Handler {
22719 private static final int MSG_CREATED = 1;
22720 private static final int MSG_STATUS_CHANGED = 2;
22722 private final RemoteCallbackList<IPackageMoveObserver>
22723 mCallbacks = new RemoteCallbackList<>();
22725 private final SparseIntArray mLastStatus = new SparseIntArray();
22727 public MoveCallbacks(Looper looper) {
22731 public void register(IPackageMoveObserver callback) {
22732 mCallbacks.register(callback);
22735 public void unregister(IPackageMoveObserver callback) {
22736 mCallbacks.unregister(callback);
22740 public void handleMessage(Message msg) {
22741 final SomeArgs args = (SomeArgs) msg.obj;
22742 final int n = mCallbacks.beginBroadcast();
22743 for (int i = 0; i < n; i++) {
22744 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
22746 invokeCallback(callback, msg.what, args);
22747 } catch (RemoteException ignored) {
22750 mCallbacks.finishBroadcast();
22754 private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
22755 throws RemoteException {
22757 case MSG_CREATED: {
22758 callback.onCreated(args.argi1, (Bundle) args.arg2);
22761 case MSG_STATUS_CHANGED: {
22762 callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
22768 private void notifyCreated(int moveId, Bundle extras) {
22769 Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
22771 final SomeArgs args = SomeArgs.obtain();
22772 args.argi1 = moveId;
22773 args.arg2 = extras;
22774 obtainMessage(MSG_CREATED, args).sendToTarget();
22777 private void notifyStatusChanged(int moveId, int status) {
22778 notifyStatusChanged(moveId, status, -1);
22781 private void notifyStatusChanged(int moveId, int status, long estMillis) {
22782 Slog.v(TAG, "Move " + moveId + " status " + status);
22784 final SomeArgs args = SomeArgs.obtain();
22785 args.argi1 = moveId;
22786 args.argi2 = status;
22787 args.arg3 = estMillis;
22788 obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
22790 synchronized (mLastStatus) {
22791 mLastStatus.put(moveId, status);
22796 private final static class OnPermissionChangeListeners extends Handler {
22797 private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
22799 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
22800 new RemoteCallbackList<>();
22802 public OnPermissionChangeListeners(Looper looper) {
22807 public void handleMessage(Message msg) {
22808 switch (msg.what) {
22809 case MSG_ON_PERMISSIONS_CHANGED: {
22810 final int uid = msg.arg1;
22811 handleOnPermissionsChanged(uid);
22816 public void addListenerLocked(IOnPermissionsChangeListener listener) {
22817 mPermissionListeners.register(listener);
22821 public void removeListenerLocked(IOnPermissionsChangeListener listener) {
22822 mPermissionListeners.unregister(listener);
22825 public void onPermissionsChanged(int uid) {
22826 if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
22827 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
22831 private void handleOnPermissionsChanged(int uid) {
22832 final int count = mPermissionListeners.beginBroadcast();
22834 for (int i = 0; i < count; i++) {
22835 IOnPermissionsChangeListener callback = mPermissionListeners
22836 .getBroadcastItem(i);
22838 callback.onPermissionsChanged(uid);
22839 } catch (RemoteException e) {
22840 Log.e(TAG, "Permission listener is dead", e);
22844 mPermissionListeners.finishBroadcast();
22849 private class PackageManagerInternalImpl extends PackageManagerInternal {
22851 public void setLocationPackagesProvider(PackagesProvider provider) {
22852 synchronized (mPackages) {
22853 mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
22858 public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
22859 synchronized (mPackages) {
22860 mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
22865 public void setSmsAppPackagesProvider(PackagesProvider provider) {
22866 synchronized (mPackages) {
22867 mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
22872 public void setDialerAppPackagesProvider(PackagesProvider provider) {
22873 synchronized (mPackages) {
22874 mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
22879 public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
22880 synchronized (mPackages) {
22881 mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider);
22886 public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
22887 synchronized (mPackages) {
22888 mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider);
22893 public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
22894 synchronized (mPackages) {
22895 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
22896 packageName, userId);
22901 public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
22902 synchronized (mPackages) {
22903 mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
22904 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
22905 packageName, userId);
22910 public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
22911 synchronized (mPackages) {
22912 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr(
22913 packageName, userId);
22918 public void setKeepUninstalledPackages(final List<String> packageList) {
22919 Preconditions.checkNotNull(packageList);
22920 List<String> removedFromList = null;
22921 synchronized (mPackages) {
22922 if (mKeepUninstalledPackages != null) {
22923 final int packagesCount = mKeepUninstalledPackages.size();
22924 for (int i = 0; i < packagesCount; i++) {
22925 String oldPackage = mKeepUninstalledPackages.get(i);
22926 if (packageList != null && packageList.contains(oldPackage)) {
22929 if (removedFromList == null) {
22930 removedFromList = new ArrayList<>();
22932 removedFromList.add(oldPackage);
22935 mKeepUninstalledPackages = new ArrayList<>(packageList);
22936 if (removedFromList != null) {
22937 final int removedCount = removedFromList.size();
22938 for (int i = 0; i < removedCount; i++) {
22939 deletePackageIfUnusedLPr(removedFromList.get(i));
22946 public boolean isPermissionsReviewRequired(String packageName, int userId) {
22947 synchronized (mPackages) {
22948 // If we do not support permission review, done.
22949 if (!mPermissionReviewRequired) {
22953 PackageSetting packageSetting = mSettings.mPackages.get(packageName);
22954 if (packageSetting == null) {
22958 // Permission review applies only to apps not supporting the new permission model.
22959 if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
22963 // Legacy apps have the permission and get user consent on launch.
22964 PermissionsState permissionsState = packageSetting.getPermissionsState();
22965 return permissionsState.isPermissionReviewRequired(userId);
22970 public ApplicationInfo getApplicationInfo(String packageName, int userId) {
22971 return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId);
22975 public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
22977 return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
22981 public void setDeviceAndProfileOwnerPackages(
22982 int deviceOwnerUserId, String deviceOwnerPackage,
22983 SparseArray<String> profileOwnerPackages) {
22984 mProtectedPackages.setDeviceAndProfileOwnerPackages(
22985 deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
22989 public boolean isPackageDataProtected(int userId, String packageName) {
22990 return mProtectedPackages.isPackageDataProtected(userId, packageName);
22994 public boolean isPackageEphemeral(int userId, String packageName) {
22995 synchronized (mPackages) {
22996 final PackageSetting ps = mSettings.mPackages.get(packageName);
22997 return ps != null ? ps.getInstantApp(userId) : false;
23002 public boolean wasPackageEverLaunched(String packageName, int userId) {
23003 synchronized (mPackages) {
23004 return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
23009 public void grantRuntimePermission(String packageName, String name, int userId,
23010 boolean overridePolicy) {
23011 PackageManagerService.this.grantRuntimePermission(packageName, name, userId,
23016 public void revokeRuntimePermission(String packageName, String name, int userId,
23017 boolean overridePolicy) {
23018 PackageManagerService.this.revokeRuntimePermission(packageName, name, userId,
23023 public String getNameForUid(int uid) {
23024 return PackageManagerService.this.getNameForUid(uid);
23028 public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
23029 Intent origIntent, String resolvedType, String callingPackage, int userId) {
23030 PackageManagerService.this.requestInstantAppResolutionPhaseTwo(
23031 responseObj, origIntent, resolvedType, callingPackage, userId);
23035 public void grantEphemeralAccess(int userId, Intent intent,
23036 int targetAppId, int ephemeralAppId) {
23037 synchronized (mPackages) {
23038 mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
23039 targetAppId, ephemeralAppId);
23044 public boolean isInstantAppInstallerComponent(ComponentName component) {
23045 synchronized (mPackages) {
23046 return component != null && component.equals(mInstantAppInstallerComponent);
23051 public void pruneInstantApps() {
23052 synchronized (mPackages) {
23053 mInstantAppRegistry.pruneInstantAppsLPw();
23058 public String getSetupWizardPackageName() {
23059 return mSetupWizardPackage;
23062 public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
23063 if (policy != null) {
23064 mExternalSourcesPolicy = policy;
23069 public boolean isPackagePersistent(String packageName) {
23070 synchronized (mPackages) {
23071 PackageParser.Package pkg = mPackages.get(packageName);
23073 ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM
23074 | ApplicationInfo.FLAG_PERSISTENT)) ==
23075 (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT))
23081 public List<PackageInfo> getOverlayPackages(int userId) {
23082 final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
23083 synchronized (mPackages) {
23084 for (PackageParser.Package p : mPackages.values()) {
23085 if (p.mOverlayTarget != null) {
23086 PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
23088 overlayPackages.add(pkg);
23093 return overlayPackages;
23097 public List<String> getTargetPackageNames(int userId) {
23098 List<String> targetPackages = new ArrayList<>();
23099 synchronized (mPackages) {
23100 for (PackageParser.Package p : mPackages.values()) {
23101 if (p.mOverlayTarget == null) {
23102 targetPackages.add(p.packageName);
23106 return targetPackages;
23110 public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
23111 @Nullable List<String> overlayPackageNames) {
23112 synchronized (mPackages) {
23113 if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
23114 Slog.e(TAG, "failed to find package " + targetPackageName);
23118 ArrayList<String> paths = null;
23119 if (overlayPackageNames != null) {
23120 final int N = overlayPackageNames.size();
23121 paths = new ArrayList<>(N);
23122 for (int i = 0; i < N; i++) {
23123 final String packageName = overlayPackageNames.get(i);
23124 final PackageParser.Package pkg = mPackages.get(packageName);
23126 Slog.e(TAG, "failed to find package " + packageName);
23129 paths.add(pkg.baseCodePath);
23133 ArrayMap<String, ArrayList<String>> userSpecificOverlays =
23134 mEnabledOverlayPaths.get(userId);
23135 if (userSpecificOverlays == null) {
23136 userSpecificOverlays = new ArrayMap<>();
23137 mEnabledOverlayPaths.put(userId, userSpecificOverlays);
23140 if (paths != null && paths.size() > 0) {
23141 userSpecificOverlays.put(targetPackageName, paths);
23143 userSpecificOverlays.remove(targetPackageName);
23149 public ResolveInfo resolveIntent(Intent intent, String resolvedType,
23150 int flags, int userId) {
23151 return resolveIntentInternal(
23152 intent, resolvedType, flags, userId, true /*includeInstantApp*/);
23157 public void addIsolatedUid(int isolatedUid, int ownerUid) {
23158 synchronized (mPackages) {
23159 mIsolatedOwners.put(isolatedUid, ownerUid);
23164 public void removeIsolatedUid(int isolatedUid) {
23165 synchronized (mPackages) {
23166 mIsolatedOwners.delete(isolatedUid);
23172 public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
23173 enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
23174 synchronized (mPackages) {
23175 final long identity = Binder.clearCallingIdentity();
23177 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
23178 packageNames, userId);
23180 Binder.restoreCallingIdentity(identity);
23186 public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
23187 enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
23188 synchronized (mPackages) {
23189 final long identity = Binder.clearCallingIdentity();
23191 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServicesLPr(
23192 packageNames, userId);
23194 Binder.restoreCallingIdentity(identity);
23199 private static void enforceSystemOrPhoneCaller(String tag) {
23200 int callingUid = Binder.getCallingUid();
23201 if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
23202 throw new SecurityException(
23203 "Cannot call " + tag + " from UID " + callingUid);
23207 boolean isHistoricalPackageUsageAvailable() {
23208 return mPackageUsage.isHistoricalPackageUsageAvailable();
23212 * Return a <b>copy</b> of the collection of packages known to the package manager.
23213 * @return A copy of the values of mPackages.
23215 Collection<PackageParser.Package> getPackages() {
23216 synchronized (mPackages) {
23217 return new ArrayList<>(mPackages.values());
23222 * Logs process start information (including base APK hash) to the security log.
23225 public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
23226 String apkFile, int pid) {
23227 if (!SecurityLog.isLoggingEnabled()) {
23230 Bundle data = new Bundle();
23231 data.putLong("startTimestamp", System.currentTimeMillis());
23232 data.putString("processName", processName);
23233 data.putInt("uid", uid);
23234 data.putString("seinfo", seinfo);
23235 data.putString("apkFile", apkFile);
23236 data.putInt("pid", pid);
23237 Message msg = mProcessLoggingHandler.obtainMessage(
23238 ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
23240 mProcessLoggingHandler.sendMessage(msg);
23243 public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
23244 return mCompilerStats.getPackageStats(pkgName);
23247 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
23248 return getOrCreateCompilerPackageStats(pkg.packageName);
23251 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
23252 return mCompilerStats.getOrCreatePackageStats(pkgName);
23255 public void deleteCompilerPackageStats(String pkgName) {
23256 mCompilerStats.deletePackageStats(pkgName);
23260 public int getInstallReason(String packageName, int userId) {
23261 enforceCrossUserPermission(Binder.getCallingUid(), userId,
23262 true /* requireFullPermission */, false /* checkShell */,
23263 "get install reason");
23264 synchronized (mPackages) {
23265 final PackageSetting ps = mSettings.mPackages.get(packageName);
23267 return ps.getInstallReason(userId);
23270 return PackageManager.INSTALL_REASON_UNKNOWN;
23274 public boolean canRequestPackageInstalls(String packageName, int userId) {
23275 int callingUid = Binder.getCallingUid();
23276 int uid = getPackageUid(packageName, 0, userId);
23277 if (callingUid != uid && callingUid != Process.ROOT_UID
23278 && callingUid != Process.SYSTEM_UID) {
23279 throw new SecurityException(
23280 "Caller uid " + callingUid + " does not own package " + packageName);
23282 ApplicationInfo info = getApplicationInfo(packageName, 0, userId);
23283 if (info == null) {
23286 if (info.targetSdkVersion < Build.VERSION_CODES.O) {
23287 throw new UnsupportedOperationException(
23288 "Operation only supported on apps targeting Android O or higher");
23290 String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
23291 String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission);
23292 if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
23293 throw new SecurityException("Need to declare " + appOpPermission + " to call this api");
23295 if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) {
23298 if (mExternalSourcesPolicy != null) {
23299 int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
23300 if (isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_DEFAULT) {
23301 return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
23304 return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED;
23308 public ComponentName getInstantAppResolverSettingsComponent() {
23309 return mInstantAppResolverSettingsComponent;