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.InstructionSets.getAppDexInstructionSets;
94 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
95 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
96 import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
97 import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
98 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
99 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getFullCompilerFilter;
100 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getNonProfileGuidedCompilerFilter;
101 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
102 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
103 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
105 import android.Manifest;
106 import android.annotation.NonNull;
107 import android.annotation.Nullable;
108 import android.app.ActivityManager;
109 import android.app.AppOpsManager;
110 import android.app.IActivityManager;
111 import android.app.ResourcesManager;
112 import android.app.admin.IDevicePolicyManager;
113 import android.app.admin.SecurityLog;
114 import android.app.backup.IBackupManager;
115 import android.content.BroadcastReceiver;
116 import android.content.ComponentName;
117 import android.content.ContentResolver;
118 import android.content.Context;
119 import android.content.IIntentReceiver;
120 import android.content.Intent;
121 import android.content.IntentFilter;
122 import android.content.IntentSender;
123 import android.content.IntentSender.SendIntentException;
124 import android.content.ServiceConnection;
125 import android.content.pm.ActivityInfo;
126 import android.content.pm.ApplicationInfo;
127 import android.content.pm.AppsQueryHelper;
128 import android.content.pm.ChangedPackages;
129 import android.content.pm.ComponentInfo;
130 import android.content.pm.InstantAppRequest;
131 import android.content.pm.AuxiliaryResolveInfo;
132 import android.content.pm.FallbackCategoryProvider;
133 import android.content.pm.FeatureInfo;
134 import android.content.pm.IOnPermissionsChangeListener;
135 import android.content.pm.IPackageDataObserver;
136 import android.content.pm.IPackageDeleteObserver;
137 import android.content.pm.IPackageDeleteObserver2;
138 import android.content.pm.IPackageInstallObserver2;
139 import android.content.pm.IPackageInstaller;
140 import android.content.pm.IPackageManager;
141 import android.content.pm.IPackageMoveObserver;
142 import android.content.pm.IPackageStatsObserver;
143 import android.content.pm.InstantAppInfo;
144 import android.content.pm.InstantAppResolveInfo;
145 import android.content.pm.InstrumentationInfo;
146 import android.content.pm.IntentFilterVerificationInfo;
147 import android.content.pm.KeySet;
148 import android.content.pm.PackageCleanItem;
149 import android.content.pm.PackageInfo;
150 import android.content.pm.PackageInfoLite;
151 import android.content.pm.PackageInstaller;
152 import android.content.pm.PackageManager;
153 import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
154 import android.content.pm.PackageManagerInternal;
155 import android.content.pm.PackageParser;
156 import android.content.pm.PackageParser.ActivityIntentInfo;
157 import android.content.pm.PackageParser.PackageLite;
158 import android.content.pm.PackageParser.PackageParserException;
159 import android.content.pm.PackageStats;
160 import android.content.pm.PackageUserState;
161 import android.content.pm.ParceledListSlice;
162 import android.content.pm.PermissionGroupInfo;
163 import android.content.pm.PermissionInfo;
164 import android.content.pm.ProviderInfo;
165 import android.content.pm.ResolveInfo;
166 import android.content.pm.ServiceInfo;
167 import android.content.pm.SharedLibraryInfo;
168 import android.content.pm.Signature;
169 import android.content.pm.UserInfo;
170 import android.content.pm.VerifierDeviceIdentity;
171 import android.content.pm.VerifierInfo;
172 import android.content.pm.VersionedPackage;
173 import android.content.res.Resources;
174 import android.database.ContentObserver;
175 import android.graphics.Bitmap;
176 import android.hardware.display.DisplayManager;
177 import android.net.Uri;
178 import android.os.Binder;
179 import android.os.Build;
180 import android.os.Bundle;
181 import android.os.Debug;
182 import android.os.Environment;
183 import android.os.Environment.UserEnvironment;
184 import android.os.FileUtils;
185 import android.os.Handler;
186 import android.os.IBinder;
187 import android.os.Looper;
188 import android.os.Message;
189 import android.os.Parcel;
190 import android.os.ParcelFileDescriptor;
191 import android.os.PatternMatcher;
192 import android.os.Process;
193 import android.os.RemoteCallbackList;
194 import android.os.RemoteException;
195 import android.os.ResultReceiver;
196 import android.os.SELinux;
197 import android.os.ServiceManager;
198 import android.os.ShellCallback;
199 import android.os.SystemClock;
200 import android.os.SystemProperties;
201 import android.os.Trace;
202 import android.os.UserHandle;
203 import android.os.UserManager;
204 import android.os.UserManagerInternal;
205 import android.os.storage.IStorageManager;
206 import android.os.storage.StorageEventListener;
207 import android.os.storage.StorageManager;
208 import android.os.storage.StorageManagerInternal;
209 import android.os.storage.VolumeInfo;
210 import android.os.storage.VolumeRecord;
211 import android.provider.Settings.Global;
212 import android.provider.Settings.Secure;
213 import android.security.KeyStore;
214 import android.security.SystemKeyStore;
215 import android.service.pm.PackageServiceDumpProto;
216 import android.system.ErrnoException;
217 import android.system.Os;
218 import android.text.TextUtils;
219 import android.text.format.DateUtils;
220 import android.util.ArrayMap;
221 import android.util.ArraySet;
222 import android.util.Base64;
223 import android.util.BootTimingsTraceLog;
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.DumpUtils;
258 import com.android.internal.util.FastPrintWriter;
259 import com.android.internal.util.FastXmlSerializer;
260 import com.android.internal.util.IndentingPrintWriter;
261 import com.android.internal.util.Preconditions;
262 import com.android.internal.util.XmlUtils;
263 import com.android.server.AttributeCache;
264 import com.android.server.DeviceIdleController;
265 import com.android.server.EventLogTags;
266 import com.android.server.FgThread;
267 import com.android.server.IntentResolver;
268 import com.android.server.LocalServices;
269 import com.android.server.LockGuard;
270 import com.android.server.ServiceThread;
271 import com.android.server.SystemConfig;
272 import com.android.server.SystemServerInitThreadPool;
273 import com.android.server.Watchdog;
274 import com.android.server.net.NetworkPolicyManagerInternal;
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.FileOutputStream;
301 import java.io.FileReader;
302 import java.io.FilenameFilter;
303 import java.io.IOException;
304 import java.io.PrintWriter;
305 import java.nio.charset.StandardCharsets;
306 import java.security.DigestInputStream;
307 import java.security.MessageDigest;
308 import java.security.NoSuchAlgorithmException;
309 import java.security.PublicKey;
310 import java.security.SecureRandom;
311 import java.security.cert.Certificate;
312 import java.security.cert.CertificateEncodingException;
313 import java.security.cert.CertificateException;
314 import java.text.SimpleDateFormat;
315 import java.util.ArrayList;
316 import java.util.Arrays;
317 import java.util.Collection;
318 import java.util.Collections;
319 import java.util.Comparator;
320 import java.util.Date;
321 import java.util.HashMap;
322 import java.util.HashSet;
323 import java.util.Iterator;
324 import java.util.List;
325 import java.util.Map;
326 import java.util.Objects;
327 import java.util.Set;
328 import java.util.concurrent.CountDownLatch;
329 import java.util.concurrent.Future;
330 import java.util.concurrent.TimeUnit;
331 import java.util.concurrent.atomic.AtomicBoolean;
332 import java.util.concurrent.atomic.AtomicInteger;
335 * Keep track of all those APKs everywhere.
337 * Internally there are two important locks:
339 * <li>{@link #mPackages} is used to guard all in-memory parsed package details
340 * and other related state. It is a fine-grained lock that should only be held
341 * momentarily, as it's one of the most contended locks in the system.
342 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
343 * operations typically involve heavy lifting of application data on disk. Since
344 * {@code installd} is single-threaded, and it's operations can often be slow,
345 * this lock should never be acquired while already holding {@link #mPackages}.
346 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
347 * holding {@link #mInstallLock}.
349 * Many internal methods rely on the caller to hold the appropriate locks, and
350 * this contract is expressed through method name suffixes:
352 * <li>fooLI(): the caller must hold {@link #mInstallLock}
353 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
354 * being modified must be frozen
355 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
356 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
359 * Because this class is very central to the platform's security; please run all
360 * CTS and unit tests whenever making modifications:
363 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
364 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
367 public class PackageManagerService extends IPackageManager.Stub
368 implements PackageSender {
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 HIDE_EPHEMERAL_APIS = false;
400 private static final boolean ENABLE_FREE_CACHE_V2 =
401 SystemProperties.getBoolean("fw.free_cache_v2", true);
403 private static final int RADIO_UID = Process.PHONE_UID;
404 private static final int LOG_UID = Process.LOG_UID;
405 private static final int NFC_UID = Process.NFC_UID;
406 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
407 private static final int SHELL_UID = Process.SHELL_UID;
409 // Cap the size of permission trees that 3rd party apps can define
410 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768; // characters of text
412 // Suffix used during package installation when copying/moving
413 // package apks to install directory.
414 private static final String INSTALL_PACKAGE_SUFFIX = "-";
416 static final int SCAN_NO_DEX = 1<<1;
417 static final int SCAN_FORCE_DEX = 1<<2;
418 static final int SCAN_UPDATE_SIGNATURE = 1<<3;
419 static final int SCAN_NEW_INSTALL = 1<<4;
420 static final int SCAN_UPDATE_TIME = 1<<5;
421 static final int SCAN_BOOTING = 1<<6;
422 static final int SCAN_TRUSTED_OVERLAY = 1<<7;
423 static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<8;
424 static final int SCAN_REPLACING = 1<<9;
425 static final int SCAN_REQUIRE_KNOWN = 1<<10;
426 static final int SCAN_MOVE = 1<<11;
427 static final int SCAN_INITIAL = 1<<12;
428 static final int SCAN_CHECK_ONLY = 1<<13;
429 static final int SCAN_DONT_KILL_APP = 1<<14;
430 static final int SCAN_IGNORE_FROZEN = 1<<15;
431 static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<16;
432 static final int SCAN_AS_INSTANT_APP = 1<<17;
433 static final int SCAN_AS_FULL_APP = 1<<18;
434 /** Should not be with the scan flags */
435 static final int FLAGS_REMOVE_CHATTY = 1<<31;
437 private static final String STATIC_SHARED_LIB_DELIMITER = "_";
439 private static final int[] EMPTY_INT_ARRAY = new int[0];
442 * Timeout (in milliseconds) after which the watchdog should declare that
443 * our handler thread is wedged. The usual default for such things is one
444 * minute but we sometimes do very lengthy I/O operations on this thread,
445 * such as installing multi-gigabyte applications, so ours needs to be longer.
447 private static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes
450 * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
451 * be run on this device. We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
452 * settings entry if available, otherwise we use the hardcoded default. If it's been
453 * more than this long since the last fstrim, we force one during the boot sequence.
455 * This backstops other fstrim scheduling: if the device is alive at midnight+idle,
456 * one gets run at the next available charging+idle time. This final mandatory
457 * no-fstrim check kicks in only of the other scheduling criteria is never met.
459 private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
462 * Whether verification is enabled by default.
464 private static final boolean DEFAULT_VERIFY_ENABLE = true;
467 * The default maximum time to wait for the verification agent to return in
470 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
473 * The default response for package verification timeout.
475 * This can be either PackageManager.VERIFICATION_ALLOW or
476 * PackageManager.VERIFICATION_REJECT.
478 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
480 static final String PLATFORM_PACKAGE_NAME = "android";
482 static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
484 static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
485 DEFAULT_CONTAINER_PACKAGE,
486 "com.android.defcontainer.DefaultContainerService");
488 private static final String KILL_APP_REASON_GIDS_CHANGED =
489 "permission grant or revoke changed gids";
491 private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
492 "permissions revoked";
494 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
496 private static final String PACKAGE_SCHEME = "package";
498 private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
500 /** Permission grant: not grant the permission. */
501 private static final int GRANT_DENIED = 1;
503 /** Permission grant: grant the permission as an install permission. */
504 private static final int GRANT_INSTALL = 2;
506 /** Permission grant: grant the permission as a runtime one. */
507 private static final int GRANT_RUNTIME = 3;
509 /** Permission grant: grant as runtime a permission that was granted as an install time one. */
510 private static final int GRANT_UPGRADE = 4;
512 /** Canonical intent used to identify what counts as a "web browser" app */
513 private static final Intent sBrowserIntent;
515 sBrowserIntent = new Intent();
516 sBrowserIntent.setAction(Intent.ACTION_VIEW);
517 sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
518 sBrowserIntent.setData(Uri.parse("http:"));
522 * The set of all protected actions [i.e. those actions for which a high priority
523 * intent filter is disallowed].
525 private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
527 PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
528 PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
529 PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
530 PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
533 // Compilation reasons.
534 public static final int REASON_FIRST_BOOT = 0;
535 public static final int REASON_BOOT = 1;
536 public static final int REASON_INSTALL = 2;
537 public static final int REASON_BACKGROUND_DEXOPT = 3;
538 public static final int REASON_AB_OTA = 4;
539 public static final int REASON_FORCED_DEXOPT = 5;
541 public static final int REASON_LAST = REASON_FORCED_DEXOPT;
543 /** All dangerous permission names in the same order as the events in MetricsEvent */
544 private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList(
545 Manifest.permission.READ_CALENDAR,
546 Manifest.permission.WRITE_CALENDAR,
547 Manifest.permission.CAMERA,
548 Manifest.permission.READ_CONTACTS,
549 Manifest.permission.WRITE_CONTACTS,
550 Manifest.permission.GET_ACCOUNTS,
551 Manifest.permission.ACCESS_FINE_LOCATION,
552 Manifest.permission.ACCESS_COARSE_LOCATION,
553 Manifest.permission.RECORD_AUDIO,
554 Manifest.permission.READ_PHONE_STATE,
555 Manifest.permission.CALL_PHONE,
556 Manifest.permission.READ_CALL_LOG,
557 Manifest.permission.WRITE_CALL_LOG,
558 Manifest.permission.ADD_VOICEMAIL,
559 Manifest.permission.USE_SIP,
560 Manifest.permission.PROCESS_OUTGOING_CALLS,
561 Manifest.permission.READ_CELL_BROADCASTS,
562 Manifest.permission.BODY_SENSORS,
563 Manifest.permission.SEND_SMS,
564 Manifest.permission.RECEIVE_SMS,
565 Manifest.permission.READ_SMS,
566 Manifest.permission.RECEIVE_WAP_PUSH,
567 Manifest.permission.RECEIVE_MMS,
568 Manifest.permission.READ_EXTERNAL_STORAGE,
569 Manifest.permission.WRITE_EXTERNAL_STORAGE,
570 Manifest.permission.READ_PHONE_NUMBERS,
571 Manifest.permission.ANSWER_PHONE_CALLS);
575 * Version number for the package parser cache. Increment this whenever the format or
576 * extent of cached data changes. See {@code PackageParser#setCacheDir}.
578 private static final String PACKAGE_PARSER_CACHE_VERSION = "1";
581 * Whether the package parser cache is enabled.
583 private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
585 final ServiceThread mHandlerThread;
587 final PackageHandler mHandler;
589 private final ProcessLoggingHandler mProcessLoggingHandler;
592 * Messages for {@link #mHandler} that need to wait for system ready before
595 private ArrayList<Message> mPostSystemReadyMessages;
597 final int mSdkVersion = Build.VERSION.SDK_INT;
599 final Context mContext;
600 final boolean mFactoryTest;
601 final boolean mOnlyCore;
602 final DisplayMetrics mMetrics;
603 final int mDefParseFlags;
604 final String[] mSeparateProcesses;
605 final boolean mIsUpgrade;
606 final boolean mIsPreNUpgrade;
607 final boolean mIsPreNMR1Upgrade;
609 // Have we told the Activity Manager to whitelist the default container service by uid yet?
610 @GuardedBy("mPackages")
611 boolean mDefaultContainerWhitelisted = false;
613 @GuardedBy("mPackages")
614 private boolean mDexOptDialogShown;
616 /** The location for ASEC container files on internal storage. */
617 final String mAsecInternalPath;
619 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
620 // LOCK HELD. Can be called with mInstallLock held.
621 @GuardedBy("mInstallLock")
622 final Installer mInstaller;
624 /** Directory where installed third-party apps stored */
625 final File mAppInstallDir;
628 * Directory to which applications installed internally have their
629 * 32 bit native libraries copied.
631 private File mAppLib32InstallDir;
633 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
635 final File mDrmAppPrivateInstallDir;
637 // ----------------------------------------------------------------
639 // Lock for state used when installing and doing other long running
640 // operations. Methods that must be called with this lock held have
642 final Object mInstallLock = new Object();
644 // ----------------------------------------------------------------
646 // Keys are String (package name), values are Package. This also serves
647 // as the lock for the global state. Methods that must be called with
648 // this lock held have the prefix "LP".
649 @GuardedBy("mPackages")
650 final ArrayMap<String, PackageParser.Package> mPackages =
651 new ArrayMap<String, PackageParser.Package>();
653 final ArrayMap<String, Set<String>> mKnownCodebase =
654 new ArrayMap<String, Set<String>>();
656 // Keys are isolated uids and values are the uid of the application
657 // that created the isolated proccess.
658 @GuardedBy("mPackages")
659 final SparseIntArray mIsolatedOwners = new SparseIntArray();
661 // List of APK paths to load for each user and package. This data is never
662 // persisted by the package manager. Instead, the overlay manager will
663 // ensure the data is up-to-date in runtime.
664 @GuardedBy("mPackages")
665 final SparseArray<ArrayMap<String, ArrayList<String>>> mEnabledOverlayPaths =
666 new SparseArray<ArrayMap<String, ArrayList<String>>>();
669 * Tracks new system packages [received in an OTA] that we expect to
670 * find updated user-installed versions. Keys are package name, values
671 * are package location.
673 final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
675 * Tracks high priority intent filters for protected actions. During boot, certain
676 * filter actions are protected and should never be allowed to have a high priority
677 * intent filter for them. However, there is one, and only one exception -- the
678 * setup wizard. It must be able to define a high priority intent filter for these
679 * actions to ensure there are no escapes from the wizard. We need to delay processing
680 * of these during boot as we need to look at all of the system packages in order
681 * to know which component is the setup wizard.
683 private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
685 * Whether or not processing protected filters should be deferred.
687 private boolean mDeferProtectedFilters = true;
690 * Tracks existing system packages prior to receiving an OTA. Keys are package name.
692 final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
694 * Whether or not system app permissions should be promoted from install to runtime.
696 boolean mPromoteSystemApps;
698 @GuardedBy("mPackages")
699 final Settings mSettings;
702 * Set of package names that are currently "frozen", which means active
703 * surgery is being done on the code/data for that package. The platform
704 * will refuse to launch frozen packages to avoid race conditions.
706 * @see PackageFreezer
708 @GuardedBy("mPackages")
709 final ArraySet<String> mFrozenPackages = new ArraySet<>();
711 final ProtectedPackages mProtectedPackages;
715 PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
717 // System configuration read by SystemConfig.
718 final int[] mGlobalGids;
719 final SparseArray<ArraySet<String>> mSystemPermissions;
720 @GuardedBy("mAvailableFeatures")
721 final ArrayMap<String, FeatureInfo> mAvailableFeatures;
723 // If mac_permissions.xml was found for seinfo labeling.
724 boolean mFoundPolicyFile;
726 private final InstantAppRegistry mInstantAppRegistry;
728 @GuardedBy("mPackages")
729 int mChangedPackagesSequenceNumber;
731 * List of changed [installed, removed or updated] packages.
732 * mapping from user id -> sequence number -> package name
734 @GuardedBy("mPackages")
735 final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>();
737 * The sequence number of the last change to a package.
738 * mapping from user id -> package name -> sequence number
740 @GuardedBy("mPackages")
741 final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
743 final PackageParser.Callback mPackageParserCallback = new PackageParser.Callback() {
744 @Override public boolean hasFeature(String feature) {
745 return PackageManagerService.this.hasSystemFeature(feature, 0);
749 public static final class SharedLibraryEntry {
750 public final String path;
751 public final String apk;
752 public final SharedLibraryInfo info;
754 SharedLibraryEntry(String _path, String _apk, String name, int version, int type,
755 String declaringPackageName, int declaringPackageVersionCode) {
758 info = new SharedLibraryInfo(name, version, type, new VersionedPackage(
759 declaringPackageName, declaringPackageVersionCode), null);
763 // Currently known shared libraries.
764 final ArrayMap<String, SparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>();
765 final ArrayMap<String, SparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage =
768 // All available activities, for your resolving pleasure.
769 final ActivityIntentResolver mActivities =
770 new ActivityIntentResolver();
772 // All available receivers, for your resolving pleasure.
773 final ActivityIntentResolver mReceivers =
774 new ActivityIntentResolver();
776 // All available services, for your resolving pleasure.
777 final ServiceIntentResolver mServices = new ServiceIntentResolver();
779 // All available providers, for your resolving pleasure.
780 final ProviderIntentResolver mProviders = new ProviderIntentResolver();
782 // Mapping from provider base names (first directory in content URI codePath)
783 // to the provider information.
784 final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
785 new ArrayMap<String, PackageParser.Provider>();
787 // Mapping from instrumentation class names to info about them.
788 final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
789 new ArrayMap<ComponentName, PackageParser.Instrumentation>();
791 // Mapping from permission names to info about them.
792 final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
793 new ArrayMap<String, PackageParser.PermissionGroup>();
795 // Packages whose data we have transfered into another package, thus
796 // should no longer exist.
797 final ArraySet<String> mTransferedPackages = new ArraySet<String>();
799 // Broadcast actions that are only available to the system.
800 final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>();
802 /** List of packages waiting for verification. */
803 final SparseArray<PackageVerificationState> mPendingVerification
804 = new SparseArray<PackageVerificationState>();
806 /** Set of packages associated with each app op permission. */
807 final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
809 final PackageInstallerService mInstallerService;
811 private final PackageDexOptimizer mPackageDexOptimizer;
812 // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
813 // is used by other apps).
814 private final DexManager mDexManager;
816 private AtomicInteger mNextMoveId = new AtomicInteger();
817 private final MoveCallbacks mMoveCallbacks;
819 private final OnPermissionChangeListeners mOnPermissionChangeListeners;
821 // Cache of users who need badging.
822 SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
824 /** Token for keys in mPendingVerification. */
825 private int mPendingVerificationToken = 0;
827 volatile boolean mSystemReady;
828 volatile boolean mSafeMode;
829 volatile boolean mHasSystemUidErrors;
830 private volatile boolean mEphemeralAppsDisabled;
832 ApplicationInfo mAndroidApplication;
833 final ActivityInfo mResolveActivity = new ActivityInfo();
834 final ResolveInfo mResolveInfo = new ResolveInfo();
835 ComponentName mResolveComponentName;
836 PackageParser.Package mPlatformPackage;
837 ComponentName mCustomResolverComponentName;
839 boolean mResolverReplaced = false;
841 private final @Nullable ComponentName mIntentFilterVerifierComponent;
842 private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
844 private int mIntentFilterVerificationToken = 0;
846 /** The service connection to the ephemeral resolver */
847 final EphemeralResolverConnection mInstantAppResolverConnection;
848 /** Component used to show resolver settings for Instant Apps */
849 final ComponentName mInstantAppResolverSettingsComponent;
851 /** Activity used to install instant applications */
852 ActivityInfo mInstantAppInstallerActivity;
853 final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
855 final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
856 = new SparseArray<IntentFilterVerificationState>();
858 final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
860 // List of packages names to keep cached, even if they are uninstalled for all users
861 private List<String> mKeepUninstalledPackages;
863 private UserManagerInternal mUserManagerInternal;
865 private DeviceIdleController.LocalService mDeviceIdleController;
867 private File mCacheDir;
869 private ArraySet<String> mPrivappPermissionsViolations;
871 private Future<?> mPrepareAppDataFuture;
873 private static class IFVerificationParams {
874 PackageParser.Package pkg;
879 public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
880 int _userId, int _verifierUid) {
882 replacing = _replacing;
884 replacing = _replacing;
885 verifierUid = _verifierUid;
889 private interface IntentFilterVerifier<T extends IntentFilter> {
890 boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
891 T filter, String packageName);
892 void startVerifications(int userId);
893 void receiveVerificationResponse(int verificationId);
896 private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
897 private Context mContext;
898 private ComponentName mIntentFilterVerifierComponent;
899 private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
901 public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
903 mIntentFilterVerifierComponent = verifierComponent;
906 private String getDefaultScheme() {
907 return IntentFilter.SCHEME_HTTPS;
911 public void startVerifications(int userId) {
912 // Launch verifications requests
913 int count = mCurrentIntentFilterVerifications.size();
914 for (int n=0; n<count; n++) {
915 int verificationId = mCurrentIntentFilterVerifications.get(n);
916 final IntentFilterVerificationState ivs =
917 mIntentFilterVerificationStates.get(verificationId);
919 String packageName = ivs.getPackageName();
921 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
922 final int filterCount = filters.size();
923 ArraySet<String> domainsSet = new ArraySet<>();
924 for (int m=0; m<filterCount; m++) {
925 PackageParser.ActivityIntentInfo filter = filters.get(m);
926 domainsSet.addAll(filter.getHostsList());
928 synchronized (mPackages) {
929 if (mSettings.createIntentFilterVerificationIfNeededLPw(
930 packageName, domainsSet) != null) {
931 scheduleWriteSettingsLocked();
934 sendVerificationRequest(userId, verificationId, ivs);
936 mCurrentIntentFilterVerifications.clear();
939 private void sendVerificationRequest(int userId, int verificationId,
940 IntentFilterVerificationState ivs) {
942 Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
943 verificationIntent.putExtra(
944 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
946 verificationIntent.putExtra(
947 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
949 verificationIntent.putExtra(
950 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
951 ivs.getHostsString());
952 verificationIntent.putExtra(
953 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
954 ivs.getPackageName());
955 verificationIntent.setComponent(mIntentFilterVerifierComponent);
956 verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
958 UserHandle user = new UserHandle(userId);
959 mContext.sendBroadcastAsUser(verificationIntent, user);
960 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
961 "Sending IntentFilter verification broadcast");
964 public void receiveVerificationResponse(int verificationId) {
965 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
967 final boolean verified = ivs.isVerified();
969 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
970 final int count = filters.size();
971 if (DEBUG_DOMAIN_VERIFICATION) {
972 Slog.i(TAG, "Received verification response " + verificationId
973 + " for " + count + " filters, verified=" + verified);
975 for (int n=0; n<count; n++) {
976 PackageParser.ActivityIntentInfo filter = filters.get(n);
977 filter.setVerified(verified);
979 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
980 + " verified with result:" + verified + " and hosts:"
981 + ivs.getHostsString());
984 mIntentFilterVerificationStates.remove(verificationId);
986 final String packageName = ivs.getPackageName();
987 IntentFilterVerificationInfo ivi = null;
989 synchronized (mPackages) {
990 ivi = mSettings.getIntentFilterVerificationLPr(packageName);
993 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
994 + verificationId + " packageName:" + packageName);
997 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
998 "Updating IntentFilterVerificationInfo for package " + packageName
999 +" verificationId:" + verificationId);
1001 synchronized (mPackages) {
1003 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
1005 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
1007 scheduleWriteSettingsLocked();
1009 final int userId = ivs.getUserId();
1010 if (userId != UserHandle.USER_ALL) {
1011 final int userStatus =
1012 mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
1014 int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1015 boolean needUpdate = false;
1017 // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
1018 // already been set by the User thru the Disambiguation dialog
1019 switch (userStatus) {
1020 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
1022 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1024 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
1029 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
1031 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1041 mSettings.updateIntentFilterVerificationStatusLPw(
1042 packageName, updatedStatus, userId);
1043 scheduleWritePackageRestrictionsLocked(userId);
1050 public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
1051 ActivityIntentInfo filter, String packageName) {
1052 if (!hasValidDomains(filter)) {
1055 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1057 ivs = createDomainVerificationState(verifierUid, userId, verificationId,
1060 if (DEBUG_DOMAIN_VERIFICATION) {
1061 Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
1063 ivs.addFilter(filter);
1067 private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
1068 int userId, int verificationId, String packageName) {
1069 IntentFilterVerificationState ivs = new IntentFilterVerificationState(
1070 verifierUid, userId, packageName);
1071 ivs.setPendingState();
1072 synchronized (mPackages) {
1073 mIntentFilterVerificationStates.append(verificationId, ivs);
1074 mCurrentIntentFilterVerifications.add(verificationId);
1080 private static boolean hasValidDomains(ActivityIntentInfo filter) {
1081 return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
1082 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
1083 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
1086 // Set of pending broadcasts for aggregating enable/disable of components.
1087 static class PendingPackageBroadcasts {
1088 // for each user id, a map of <package name -> components within that package>
1089 final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
1091 public PendingPackageBroadcasts() {
1092 mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
1095 public ArrayList<String> get(int userId, String packageName) {
1096 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1097 return packages.get(packageName);
1100 public void put(int userId, String packageName, ArrayList<String> components) {
1101 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1102 packages.put(packageName, components);
1105 public void remove(int userId, String packageName) {
1106 ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1107 if (packages != null) {
1108 packages.remove(packageName);
1112 public void remove(int userId) {
1113 mUidMap.remove(userId);
1116 public int userIdCount() {
1117 return mUidMap.size();
1120 public int userIdAt(int n) {
1121 return mUidMap.keyAt(n);
1124 public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1125 return mUidMap.get(userId);
1129 // total number of pending broadcast entries across all userIds
1131 for (int i = 0; i< mUidMap.size(); i++) {
1132 num += mUidMap.valueAt(i).size();
1137 public void clear() {
1141 private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1142 ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1144 map = new ArrayMap<String, ArrayList<String>>();
1145 mUidMap.put(userId, map);
1150 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1152 // Service Connection to remote media container service to copy
1153 // package uri's from external media onto secure containers
1154 // or internal storage.
1155 private IMediaContainerService mContainerService = null;
1157 static final int SEND_PENDING_BROADCAST = 1;
1158 static final int MCS_BOUND = 3;
1159 static final int END_COPY = 4;
1160 static final int INIT_COPY = 5;
1161 static final int MCS_UNBIND = 6;
1162 static final int START_CLEANING_PACKAGE = 7;
1163 static final int FIND_INSTALL_LOC = 8;
1164 static final int POST_INSTALL = 9;
1165 static final int MCS_RECONNECT = 10;
1166 static final int MCS_GIVE_UP = 11;
1167 static final int UPDATED_MEDIA_STATUS = 12;
1168 static final int WRITE_SETTINGS = 13;
1169 static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1170 static final int PACKAGE_VERIFIED = 15;
1171 static final int CHECK_PENDING_VERIFICATION = 16;
1172 static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1173 static final int INTENT_FILTER_VERIFIED = 18;
1174 static final int WRITE_PACKAGE_LIST = 19;
1175 static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
1177 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds
1179 // Delay time in millisecs
1180 static final int BROADCAST_DELAY = 10 * 1000;
1182 static UserManagerService sUserManager;
1184 // Stores a list of users whose package restrictions file needs to be updated
1185 private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1187 final private DefaultContainerConnection mDefContainerConn =
1188 new DefaultContainerConnection();
1189 class DefaultContainerConnection implements ServiceConnection {
1190 public void onServiceConnected(ComponentName name, IBinder service) {
1191 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1192 final IMediaContainerService imcs = IMediaContainerService.Stub
1193 .asInterface(Binder.allowBlocking(service));
1194 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1197 public void onServiceDisconnected(ComponentName name) {
1198 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1202 // Recordkeeping of restore-after-install operations that are currently in flight
1203 // between the Package Manager and the Backup Manager
1204 static class PostInstallData {
1205 public InstallArgs args;
1206 public PackageInstalledInfo res;
1208 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1214 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1215 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows
1217 // XML tags for backup/restore of various bits of state
1218 private static final String TAG_PREFERRED_BACKUP = "pa";
1219 private static final String TAG_DEFAULT_APPS = "da";
1220 private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1222 private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1223 private static final String TAG_ALL_GRANTS = "rt-grants";
1224 private static final String TAG_GRANT = "grant";
1225 private static final String ATTR_PACKAGE_NAME = "pkg";
1227 private static final String TAG_PERMISSION = "perm";
1228 private static final String ATTR_PERMISSION_NAME = "name";
1229 private static final String ATTR_IS_GRANTED = "g";
1230 private static final String ATTR_USER_SET = "set";
1231 private static final String ATTR_USER_FIXED = "fixed";
1232 private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1234 // System/policy permission grants are not backed up
1235 private static final int SYSTEM_RUNTIME_GRANT_MASK =
1236 FLAG_PERMISSION_POLICY_FIXED
1237 | FLAG_PERMISSION_SYSTEM_FIXED
1238 | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1240 // And we back up these user-adjusted states
1241 private static final int USER_RUNTIME_GRANT_MASK =
1242 FLAG_PERMISSION_USER_SET
1243 | FLAG_PERMISSION_USER_FIXED
1244 | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1246 final @Nullable String mRequiredVerifierPackage;
1247 final @NonNull String mRequiredInstallerPackage;
1248 final @NonNull String mRequiredUninstallerPackage;
1249 final @Nullable String mSetupWizardPackage;
1250 final @Nullable String mStorageManagerPackage;
1251 final @NonNull String mServicesSystemSharedLibraryPackageName;
1252 final @NonNull String mSharedSystemSharedLibraryPackageName;
1254 final boolean mPermissionReviewRequired;
1256 private final PackageUsage mPackageUsage = new PackageUsage();
1257 private final CompilerStats mCompilerStats = new CompilerStats();
1259 class PackageHandler extends Handler {
1260 private boolean mBound = false;
1261 final ArrayList<HandlerParams> mPendingInstalls =
1262 new ArrayList<HandlerParams>();
1264 private boolean connectToService() {
1265 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1266 " DefaultContainerService");
1267 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1268 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1269 if (mContext.bindServiceAsUser(service, mDefContainerConn,
1270 Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1271 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1275 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1279 private void disconnectService() {
1280 mContainerService = null;
1282 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1283 mContext.unbindService(mDefContainerConn);
1284 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1287 PackageHandler(Looper looper) {
1291 public void handleMessage(Message msg) {
1293 doHandleMessage(msg);
1295 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1299 void doHandleMessage(Message msg) {
1302 HandlerParams params = (HandlerParams) msg.obj;
1303 int idx = mPendingInstalls.size();
1304 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1305 // If a bind was already initiated we dont really
1306 // need to do anything. The pending install
1307 // will be processed later on.
1309 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1310 System.identityHashCode(mHandler));
1311 // If this is the only one pending we might
1312 // have to bind to the service again.
1313 if (!connectToService()) {
1314 Slog.e(TAG, "Failed to bind to media container service");
1315 params.serviceError();
1316 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1317 System.identityHashCode(mHandler));
1318 if (params.traceMethod != null) {
1319 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1320 params.traceCookie);
1324 // Once we bind to the service, the first
1325 // pending request will be processed.
1326 mPendingInstalls.add(idx, params);
1329 mPendingInstalls.add(idx, params);
1330 // Already bound to the service. Just make
1331 // sure we trigger off processing the first request.
1333 mHandler.sendEmptyMessage(MCS_BOUND);
1339 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1340 if (msg.obj != null) {
1341 mContainerService = (IMediaContainerService) msg.obj;
1342 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1343 System.identityHashCode(mHandler));
1345 if (mContainerService == null) {
1347 // Something seriously wrong since we are not bound and we are not
1348 // waiting for connection. Bail out.
1349 Slog.e(TAG, "Cannot bind to media container service");
1350 for (HandlerParams params : mPendingInstalls) {
1351 // Indicate service bind error
1352 params.serviceError();
1353 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1354 System.identityHashCode(params));
1355 if (params.traceMethod != null) {
1356 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1357 params.traceMethod, params.traceCookie);
1361 mPendingInstalls.clear();
1363 Slog.w(TAG, "Waiting to connect to media container service");
1365 } else if (mPendingInstalls.size() > 0) {
1366 HandlerParams params = mPendingInstalls.get(0);
1367 if (params != null) {
1368 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1369 System.identityHashCode(params));
1370 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1371 if (params.startCopy()) {
1372 // We are done... look for more work or to
1374 if (DEBUG_SD_INSTALL) Log.i(TAG,
1375 "Checking for more work or unbind...");
1376 // Delete pending install
1377 if (mPendingInstalls.size() > 0) {
1378 mPendingInstalls.remove(0);
1380 if (mPendingInstalls.size() == 0) {
1382 if (DEBUG_SD_INSTALL) Log.i(TAG,
1383 "Posting delayed MCS_UNBIND");
1384 removeMessages(MCS_UNBIND);
1385 Message ubmsg = obtainMessage(MCS_UNBIND);
1386 // Unbind after a little delay, to avoid
1387 // continual thrashing.
1388 sendMessageDelayed(ubmsg, 10000);
1391 // There are more pending requests in queue.
1392 // Just post MCS_BOUND message to trigger processing
1393 // of next pending install.
1394 if (DEBUG_SD_INSTALL) Log.i(TAG,
1395 "Posting MCS_BOUND for next work");
1396 mHandler.sendEmptyMessage(MCS_BOUND);
1399 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1402 // Should never happen ideally.
1403 Slog.w(TAG, "Empty queue");
1407 case MCS_RECONNECT: {
1408 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1409 if (mPendingInstalls.size() > 0) {
1411 disconnectService();
1413 if (!connectToService()) {
1414 Slog.e(TAG, "Failed to bind to media container service");
1415 for (HandlerParams params : mPendingInstalls) {
1416 // Indicate service bind error
1417 params.serviceError();
1418 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1419 System.identityHashCode(params));
1421 mPendingInstalls.clear();
1427 // If there is no actual work left, then time to unbind.
1428 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1430 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1432 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1434 disconnectService();
1436 } else if (mPendingInstalls.size() > 0) {
1437 // There are more pending requests in queue.
1438 // Just post MCS_BOUND message to trigger processing
1439 // of next pending install.
1440 mHandler.sendEmptyMessage(MCS_BOUND);
1446 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1447 HandlerParams params = mPendingInstalls.remove(0);
1448 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1449 System.identityHashCode(params));
1452 case SEND_PENDING_BROADCAST: {
1454 ArrayList<String> components[];
1457 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1458 synchronized (mPackages) {
1459 if (mPendingBroadcasts == null) {
1462 size = mPendingBroadcasts.size();
1464 // Nothing to be done. Just return
1467 packages = new String[size];
1468 components = new ArrayList[size];
1469 uids = new int[size];
1470 int i = 0; // filling out the above arrays
1472 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1473 int packageUserId = mPendingBroadcasts.userIdAt(n);
1474 Iterator<Map.Entry<String, ArrayList<String>>> it
1475 = mPendingBroadcasts.packagesForUserId(packageUserId)
1476 .entrySet().iterator();
1477 while (it.hasNext() && i < size) {
1478 Map.Entry<String, ArrayList<String>> ent = it.next();
1479 packages[i] = ent.getKey();
1480 components[i] = ent.getValue();
1481 PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1482 uids[i] = (ps != null)
1483 ? UserHandle.getUid(packageUserId, ps.appId)
1489 mPendingBroadcasts.clear();
1492 for (int i = 0; i < size; i++) {
1493 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1495 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1498 case START_CLEANING_PACKAGE: {
1499 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1500 final String packageName = (String)msg.obj;
1501 final int userId = msg.arg1;
1502 final boolean andCode = msg.arg2 != 0;
1503 synchronized (mPackages) {
1504 if (userId == UserHandle.USER_ALL) {
1505 int[] users = sUserManager.getUserIds();
1506 for (int user : users) {
1507 mSettings.addPackageToCleanLPw(
1508 new PackageCleanItem(user, packageName, andCode));
1511 mSettings.addPackageToCleanLPw(
1512 new PackageCleanItem(userId, packageName, andCode));
1515 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1516 startCleaningPackages();
1518 case POST_INSTALL: {
1519 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1521 PostInstallData data = mRunningInstalls.get(msg.arg1);
1522 final boolean didRestore = (msg.arg2 != 0);
1523 mRunningInstalls.delete(msg.arg1);
1526 InstallArgs args = data.args;
1527 PackageInstalledInfo parentRes = data.res;
1529 final boolean grantPermissions = (args.installFlags
1530 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1531 final boolean killApp = (args.installFlags
1532 & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1533 final String[] grantedPermissions = args.installGrantPermissions;
1535 // Handle the parent package
1536 handlePackagePostInstall(parentRes, grantPermissions, killApp,
1537 grantedPermissions, didRestore, args.installerPackageName,
1540 // Handle the child packages
1541 final int childCount = (parentRes.addedChildPackages != null)
1542 ? parentRes.addedChildPackages.size() : 0;
1543 for (int i = 0; i < childCount; i++) {
1544 PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1545 handlePackagePostInstall(childRes, grantPermissions, killApp,
1546 grantedPermissions, false, args.installerPackageName,
1550 // Log tracing if needed
1551 if (args.traceMethod != null) {
1552 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1556 Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1559 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1561 case UPDATED_MEDIA_STATUS: {
1562 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1563 boolean reportStatus = msg.arg1 == 1;
1564 boolean doGc = msg.arg2 == 1;
1565 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1567 // Force a gc to clear up stale containers.
1568 Runtime.getRuntime().gc();
1570 if (msg.obj != null) {
1571 @SuppressWarnings("unchecked")
1572 Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1573 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1574 // Unload containers
1575 unloadAllContainers(args);
1579 if (DEBUG_SD_INSTALL) Log.i(TAG,
1580 "Invoking StorageManagerService call back");
1581 PackageHelper.getStorageManager().finishMediaUpdate();
1582 } catch (RemoteException e) {
1583 Log.e(TAG, "StorageManagerService not running?");
1587 case WRITE_SETTINGS: {
1588 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1589 synchronized (mPackages) {
1590 removeMessages(WRITE_SETTINGS);
1591 removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1592 mSettings.writeLPr();
1593 mDirtyUsers.clear();
1595 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1597 case WRITE_PACKAGE_RESTRICTIONS: {
1598 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1599 synchronized (mPackages) {
1600 removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1601 for (int userId : mDirtyUsers) {
1602 mSettings.writePackageRestrictionsLPr(userId);
1604 mDirtyUsers.clear();
1606 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1608 case WRITE_PACKAGE_LIST: {
1609 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1610 synchronized (mPackages) {
1611 removeMessages(WRITE_PACKAGE_LIST);
1612 mSettings.writePackageListLPr(msg.arg1);
1614 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1616 case CHECK_PENDING_VERIFICATION: {
1617 final int verificationId = msg.arg1;
1618 final PackageVerificationState state = mPendingVerification.get(verificationId);
1620 if ((state != null) && !state.timeoutExtended()) {
1621 final InstallArgs args = state.getInstallArgs();
1622 final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1624 Slog.i(TAG, "Verification timed out for " + originUri);
1625 mPendingVerification.remove(verificationId);
1627 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1629 if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
1630 Slog.i(TAG, "Continuing with installation of " + originUri);
1631 state.setVerifierResponse(Binder.getCallingUid(),
1632 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1633 broadcastPackageVerified(verificationId, originUri,
1634 PackageManager.VERIFICATION_ALLOW,
1635 state.getInstallArgs().getUser());
1637 ret = args.copyApk(mContainerService, true);
1638 } catch (RemoteException e) {
1639 Slog.e(TAG, "Could not contact the ContainerService");
1642 broadcastPackageVerified(verificationId, originUri,
1643 PackageManager.VERIFICATION_REJECT,
1644 state.getInstallArgs().getUser());
1647 Trace.asyncTraceEnd(
1648 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1650 processPendingInstall(args, ret);
1651 mHandler.sendEmptyMessage(MCS_UNBIND);
1655 case PACKAGE_VERIFIED: {
1656 final int verificationId = msg.arg1;
1658 final PackageVerificationState state = mPendingVerification.get(verificationId);
1659 if (state == null) {
1660 Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1664 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1666 state.setVerifierResponse(response.callerUid, response.code);
1668 if (state.isVerificationComplete()) {
1669 mPendingVerification.remove(verificationId);
1671 final InstallArgs args = state.getInstallArgs();
1672 final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1675 if (state.isInstallAllowed()) {
1676 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1677 broadcastPackageVerified(verificationId, originUri,
1678 response.code, state.getInstallArgs().getUser());
1680 ret = args.copyApk(mContainerService, true);
1681 } catch (RemoteException e) {
1682 Slog.e(TAG, "Could not contact the ContainerService");
1685 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1688 Trace.asyncTraceEnd(
1689 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1691 processPendingInstall(args, ret);
1692 mHandler.sendEmptyMessage(MCS_UNBIND);
1697 case START_INTENT_FILTER_VERIFICATIONS: {
1698 IFVerificationParams params = (IFVerificationParams) msg.obj;
1699 verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1700 params.replacing, params.pkg);
1703 case INTENT_FILTER_VERIFIED: {
1704 final int verificationId = msg.arg1;
1706 final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1708 if (state == null) {
1709 Slog.w(TAG, "Invalid IntentFilter verification token "
1710 + verificationId + " received");
1714 final int userId = state.getUserId();
1716 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1717 "Processing IntentFilter verification with token:"
1718 + verificationId + " and userId:" + userId);
1720 final IntentFilterVerificationResponse response =
1721 (IntentFilterVerificationResponse) msg.obj;
1723 state.setVerifierResponse(response.callerUid, response.code);
1725 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1726 "IntentFilter verification with token:" + verificationId
1727 + " and userId:" + userId
1728 + " is settings verifier response with response code:"
1731 if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1732 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1733 + response.getFailedDomainsString());
1736 if (state.isVerificationComplete()) {
1737 mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1739 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1740 "IntentFilter verification with token:" + verificationId
1741 + " was not said to be complete");
1746 case INSTANT_APP_RESOLUTION_PHASE_TWO: {
1747 InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
1748 mInstantAppResolverConnection,
1749 (InstantAppRequest) msg.obj,
1750 mInstantAppInstallerActivity,
1757 private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1758 boolean killApp, String[] grantedPermissions,
1759 boolean launchedForRestore, String installerPackage,
1760 IPackageInstallObserver2 installObserver) {
1761 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1762 // Send the removed broadcasts
1763 if (res.removedInfo != null) {
1764 res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1767 // Now that we successfully installed the package, grant runtime
1768 // permissions if requested before broadcasting the install. Also
1769 // for legacy apps in permission review mode we clear the permission
1770 // review flag which is used to emulate runtime permissions for
1772 if (grantPermissions) {
1773 grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions);
1776 final boolean update = res.removedInfo != null
1777 && res.removedInfo.removedPackage != null;
1779 // If this is the first time we have child packages for a disabled privileged
1780 // app that had no children, we grant requested runtime permissions to the new
1781 // children if the parent on the system image had them already granted.
1782 if (res.pkg.parentPackage != null) {
1783 synchronized (mPackages) {
1784 grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg);
1788 synchronized (mPackages) {
1789 mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
1792 final String packageName = res.pkg.applicationInfo.packageName;
1794 // Determine the set of users who are adding this package for
1795 // the first time vs. those who are seeing an update.
1796 int[] firstUsers = EMPTY_INT_ARRAY;
1797 int[] updateUsers = EMPTY_INT_ARRAY;
1798 final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
1799 final PackageSetting ps = (PackageSetting) res.pkg.mExtras;
1800 for (int newUser : res.newUsers) {
1801 if (ps.getInstantApp(newUser)) {
1805 firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1808 boolean isNew = true;
1809 for (int origUser : res.origUsers) {
1810 if (origUser == newUser) {
1816 firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1818 updateUsers = ArrayUtils.appendInt(updateUsers, newUser);
1822 // Send installed broadcasts if the package is not a static shared lib.
1823 if (res.pkg.staticSharedLibName == null) {
1824 mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
1826 // Send added for users that see the package for the first time
1827 // sendPackageAddedForNewUsers also deals with system apps
1828 int appId = UserHandle.getAppId(res.uid);
1829 boolean isSystem = res.pkg.applicationInfo.isSystemApp();
1830 sendPackageAddedForNewUsers(packageName, isSystem, appId, firstUsers);
1832 // Send added for users that don't see the package for the first time
1833 Bundle extras = new Bundle(1);
1834 extras.putInt(Intent.EXTRA_UID, res.uid);
1836 extras.putBoolean(Intent.EXTRA_REPLACING, true);
1838 sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_ADDED, packageName,
1839 extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
1840 null /*targetPackage*/, null /*finishedReceiver*/, updateUsers);
1842 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1843 extras, 0 /*flags*/, null /*targetPackage*/,
1844 null /*finishedReceiver*/, updateUsers);
1846 // Send replaced for users that don't see the package for the first time
1848 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
1849 packageName, extras, 0 /*flags*/,
1850 null /*targetPackage*/, null /*finishedReceiver*/,
1852 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
1853 null /*package*/, null /*extras*/, 0 /*flags*/,
1854 packageName /*targetPackage*/,
1855 null /*finishedReceiver*/, updateUsers);
1856 } else if (launchedForRestore && !isSystemApp(res.pkg)) {
1857 // First-install and we did a restore, so we're responsible for the
1858 // first-launch broadcast.
1860 Slog.i(TAG, "Post-restore of " + packageName
1861 + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers));
1863 sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers);
1866 // Send broadcast package appeared if forward locked/external for all users
1867 // treat asec-hosted packages like removable media on upgrade
1868 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
1869 if (DEBUG_INSTALL) {
1870 Slog.i(TAG, "upgrading pkg " + res.pkg
1871 + " is ASEC-hosted -> AVAILABLE");
1873 final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
1874 ArrayList<String> pkgList = new ArrayList<>(1);
1875 pkgList.add(packageName);
1876 sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
1880 // Work that needs to happen on first install within each user
1881 if (firstUsers != null && firstUsers.length > 0) {
1882 synchronized (mPackages) {
1883 for (int userId : firstUsers) {
1884 // If this app is a browser and it's newly-installed for some
1885 // users, clear any default-browser state in those users. The
1886 // app's nature doesn't depend on the user, so we can just check
1887 // its browser nature in any user and generalize.
1888 if (packageIsBrowser(packageName, userId)) {
1889 mSettings.setDefaultBrowserPackageNameLPw(null, userId);
1892 // We may also need to apply pending (restored) runtime
1893 // permission grants within these users.
1894 mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
1899 // Log current value of "unknown sources" setting
1900 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
1901 getUnknownSourcesSettings());
1903 // Force a gc to clear up things
1904 Runtime.getRuntime().gc();
1906 // Remove the replaced package's older resources safely now
1907 // We delete after a gc for applications on sdcard.
1908 if (res.removedInfo != null && res.removedInfo.args != null) {
1909 synchronized (mInstallLock) {
1910 res.removedInfo.args.doPostDeleteLI(true);
1914 // Notify DexManager that the package was installed for new users.
1915 // The updated users should already be indexed and the package code paths
1916 // should not change.
1917 // Don't notify the manager for ephemeral apps as they are not expected to
1918 // survive long enough to benefit of background optimizations.
1919 for (int userId : firstUsers) {
1920 PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
1921 // There's a race currently where some install events may interleave with an uninstall.
1922 // This can lead to package info being null (b/36642664).
1924 mDexManager.notifyPackageInstalled(info, userId);
1929 // If someone is watching installs - notify them
1930 if (installObserver != null) {
1932 Bundle extras = extrasForInstallResult(res);
1933 installObserver.onPackageInstalled(res.name, res.returnCode,
1934 res.returnMsg, extras);
1935 } catch (RemoteException e) {
1936 Slog.i(TAG, "Observer no longer exists.");
1941 private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(
1942 PackageParser.Package pkg) {
1943 if (pkg.parentPackage == null) {
1946 if (pkg.requestedPermissions == null) {
1949 final PackageSetting disabledSysParentPs = mSettings
1950 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
1951 if (disabledSysParentPs == null || disabledSysParentPs.pkg == null
1952 || !disabledSysParentPs.isPrivileged()
1953 || (disabledSysParentPs.childPackageNames != null
1954 && !disabledSysParentPs.childPackageNames.isEmpty())) {
1957 final int[] allUserIds = sUserManager.getUserIds();
1958 final int permCount = pkg.requestedPermissions.size();
1959 for (int i = 0; i < permCount; i++) {
1960 String permission = pkg.requestedPermissions.get(i);
1961 BasePermission bp = mSettings.mPermissions.get(permission);
1962 if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
1965 for (int userId : allUserIds) {
1966 if (disabledSysParentPs.getPermissionsState().hasRuntimePermission(
1967 permission, userId)) {
1968 grantRuntimePermission(pkg.packageName, permission, userId);
1974 private StorageEventListener mStorageListener = new StorageEventListener() {
1976 public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
1977 if (vol.type == VolumeInfo.TYPE_PRIVATE) {
1978 if (vol.state == VolumeInfo.STATE_MOUNTED) {
1979 final String volumeUuid = vol.getFsUuid();
1981 // Clean up any users or apps that were removed or recreated
1982 // while this volume was missing
1983 sUserManager.reconcileUsers(volumeUuid);
1984 reconcileApps(volumeUuid);
1986 // Clean up any install sessions that expired or were
1987 // cancelled while this volume was missing
1988 mInstallerService.onPrivateVolumeMounted(volumeUuid);
1990 loadPrivatePackages(vol);
1992 } else if (vol.state == VolumeInfo.STATE_EJECTING) {
1993 unloadPrivatePackages(vol);
1997 if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) {
1998 if (vol.state == VolumeInfo.STATE_MOUNTED) {
1999 updateExternalMediaStatus(true, false);
2000 } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2001 updateExternalMediaStatus(false, false);
2007 public void onVolumeForgotten(String fsUuid) {
2008 if (TextUtils.isEmpty(fsUuid)) {
2009 Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
2013 // Remove any apps installed on the forgotten volume
2014 synchronized (mPackages) {
2015 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
2016 for (PackageSetting ps : packages) {
2017 Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
2018 deletePackageVersioned(new VersionedPackage(ps.name,
2019 PackageManager.VERSION_CODE_HIGHEST),
2020 new LegacyPackageDeleteObserver(null).getBinder(),
2021 UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
2022 // Try very hard to release any references to this package
2023 // so we don't risk the system server being killed due to
2025 AttributeCache.instance().removePackage(ps.name);
2028 mSettings.onVolumeForgotten(fsUuid);
2029 mSettings.writeLPr();
2034 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
2035 String[] grantedPermissions) {
2036 for (int userId : userIds) {
2037 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions);
2041 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
2042 String[] grantedPermissions) {
2043 SettingBase sb = (SettingBase) pkg.mExtras;
2048 PermissionsState permissionsState = sb.getPermissionsState();
2050 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
2051 | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2053 final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
2054 >= Build.VERSION_CODES.M;
2056 final boolean instantApp = isInstantApp(pkg.packageName, userId);
2058 for (String permission : pkg.requestedPermissions) {
2059 final BasePermission bp;
2060 synchronized (mPackages) {
2061 bp = mSettings.mPermissions.get(permission);
2063 if (bp != null && (bp.isRuntime() || bp.isDevelopment())
2064 && (!instantApp || bp.isInstant())
2065 && (supportsRuntimePermissions || !bp.isRuntimeOnly())
2066 && (grantedPermissions == null
2067 || ArrayUtils.contains(grantedPermissions, permission))) {
2068 final int flags = permissionsState.getPermissionFlags(permission, userId);
2069 if (supportsRuntimePermissions) {
2070 // Installer cannot change immutable permissions.
2071 if ((flags & immutableFlags) == 0) {
2072 grantRuntimePermission(pkg.packageName, permission, userId);
2074 } else if (mPermissionReviewRequired) {
2075 // In permission review mode we clear the review flag when we
2076 // are asked to install the app with all permissions granted.
2077 if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2078 updatePermissionFlags(permission, pkg.packageName,
2079 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, userId);
2086 Bundle extrasForInstallResult(PackageInstalledInfo res) {
2087 Bundle extras = null;
2088 switch (res.returnCode) {
2089 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2090 extras = new Bundle();
2091 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2092 res.origPermission);
2093 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2097 case PackageManager.INSTALL_SUCCEEDED: {
2098 extras = new Bundle();
2099 extras.putBoolean(Intent.EXTRA_REPLACING,
2100 res.removedInfo != null && res.removedInfo.removedPackage != null);
2107 void scheduleWriteSettingsLocked() {
2108 if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2109 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2113 void scheduleWritePackageListLocked(int userId) {
2114 if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2115 Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2117 mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2121 void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2122 final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2123 scheduleWritePackageRestrictionsLocked(userId);
2126 void scheduleWritePackageRestrictionsLocked(int userId) {
2127 final int[] userIds = (userId == UserHandle.USER_ALL)
2128 ? sUserManager.getUserIds() : new int[]{userId};
2129 for (int nextUserId : userIds) {
2130 if (!sUserManager.exists(nextUserId)) return;
2131 mDirtyUsers.add(nextUserId);
2132 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2133 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2138 public static PackageManagerService main(Context context, Installer installer,
2139 boolean factoryTest, boolean onlyCore) {
2140 // Self-check for initial settings.
2141 PackageManagerServiceCompilerMapping.checkProperties();
2143 PackageManagerService m = new PackageManagerService(context, installer,
2144 factoryTest, onlyCore);
2145 m.enableSystemUserPackages();
2146 ServiceManager.addService("package", m);
2150 private void enableSystemUserPackages() {
2151 if (!UserManager.isSplitSystemUser()) {
2154 // For system user, enable apps based on the following conditions:
2155 // - app is whitelisted or belong to one of these groups:
2156 // -- system app which has no launcher icons
2157 // -- system app which has INTERACT_ACROSS_USERS permission
2158 // -- system IME app
2159 // - app is not in the blacklist
2160 AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2161 Set<String> enableApps = new ArraySet<>();
2162 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2163 | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2164 | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2165 ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2166 enableApps.addAll(wlApps);
2167 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2168 /* systemAppsOnly */ false, UserHandle.SYSTEM));
2169 ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2170 enableApps.removeAll(blApps);
2171 Log.i(TAG, "Applications installed for system user: " + enableApps);
2172 List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2174 final int allAppsSize = allAps.size();
2175 synchronized (mPackages) {
2176 for (int i = 0; i < allAppsSize; i++) {
2177 String pName = allAps.get(i);
2178 PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2179 // Should not happen, but we shouldn't be failing if it does
2180 if (pkgSetting == null) {
2183 boolean install = enableApps.contains(pName);
2184 if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2185 Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2186 + " for system user");
2187 pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2190 scheduleWritePackageRestrictionsLocked(UserHandle.USER_SYSTEM);
2194 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2195 DisplayManager displayManager = (DisplayManager) context.getSystemService(
2196 Context.DISPLAY_SERVICE);
2197 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2201 * Requests that files preopted on a secondary system partition be copied to the data partition
2202 * if possible. Note that the actual copying of the files is accomplished by init for security
2203 * reasons. This simply requests that the copy takes place and awaits confirmation of its
2204 * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2206 private static void requestCopyPreoptedFiles() {
2207 final int WAIT_TIME_MS = 100;
2208 final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2209 if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2210 SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2211 // We will wait for up to 100 seconds.
2212 final long timeStart = SystemClock.uptimeMillis();
2213 final long timeEnd = timeStart + 100 * 1000;
2214 long timeNow = timeStart;
2215 while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2217 Thread.sleep(WAIT_TIME_MS);
2218 } catch (InterruptedException e) {
2221 timeNow = SystemClock.uptimeMillis();
2222 if (timeNow > timeEnd) {
2223 SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2224 Slog.wtf(TAG, "cppreopt did not finish!");
2229 Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2233 public PackageManagerService(Context context, Installer installer,
2234 boolean factoryTest, boolean onlyCore) {
2235 LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
2236 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
2237 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2238 SystemClock.uptimeMillis());
2240 if (mSdkVersion <= 0) {
2241 Slog.w(TAG, "**** ro.build.version.sdk not set!");
2246 mPermissionReviewRequired = context.getResources().getBoolean(
2247 R.bool.config_permissionReviewRequired);
2249 mFactoryTest = factoryTest;
2250 mOnlyCore = onlyCore;
2251 mMetrics = new DisplayMetrics();
2252 mSettings = new Settings(mPackages);
2253 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2254 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2255 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2256 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2257 mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2258 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2259 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2260 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2261 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2262 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2263 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2264 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2266 String separateProcesses = SystemProperties.get("debug.separate_processes");
2267 if (separateProcesses != null && separateProcesses.length() > 0) {
2268 if ("*".equals(separateProcesses)) {
2269 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2270 mSeparateProcesses = null;
2271 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2274 mSeparateProcesses = separateProcesses.split(",");
2275 Slog.w(TAG, "Running with debug.separate_processes: "
2276 + separateProcesses);
2280 mSeparateProcesses = null;
2283 mInstaller = installer;
2284 mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2286 mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock);
2287 mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2289 mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2290 FgThread.get().getLooper());
2292 getDefaultDisplayMetrics(context, mMetrics);
2294 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
2295 SystemConfig systemConfig = SystemConfig.getInstance();
2296 mGlobalGids = systemConfig.getGlobalGids();
2297 mSystemPermissions = systemConfig.getSystemPermissions();
2298 mAvailableFeatures = systemConfig.getAvailableFeatures();
2299 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2301 mProtectedPackages = new ProtectedPackages(mContext);
2303 synchronized (mInstallLock) {
2305 synchronized (mPackages) {
2306 mHandlerThread = new ServiceThread(TAG,
2307 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2308 mHandlerThread.start();
2309 mHandler = new PackageHandler(mHandlerThread.getLooper());
2310 mProcessLoggingHandler = new ProcessLoggingHandler();
2311 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2313 mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this);
2314 mInstantAppRegistry = new InstantAppRegistry(this);
2316 File dataDir = Environment.getDataDirectory();
2317 mAppInstallDir = new File(dataDir, "app");
2318 mAppLib32InstallDir = new File(dataDir, "app-lib");
2319 mAsecInternalPath = new File(dataDir, "app-asec").getPath();
2320 mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
2321 sUserManager = new UserManagerService(context, this,
2322 new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
2324 // Propagate permission configuration in to package manager.
2325 ArrayMap<String, SystemConfig.PermissionEntry> permConfig
2326 = systemConfig.getPermissions();
2327 for (int i=0; i<permConfig.size(); i++) {
2328 SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
2329 BasePermission bp = mSettings.mPermissions.get(perm.name);
2331 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
2332 mSettings.mPermissions.put(perm.name, bp);
2334 if (perm.gids != null) {
2335 bp.setGids(perm.gids, perm.perUser);
2339 ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2340 final int builtInLibCount = libConfig.size();
2341 for (int i = 0; i < builtInLibCount; i++) {
2342 String name = libConfig.keyAt(i);
2343 String path = libConfig.valueAt(i);
2344 addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
2345 SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
2348 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
2350 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
2351 mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2352 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2354 // Clean up orphaned packages for which the code path doesn't exist
2355 // and they are an update to a system app - caused by bug/32321269
2356 final int packageSettingCount = mSettings.mPackages.size();
2357 for (int i = packageSettingCount - 1; i >= 0; i--) {
2358 PackageSetting ps = mSettings.mPackages.valueAt(i);
2359 if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2360 && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2361 mSettings.mPackages.removeAt(i);
2362 mSettings.enableSystemPackageLPw(ps.name);
2367 requestCopyPreoptedFiles();
2370 String customResolverActivity = Resources.getSystem().getString(
2371 R.string.config_customResolverActivity);
2372 if (TextUtils.isEmpty(customResolverActivity)) {
2373 customResolverActivity = null;
2375 mCustomResolverComponentName = ComponentName.unflattenFromString(
2376 customResolverActivity);
2379 long startTime = SystemClock.uptimeMillis();
2381 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2384 final String bootClassPath = System.getenv("BOOTCLASSPATH");
2385 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2387 if (bootClassPath == null) {
2388 Slog.w(TAG, "No BOOTCLASSPATH found!");
2391 if (systemServerClassPath == null) {
2392 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2395 File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2397 final VersionInfo ver = mSettings.getInternalVersion();
2398 mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2400 logCriticalInfo(Log.INFO,
2401 "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
2404 // when upgrading from pre-M, promote system app permissions from install to runtime
2405 mPromoteSystemApps =
2406 mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2408 // When upgrading from pre-N, we need to handle package extraction like first boot,
2409 // as there is no profiling data available.
2410 mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2412 mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2414 // save off the names of pre-existing system packages prior to scanning; we don't
2415 // want to automatically grant runtime permissions for new system apps
2416 if (mPromoteSystemApps) {
2417 Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2418 while (pkgSettingIter.hasNext()) {
2419 PackageSetting ps = pkgSettingIter.next();
2420 if (isSystemApp(ps)) {
2421 mExistingSystemPackages.add(ps.name);
2426 mCacheDir = preparePackageParserCache(mIsUpgrade);
2428 // Set flag to monitor and not change apk file paths when
2429 // scanning install directories.
2430 int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2432 if (mIsUpgrade || mFirstBoot) {
2433 scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2436 // Collect vendor overlay packages. (Do this before scanning any apps.)
2437 // For security and version matching reason, only consider
2438 // overlay packages if they reside in the right directory.
2439 scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags
2440 | PackageParser.PARSE_IS_SYSTEM
2441 | PackageParser.PARSE_IS_SYSTEM_DIR
2442 | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2444 // Find base frameworks (resource packages without code).
2445 scanDirTracedLI(frameworkDir, mDefParseFlags
2446 | PackageParser.PARSE_IS_SYSTEM
2447 | PackageParser.PARSE_IS_SYSTEM_DIR
2448 | PackageParser.PARSE_IS_PRIVILEGED,
2449 scanFlags | SCAN_NO_DEX, 0);
2451 // Collected privileged system packages.
2452 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2453 scanDirTracedLI(privilegedAppDir, mDefParseFlags
2454 | PackageParser.PARSE_IS_SYSTEM
2455 | PackageParser.PARSE_IS_SYSTEM_DIR
2456 | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
2458 // Collect ordinary system packages.
2459 final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2460 scanDirTracedLI(systemAppDir, mDefParseFlags
2461 | PackageParser.PARSE_IS_SYSTEM
2462 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2464 // Collect all vendor packages.
2465 File vendorAppDir = new File("/vendor/app");
2467 vendorAppDir = vendorAppDir.getCanonicalFile();
2468 } catch (IOException e) {
2469 // failed to look up canonical path, continue with original one
2471 scanDirTracedLI(vendorAppDir, mDefParseFlags
2472 | PackageParser.PARSE_IS_SYSTEM
2473 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2475 // Collect all OEM packages.
2476 final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2477 scanDirTracedLI(oemAppDir, mDefParseFlags
2478 | PackageParser.PARSE_IS_SYSTEM
2479 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2481 // Prune any system packages that no longer exist.
2482 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
2484 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2485 while (psit.hasNext()) {
2486 PackageSetting ps = psit.next();
2489 * If this is not a system app, it can't be a
2490 * disable system app.
2492 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2497 * If the package is scanned, it's not erased.
2499 final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2500 if (scannedPkg != null) {
2502 * If the system app is both scanned and in the
2503 * disabled packages list, then it must have been
2504 * added via OTA. Remove it from the currently
2505 * scanned package so the previously user-installed
2506 * application can be scanned.
2508 if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2509 logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2510 + ps.name + "; removing system app. Last known codePath="
2511 + ps.codePathString + ", installStatus=" + ps.installStatus
2512 + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2513 + scannedPkg.mVersionCode);
2514 removePackageLI(scannedPkg, true);
2515 mExpectingBetter.put(ps.name, ps.codePath);
2521 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2523 logCriticalInfo(Log.WARN, "System package " + ps.name
2524 + " no longer exists; it's data will be wiped");
2525 // Actual deletion of code and data will be handled by later
2526 // reconciliation step
2528 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
2529 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
2530 possiblyDeletedUpdatedSystemApps.add(ps.name);
2536 //look for any incomplete package installations
2537 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2538 for (int i = 0; i < deletePkgsList.size(); i++) {
2539 // Actual deletion of code and data will be handled by later
2540 // reconciliation step
2541 final String packageName = deletePkgsList.get(i).name;
2542 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
2543 synchronized (mPackages) {
2544 mSettings.removePackageLPw(packageName);
2549 deleteTempPackageFiles();
2551 // Remove any shared userIDs that have no associated packages
2552 mSettings.pruneSharedUsersLPw();
2555 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2556 SystemClock.uptimeMillis());
2557 scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2559 scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
2560 | PackageParser.PARSE_FORWARD_LOCK,
2561 scanFlags | SCAN_REQUIRE_KNOWN, 0);
2564 * Remove disable package settings for any updated system
2565 * apps that were removed via an OTA. If they're not a
2566 * previously-updated app, remove them completely.
2567 * Otherwise, just revoke their system-level permissions.
2569 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2570 PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2571 mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2574 if (deletedPkg == null) {
2575 msg = "Updated system package " + deletedAppName
2576 + " no longer exists; it's data will be wiped";
2577 // Actual deletion of code and data will be handled by later
2578 // reconciliation step
2580 msg = "Updated system app + " + deletedAppName
2581 + " no longer present; removing system privileges for "
2584 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2586 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2587 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2589 logCriticalInfo(Log.WARN, msg);
2593 * Make sure all system apps that we expected to appear on
2594 * the userdata partition actually showed up. If they never
2595 * appeared, crawl back and revive the system version.
2597 for (int i = 0; i < mExpectingBetter.size(); i++) {
2598 final String packageName = mExpectingBetter.keyAt(i);
2599 if (!mPackages.containsKey(packageName)) {
2600 final File scanFile = mExpectingBetter.valueAt(i);
2602 logCriticalInfo(Log.WARN, "Expected better " + packageName
2603 + " but never showed up; reverting to system");
2605 int reparseFlags = mDefParseFlags;
2606 if (FileUtils.contains(privilegedAppDir, scanFile)) {
2607 reparseFlags = PackageParser.PARSE_IS_SYSTEM
2608 | PackageParser.PARSE_IS_SYSTEM_DIR
2609 | PackageParser.PARSE_IS_PRIVILEGED;
2610 } else if (FileUtils.contains(systemAppDir, scanFile)) {
2611 reparseFlags = PackageParser.PARSE_IS_SYSTEM
2612 | PackageParser.PARSE_IS_SYSTEM_DIR;
2613 } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2614 reparseFlags = PackageParser.PARSE_IS_SYSTEM
2615 | PackageParser.PARSE_IS_SYSTEM_DIR;
2616 } else if (FileUtils.contains(oemAppDir, scanFile)) {
2617 reparseFlags = PackageParser.PARSE_IS_SYSTEM
2618 | PackageParser.PARSE_IS_SYSTEM_DIR;
2620 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2624 mSettings.enableSystemPackageLPw(packageName);
2627 scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
2628 } catch (PackageManagerException e) {
2629 Slog.e(TAG, "Failed to parse original system package: "
2635 mExpectingBetter.clear();
2637 // Resolve the storage manager.
2638 mStorageManagerPackage = getStorageManagerPackageName();
2640 // Resolve protected action filters. Only the setup wizard is allowed to
2641 // have a high priority filter for these actions.
2642 mSetupWizardPackage = getSetupWizardPackageName();
2643 if (mProtectedFilters.size() > 0) {
2644 if (DEBUG_FILTERS && mSetupWizardPackage == null) {
2645 Slog.i(TAG, "No setup wizard;"
2646 + " All protected intents capped to priority 0");
2648 for (ActivityIntentInfo filter : mProtectedFilters) {
2649 if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
2650 if (DEBUG_FILTERS) {
2651 Slog.i(TAG, "Found setup wizard;"
2652 + " allow priority " + filter.getPriority() + ";"
2653 + " package: " + filter.activity.info.packageName
2654 + " activity: " + filter.activity.className
2655 + " priority: " + filter.getPriority());
2657 // skip setup wizard; allow it to keep the high priority filter
2660 Slog.w(TAG, "Protected action; cap priority to 0;"
2661 + " package: " + filter.activity.info.packageName
2662 + " activity: " + filter.activity.className
2663 + " origPrio: " + filter.getPriority());
2664 filter.setPriority(0);
2667 mDeferProtectedFilters = false;
2668 mProtectedFilters.clear();
2670 // Now that we know all of the shared libraries, update all clients to have
2671 // the correct library paths.
2672 updateAllSharedLibrariesLPw(null);
2674 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2675 // NOTE: We ignore potential failures here during a system scan (like
2676 // the rest of the commands above) because there's precious little we
2677 // can do about it. A settings error is reported, though.
2678 adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
2681 // Now that we know all the packages we are keeping,
2682 // read and update their last usage times.
2683 mPackageUsage.read(mPackages);
2684 mCompilerStats.read();
2686 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2687 SystemClock.uptimeMillis());
2688 Slog.i(TAG, "Time to scan packages: "
2689 + ((SystemClock.uptimeMillis()-startTime)/1000f)
2692 // If the platform SDK has changed since the last time we booted,
2693 // we need to re-grant app permission to catch any new ones that
2694 // appear. This is really a hack, and means that apps can in some
2695 // cases get permissions that the user didn't initially explicitly
2696 // allow... it would be nice to have some better way to handle
2698 int updateFlags = UPDATE_PERMISSIONS_ALL;
2699 if (ver.sdkVersion != mSdkVersion) {
2700 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2701 + mSdkVersion + "; regranting permissions for internal storage");
2702 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
2704 updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
2705 ver.sdkVersion = mSdkVersion;
2707 // If this is the first boot or an update from pre-M, and it is a normal
2708 // boot, then we need to initialize the default preferred apps across
2709 // all defined users.
2710 if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
2711 for (UserInfo user : sUserManager.getUsers(true)) {
2712 mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2713 applyFactoryDefaultBrowserLPw(user.id);
2714 primeDomainVerificationsLPw(user.id);
2718 // Prepare storage for system user really early during boot,
2719 // since core system apps like SettingsProvider and SystemUI
2720 // can't wait for user to start
2721 final int storageFlags;
2722 if (StorageManager.isFileEncryptedNativeOrEmulated()) {
2723 storageFlags = StorageManager.FLAG_STORAGE_DE;
2725 storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
2727 List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
2728 UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
2729 true /* onlyCoreApps */);
2730 mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
2731 BootTimingsTraceLog traceLog = new BootTimingsTraceLog("SystemServerTimingAsync",
2732 Trace.TRACE_TAG_PACKAGE_MANAGER);
2733 traceLog.traceBegin("AppDataFixup");
2735 mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
2736 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
2737 } catch (InstallerException e) {
2738 Slog.w(TAG, "Trouble fixing GIDs", e);
2740 traceLog.traceEnd();
2742 traceLog.traceBegin("AppDataPrepare");
2743 if (deferPackages == null || deferPackages.isEmpty()) {
2747 for (String pkgName : deferPackages) {
2748 PackageParser.Package pkg = null;
2749 synchronized (mPackages) {
2750 PackageSetting ps = mSettings.getPackageLPr(pkgName);
2751 if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
2756 synchronized (mInstallLock) {
2757 prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
2758 true /* maybeMigrateAppData */);
2763 traceLog.traceEnd();
2764 Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
2765 }, "prepareAppData");
2767 // If this is first boot after an OTA, and a normal boot, then
2768 // we need to clear code cache directories.
2769 // Note that we do *not* clear the application profiles. These remain valid
2770 // across OTAs and are used to drive profile verification (post OTA) and
2771 // profile compilation (without waiting to collect a fresh set of profiles).
2772 if (mIsUpgrade && !onlyCore) {
2773 Slog.i(TAG, "Build fingerprint changed; clearing code caches");
2774 for (int i = 0; i < mSettings.mPackages.size(); i++) {
2775 final PackageSetting ps = mSettings.mPackages.valueAt(i);
2776 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
2777 // No apps are running this early, so no need to freeze
2778 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
2779 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
2780 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
2783 ver.fingerprint = Build.FINGERPRINT;
2786 checkDefaultBrowser();
2788 // clear only after permissions and other defaults have been updated
2789 mExistingSystemPackages.clear();
2790 mPromoteSystemApps = false;
2792 // All the changes are done during package scanning.
2793 ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
2795 // can downgrade to reader
2796 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
2797 mSettings.writeLPr();
2798 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2800 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
2801 SystemClock.uptimeMillis());
2804 mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
2805 mRequiredInstallerPackage = getRequiredInstallerLPr();
2806 mRequiredUninstallerPackage = getRequiredUninstallerLPr();
2807 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
2808 mIntentFilterVerifier = new IntentVerifierProxy(mContext,
2809 mIntentFilterVerifierComponent);
2810 mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2811 PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
2812 SharedLibraryInfo.VERSION_UNDEFINED);
2813 mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2814 PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
2815 SharedLibraryInfo.VERSION_UNDEFINED);
2817 mRequiredVerifierPackage = null;
2818 mRequiredInstallerPackage = null;
2819 mRequiredUninstallerPackage = null;
2820 mIntentFilterVerifierComponent = null;
2821 mIntentFilterVerifier = null;
2822 mServicesSystemSharedLibraryPackageName = null;
2823 mSharedSystemSharedLibraryPackageName = null;
2826 mInstallerService = new PackageInstallerService(context, this);
2827 final Pair<ComponentName, String> instantAppResolverComponent =
2828 getInstantAppResolverLPr();
2829 if (instantAppResolverComponent != null) {
2830 if (DEBUG_EPHEMERAL) {
2831 Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
2833 mInstantAppResolverConnection = new EphemeralResolverConnection(
2834 mContext, instantAppResolverComponent.first,
2835 instantAppResolverComponent.second);
2836 mInstantAppResolverSettingsComponent =
2837 getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
2839 mInstantAppResolverConnection = null;
2840 mInstantAppResolverSettingsComponent = null;
2842 updateInstantAppInstallerLocked(null);
2844 // Read and update the usage of dex files.
2845 // Do this at the end of PM init so that all the packages have their
2846 // data directory reconciled.
2847 // At this point we know the code paths of the packages, so we can validate
2848 // the disk file and build the internal cache.
2849 // The usage file is expected to be small so loading and verifying it
2850 // should take a fairly small time compare to the other activities (e.g. package
2852 final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
2853 final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
2854 for (int userId : currentUserIds) {
2855 userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
2857 mDexManager.load(userPackages);
2858 } // synchronized (mPackages)
2859 } // synchronized (mInstallLock)
2861 // Now after opening every single application zip, make sure they
2862 // are all flushed. Not really needed, but keeps things nice and
2864 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
2865 Runtime.getRuntime().gc();
2866 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2868 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
2869 FallbackCategoryProvider.loadFallbacks();
2870 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2872 // The initial scanning above does many calls into installd while
2873 // holding the mPackages lock, but we're mostly interested in yelling
2874 // once we have a booted system.
2875 mInstaller.setWarnIfHeld(mPackages);
2877 // Expose private service for system components to use.
2878 LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
2879 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2882 private void updateInstantAppInstallerLocked(String modifiedPackage) {
2883 // we're only interested in updating the installer appliction when 1) it's not
2884 // already set or 2) the modified package is the installer
2885 if (mInstantAppInstallerActivity != null
2886 && !mInstantAppInstallerActivity.getComponentName().getPackageName()
2887 .equals(modifiedPackage)) {
2890 setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
2893 private static File preparePackageParserCache(boolean isUpgrade) {
2894 if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
2898 // Disable package parsing on eng builds to allow for faster incremental development.
2899 if ("eng".equals(Build.TYPE)) {
2903 if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
2904 Slog.i(TAG, "Disabling package parser cache due to system property.");
2908 // The base directory for the package parser cache lives under /data/system/.
2909 final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(),
2911 if (cacheBaseDir == null) {
2915 // If this is a system upgrade scenario, delete the contents of the package cache dir.
2916 // This also serves to "GC" unused entries when the package cache version changes (which
2917 // can only happen during upgrades).
2919 FileUtils.deleteContents(cacheBaseDir);
2923 // Return the versioned package cache directory. This is something like
2924 // "/data/system/package_cache/1"
2925 File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
2927 // The following is a workaround to aid development on non-numbered userdebug
2928 // builds or cases where "adb sync" is used on userdebug builds. If we detect that
2929 // the system partition is newer.
2931 // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
2932 // that starts with "eng." to signify that this is an engineering build and not
2933 // destined for release.
2934 if ("userdebug".equals(Build.TYPE) && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
2935 Slog.w(TAG, "Wiping cache directory because the system partition changed.");
2937 // Heuristic: If the /system directory has been modified recently due to an "adb sync"
2938 // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
2939 // in general and should not be used for production changes. In this specific case,
2940 // we know that they will work.
2941 File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2942 if (cacheDir.lastModified() < frameworkDir.lastModified()) {
2943 FileUtils.deleteContents(cacheBaseDir);
2944 cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
2952 public boolean isFirstBoot() {
2957 public boolean isOnlyCoreApps() {
2962 public boolean isUpgrade() {
2966 private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
2967 final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
2969 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
2970 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2971 UserHandle.USER_SYSTEM);
2972 if (matches.size() == 1) {
2973 return matches.get(0).getComponentInfo().packageName;
2974 } else if (matches.size() == 0) {
2975 Log.e(TAG, "There should probably be a verifier, but, none were found");
2978 throw new RuntimeException("There must be exactly one verifier; found " + matches);
2981 private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
2982 synchronized (mPackages) {
2983 SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version);
2984 if (libraryEntry == null) {
2985 throw new IllegalStateException("Missing required shared library:" + name);
2987 return libraryEntry.apk;
2991 private @NonNull String getRequiredInstallerLPr() {
2992 final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
2993 intent.addCategory(Intent.CATEGORY_DEFAULT);
2994 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
2996 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
2997 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2998 UserHandle.USER_SYSTEM);
2999 if (matches.size() == 1) {
3000 ResolveInfo resolveInfo = matches.get(0);
3001 if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3002 throw new RuntimeException("The installer must be a privileged app");
3004 return matches.get(0).getComponentInfo().packageName;
3006 throw new RuntimeException("There must be exactly one installer; found " + matches);
3010 private @NonNull String getRequiredUninstallerLPr() {
3011 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
3012 intent.addCategory(Intent.CATEGORY_DEFAULT);
3013 intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
3015 final ResolveInfo resolveInfo = resolveIntent(intent, null,
3016 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3017 UserHandle.USER_SYSTEM);
3018 if (resolveInfo == null ||
3019 mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
3020 throw new RuntimeException("There must be exactly one uninstaller; found "
3023 return resolveInfo.getComponentInfo().packageName;
3026 private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3027 final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3029 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3030 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3031 UserHandle.USER_SYSTEM);
3032 ResolveInfo best = null;
3033 final int N = matches.size();
3034 for (int i = 0; i < N; i++) {
3035 final ResolveInfo cur = matches.get(i);
3036 final String packageName = cur.getComponentInfo().packageName;
3037 if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3038 packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3042 if (best == null || cur.priority > best.priority) {
3048 return best.getComponentInfo().getComponentName();
3050 throw new RuntimeException("There must be at least one intent filter verifier");
3054 private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
3055 final String[] packageArray =
3056 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3057 if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3058 if (DEBUG_EPHEMERAL) {
3059 Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3064 final int callingUid = Binder.getCallingUid();
3065 final int resolveFlags =
3066 MATCH_DIRECT_BOOT_AWARE
3067 | MATCH_DIRECT_BOOT_UNAWARE
3068 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3069 String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
3070 final Intent resolverIntent = new Intent(actionName);
3071 List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3072 resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3073 // temporarily look for the old action
3074 if (resolvers.size() == 0) {
3075 if (DEBUG_EPHEMERAL) {
3076 Slog.d(TAG, "Ephemeral resolver not found with new action; try old one");
3078 actionName = Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE;
3079 resolverIntent.setAction(actionName);
3080 resolvers = queryIntentServicesInternal(resolverIntent, null,
3081 resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3083 final int N = resolvers.size();
3085 if (DEBUG_EPHEMERAL) {
3086 Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3091 final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3092 for (int i = 0; i < N; i++) {
3093 final ResolveInfo info = resolvers.get(i);
3095 if (info.serviceInfo == null) {
3099 final String packageName = info.serviceInfo.packageName;
3100 if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3101 if (DEBUG_EPHEMERAL) {
3102 Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3103 + " pkg: " + packageName + ", info:" + info);
3108 if (DEBUG_EPHEMERAL) {
3109 Slog.v(TAG, "Ephemeral resolver found;"
3110 + " pkg: " + packageName + ", info:" + info);
3112 return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
3114 if (DEBUG_EPHEMERAL) {
3115 Slog.v(TAG, "Ephemeral resolver NOT found");
3120 private @Nullable ActivityInfo getInstantAppInstallerLPr() {
3121 final Intent intent = new Intent(Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE);
3122 intent.addCategory(Intent.CATEGORY_DEFAULT);
3123 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3125 final int resolveFlags =
3126 MATCH_DIRECT_BOOT_AWARE
3127 | MATCH_DIRECT_BOOT_UNAWARE
3128 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3129 List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3130 resolveFlags, UserHandle.USER_SYSTEM);
3131 // temporarily look for the old action
3132 if (matches.isEmpty()) {
3133 if (DEBUG_EPHEMERAL) {
3134 Slog.d(TAG, "Ephemeral installer not found with new action; try old one");
3136 intent.setAction(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
3137 matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3138 resolveFlags, UserHandle.USER_SYSTEM);
3140 Iterator<ResolveInfo> iter = matches.iterator();
3141 while (iter.hasNext()) {
3142 final ResolveInfo rInfo = iter.next();
3143 final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3145 final PermissionsState permissionsState = ps.getPermissionsState();
3146 if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)) {
3152 if (matches.size() == 0) {
3154 } else if (matches.size() == 1) {
3155 return (ActivityInfo) matches.get(0).getComponentInfo();
3157 throw new RuntimeException(
3158 "There must be at most one ephemeral installer; found " + matches);
3162 private @Nullable ComponentName getInstantAppResolverSettingsLPr(
3163 @NonNull ComponentName resolver) {
3164 final Intent intent = new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
3165 .addCategory(Intent.CATEGORY_DEFAULT)
3166 .setPackage(resolver.getPackageName());
3167 final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3168 List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3169 UserHandle.USER_SYSTEM);
3170 // temporarily look for the old action
3171 if (matches.isEmpty()) {
3172 if (DEBUG_EPHEMERAL) {
3173 Slog.d(TAG, "Ephemeral resolver settings not found with new action; try old one");
3175 intent.setAction(Intent.ACTION_EPHEMERAL_RESOLVER_SETTINGS);
3176 matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3177 UserHandle.USER_SYSTEM);
3179 if (matches.isEmpty()) {
3182 return matches.get(0).getComponentInfo().getComponentName();
3185 private void primeDomainVerificationsLPw(int userId) {
3186 if (DEBUG_DOMAIN_VERIFICATION) {
3187 Slog.d(TAG, "Priming domain verifications in user " + userId);
3190 SystemConfig systemConfig = SystemConfig.getInstance();
3191 ArraySet<String> packages = systemConfig.getLinkedApps();
3193 for (String packageName : packages) {
3194 PackageParser.Package pkg = mPackages.get(packageName);
3196 if (!pkg.isSystemApp()) {
3197 Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
3201 ArraySet<String> domains = null;
3202 for (PackageParser.Activity a : pkg.activities) {
3203 for (ActivityIntentInfo filter : a.intents) {
3204 if (hasValidDomains(filter)) {
3205 if (domains == null) {
3206 domains = new ArraySet<String>();
3208 domains.addAll(filter.getHostsList());
3213 if (domains != null && domains.size() > 0) {
3214 if (DEBUG_DOMAIN_VERIFICATION) {
3215 Slog.v(TAG, " + " + packageName);
3217 // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
3218 // state w.r.t. the formal app-linkage "no verification attempted" state;
3219 // and then 'always' in the per-user state actually used for intent resolution.
3220 final IntentFilterVerificationInfo ivi;
3221 ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
3222 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
3223 mSettings.updateIntentFilterVerificationStatusLPw(packageName,
3224 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
3226 Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
3227 + "' does not handle web links");
3230 Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
3234 scheduleWritePackageRestrictionsLocked(userId);
3235 scheduleWriteSettingsLocked();
3238 private void applyFactoryDefaultBrowserLPw(int userId) {
3239 // The default browser app's package name is stored in a string resource,
3240 // with a product-specific overlay used for vendor customization.
3241 String browserPkg = mContext.getResources().getString(
3242 com.android.internal.R.string.default_browser);
3243 if (!TextUtils.isEmpty(browserPkg)) {
3244 // non-empty string => required to be a known package
3245 PackageSetting ps = mSettings.mPackages.get(browserPkg);
3247 Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
3250 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3254 // Nothing valid explicitly set? Make the factory-installed browser the explicit
3255 // default. If there's more than one, just leave everything alone.
3256 if (browserPkg == null) {
3257 calculateDefaultBrowserLPw(userId);
3261 private void calculateDefaultBrowserLPw(int userId) {
3262 List<String> allBrowsers = resolveAllBrowserApps(userId);
3263 final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
3264 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3267 private List<String> resolveAllBrowserApps(int userId) {
3268 // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
3269 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3270 PackageManager.MATCH_ALL, userId);
3272 final int count = list.size();
3273 List<String> result = new ArrayList<String>(count);
3274 for (int i=0; i<count; i++) {
3275 ResolveInfo info = list.get(i);
3276 if (info.activityInfo == null
3277 || !info.handleAllWebDataURI
3278 || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
3279 || result.contains(info.activityInfo.packageName)) {
3282 result.add(info.activityInfo.packageName);
3288 private boolean packageIsBrowser(String packageName, int userId) {
3289 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3290 PackageManager.MATCH_ALL, userId);
3291 final int N = list.size();
3292 for (int i = 0; i < N; i++) {
3293 ResolveInfo info = list.get(i);
3294 if (packageName.equals(info.activityInfo.packageName)) {
3301 private void checkDefaultBrowser() {
3302 final int myUserId = UserHandle.myUserId();
3303 final String packageName = getDefaultBrowserPackageName(myUserId);
3304 if (packageName != null) {
3305 PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3307 Slog.w(TAG, "Default browser no longer installed: " + packageName);
3308 synchronized (mPackages) {
3309 applyFactoryDefaultBrowserLPw(myUserId); // leaves ambiguous when > 1
3316 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3317 throws RemoteException {
3319 return super.onTransact(code, data, reply, flags);
3320 } catch (RuntimeException e) {
3321 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3322 Slog.wtf(TAG, "Package Manager Crash", e);
3328 static int[] appendInts(int[] cur, int[] add) {
3329 if (add == null) return cur;
3330 if (cur == null) return add;
3331 final int N = add.length;
3332 for (int i=0; i<N; i++) {
3333 cur = appendInt(cur, add[i]);
3338 private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3339 if (!sUserManager.exists(userId)) return null;
3343 final PackageParser.Package p = ps.pkg;
3347 // Filter out ephemeral app metadata:
3348 // * The system/shell/root can see metadata for any app
3349 // * An installed app can see metadata for 1) other installed apps
3350 // and 2) ephemeral apps that have explicitly interacted with it
3351 // * Ephemeral apps can only see their own data and exposed installed apps
3352 // * Holding a signature permission allows seeing instant apps
3353 final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
3354 if (callingAppId != Process.SYSTEM_UID
3355 && callingAppId != Process.SHELL_UID
3356 && callingAppId != Process.ROOT_UID
3357 && checkUidPermission(Manifest.permission.ACCESS_INSTANT_APPS,
3358 Binder.getCallingUid()) != PackageManager.PERMISSION_GRANTED) {
3359 final String instantAppPackageName = getInstantAppPackageName(Binder.getCallingUid());
3360 if (instantAppPackageName != null) {
3361 // ephemeral apps can only get information on themselves or
3362 // installed apps that are exposed.
3363 if (!instantAppPackageName.equals(p.packageName)
3364 && (ps.getInstantApp(userId) || !p.visibleToInstantApps)) {
3368 if (ps.getInstantApp(userId)) {
3369 // only get access to the ephemeral app if we've been granted access
3370 if (!mInstantAppRegistry.isInstantAccessGranted(
3371 userId, callingAppId, ps.appId)) {
3378 final PermissionsState permissionsState = ps.getPermissionsState();
3380 // Compute GIDs only if requested
3381 final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3382 ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3383 // Compute granted permissions only if package has requested permissions
3384 final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3385 ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3386 final PackageUserState state = ps.readUserState(userId);
3388 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
3390 flags |= MATCH_ANY_USER;
3393 PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags,
3394 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3396 if (packageInfo == null) {
3400 rebaseEnabledOverlays(packageInfo.applicationInfo, userId);
3402 packageInfo.packageName = packageInfo.applicationInfo.packageName =
3403 resolveExternalPackageNameLPr(p);
3409 public void checkPackageStartable(String packageName, int userId) {
3410 final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3412 synchronized (mPackages) {
3413 final PackageSetting ps = mSettings.mPackages.get(packageName);
3415 throw new SecurityException("Package " + packageName + " was not found!");
3418 if (!ps.getInstalled(userId)) {
3419 throw new SecurityException(
3420 "Package " + packageName + " was not installed for user " + userId + "!");
3423 if (mSafeMode && !ps.isSystem()) {
3424 throw new SecurityException("Package " + packageName + " not a system app!");
3427 if (mFrozenPackages.contains(packageName)) {
3428 throw new SecurityException("Package " + packageName + " is currently frozen!");
3431 if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware()
3432 || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) {
3433 throw new SecurityException("Package " + packageName + " is not encryption aware!");
3439 public boolean isPackageAvailable(String packageName, int userId) {
3440 if (!sUserManager.exists(userId)) return false;
3441 enforceCrossUserPermission(Binder.getCallingUid(), userId,
3442 false /* requireFullPermission */, false /* checkShell */, "is package available");
3443 synchronized (mPackages) {
3444 PackageParser.Package p = mPackages.get(packageName);
3446 final PackageSetting ps = (PackageSetting) p.mExtras;
3448 final PackageUserState state = ps.readUserState(userId);
3449 if (state != null) {
3450 return PackageParser.isAvailable(state);
3459 public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3460 return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
3465 public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
3466 int flags, int userId) {
3467 return getPackageInfoInternal(versionedPackage.getPackageName(),
3468 // TODO: We will change version code to long, so in the new API it is long
3469 (int) versionedPackage.getVersionCode(), flags, userId);
3472 private PackageInfo getPackageInfoInternal(String packageName, int versionCode,
3473 int flags, int userId) {
3474 if (!sUserManager.exists(userId)) return null;
3475 flags = updateFlagsForPackage(flags, userId, packageName);
3476 enforceCrossUserPermission(Binder.getCallingUid(), userId,
3477 false /* requireFullPermission */, false /* checkShell */, "get package info");
3480 synchronized (mPackages) {
3481 // Normalize package name to handle renamed packages and static libs
3482 packageName = resolveInternalPackageNameLPr(packageName, versionCode);
3484 final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
3485 if (matchFactoryOnly) {
3486 final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
3488 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
3491 return generatePackageInfo(ps, flags, userId);
3495 PackageParser.Package p = mPackages.get(packageName);
3496 if (matchFactoryOnly && p != null && !isSystemApp(p)) {
3499 if (DEBUG_PACKAGE_INFO)
3500 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
3502 if (filterSharedLibPackageLPr((PackageSetting) p.mExtras,
3503 Binder.getCallingUid(), userId)) {
3506 return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
3508 if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
3509 final PackageSetting ps = mSettings.mPackages.get(packageName);
3510 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
3513 return generatePackageInfo(ps, flags, userId);
3520 private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId) {
3521 // System/shell/root get to see all static libs
3522 final int appId = UserHandle.getAppId(uid);
3523 if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
3524 || appId == Process.ROOT_UID) {
3528 // No package means no static lib as it is always on internal storage
3529 if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) {
3533 final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName,
3534 ps.pkg.staticSharedLibVersion);
3535 if (libEntry == null) {
3539 final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
3540 final String[] uidPackageNames = getPackagesForUid(resolvedUid);
3541 if (uidPackageNames == null) {
3545 for (String uidPackageName : uidPackageNames) {
3546 if (ps.name.equals(uidPackageName)) {
3549 PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
3550 if (uidPs != null) {
3551 final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
3552 libEntry.info.getName());
3556 if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getVersion()) {
3565 public String[] currentToCanonicalPackageNames(String[] names) {
3566 String[] out = new String[names.length];
3568 synchronized (mPackages) {
3569 for (int i=names.length-1; i>=0; i--) {
3570 PackageSetting ps = mSettings.mPackages.get(names[i]);
3571 out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
3578 public String[] canonicalToCurrentPackageNames(String[] names) {
3579 String[] out = new String[names.length];
3581 synchronized (mPackages) {
3582 for (int i=names.length-1; i>=0; i--) {
3583 String cur = mSettings.getRenamedPackageLPr(names[i]);
3584 out[i] = cur != null ? cur : names[i];
3591 public int getPackageUid(String packageName, int flags, int userId) {
3592 if (!sUserManager.exists(userId)) return -1;
3593 flags = updateFlagsForPackage(flags, userId, packageName);
3594 enforceCrossUserPermission(Binder.getCallingUid(), userId,
3595 false /* requireFullPermission */, false /* checkShell */, "get package uid");
3598 synchronized (mPackages) {
3599 final PackageParser.Package p = mPackages.get(packageName);
3600 if (p != null && p.isMatch(flags)) {
3601 return UserHandle.getUid(userId, p.applicationInfo.uid);
3603 if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
3604 final PackageSetting ps = mSettings.mPackages.get(packageName);
3605 if (ps != null && ps.isMatch(flags)) {
3606 return UserHandle.getUid(userId, ps.appId);
3615 public int[] getPackageGids(String packageName, int flags, int userId) {
3616 if (!sUserManager.exists(userId)) return null;
3617 flags = updateFlagsForPackage(flags, userId, packageName);
3618 enforceCrossUserPermission(Binder.getCallingUid(), userId,
3619 false /* requireFullPermission */, false /* checkShell */,
3623 synchronized (mPackages) {
3624 final PackageParser.Package p = mPackages.get(packageName);
3625 if (p != null && p.isMatch(flags)) {
3626 PackageSetting ps = (PackageSetting) p.mExtras;
3627 // TODO: Shouldn't this be checking for package installed state for userId and
3629 return ps.getPermissionsState().computeGids(userId);
3631 if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
3632 final PackageSetting ps = mSettings.mPackages.get(packageName);
3633 if (ps != null && ps.isMatch(flags)) {
3634 return ps.getPermissionsState().computeGids(userId);
3642 static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) {
3643 if (bp.perm != null) {
3644 return PackageParser.generatePermissionInfo(bp.perm, flags);
3646 PermissionInfo pi = new PermissionInfo();
3648 pi.packageName = bp.sourcePackage;
3649 pi.nonLocalizedLabel = bp.name;
3650 pi.protectionLevel = bp.protectionLevel;
3655 public PermissionInfo getPermissionInfo(String name, int flags) {
3657 synchronized (mPackages) {
3658 final BasePermission p = mSettings.mPermissions.get(name);
3660 return generatePermissionInfo(p, flags);
3667 public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group,
3670 synchronized (mPackages) {
3671 if (group != null && !mPermissionGroups.containsKey(group)) {
3672 // This is thrown as NameNotFoundException
3676 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
3677 for (BasePermission p : mSettings.mPermissions.values()) {
3678 if (group == null) {
3679 if (p.perm == null || p.perm.info.group == null) {
3680 out.add(generatePermissionInfo(p, flags));
3683 if (p.perm != null && group.equals(p.perm.info.group)) {
3684 out.add(PackageParser.generatePermissionInfo(p.perm, flags));
3688 return new ParceledListSlice<>(out);
3693 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
3695 synchronized (mPackages) {
3696 return PackageParser.generatePermissionGroupInfo(
3697 mPermissionGroups.get(name), flags);
3702 public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
3704 synchronized (mPackages) {
3705 final int N = mPermissionGroups.size();
3706 ArrayList<PermissionGroupInfo> out
3707 = new ArrayList<PermissionGroupInfo>(N);
3708 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
3709 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
3711 return new ParceledListSlice<>(out);
3715 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
3716 int uid, int userId) {
3717 if (!sUserManager.exists(userId)) return null;
3718 PackageSetting ps = mSettings.mPackages.get(packageName);
3720 if (filterSharedLibPackageLPr(ps, uid, userId)) {
3723 if (ps.pkg == null) {
3724 final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
3725 if (pInfo != null) {
3726 return pInfo.applicationInfo;
3730 ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
3731 ps.readUserState(userId), userId);
3733 rebaseEnabledOverlays(ai, userId);
3734 ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
3742 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
3743 if (!sUserManager.exists(userId)) return null;
3744 flags = updateFlagsForApplication(flags, userId, packageName);
3745 enforceCrossUserPermission(Binder.getCallingUid(), userId,
3746 false /* requireFullPermission */, false /* checkShell */, "get application info");
3749 synchronized (mPackages) {
3750 // Normalize package name to handle renamed packages and static libs
3751 packageName = resolveInternalPackageNameLPr(packageName,
3752 PackageManager.VERSION_CODE_HIGHEST);
3754 PackageParser.Package p = mPackages.get(packageName);
3755 if (DEBUG_PACKAGE_INFO) Log.v(
3756 TAG, "getApplicationInfo " + packageName
3759 PackageSetting ps = mSettings.mPackages.get(packageName);
3760 if (ps == null) return null;
3761 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
3764 // Note: isEnabledLP() does not apply here - always return info
3765 ApplicationInfo ai = PackageParser.generateApplicationInfo(
3766 p, flags, ps.readUserState(userId), userId);
3768 rebaseEnabledOverlays(ai, userId);
3769 ai.packageName = resolveExternalPackageNameLPr(p);
3773 if ("android".equals(packageName)||"system".equals(packageName)) {
3774 return mAndroidApplication;
3776 if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
3777 // Already generates the external package name
3778 return generateApplicationInfoFromSettingsLPw(packageName,
3779 Binder.getCallingUid(), flags, userId);
3785 private void rebaseEnabledOverlays(@NonNull ApplicationInfo ai, int userId) {
3786 List<String> paths = new ArrayList<>();
3787 ArrayMap<String, ArrayList<String>> userSpecificOverlays =
3788 mEnabledOverlayPaths.get(userId);
3789 if (userSpecificOverlays != null) {
3790 if (!"android".equals(ai.packageName)) {
3791 ArrayList<String> frameworkOverlays = userSpecificOverlays.get("android");
3792 if (frameworkOverlays != null) {
3793 paths.addAll(frameworkOverlays);
3797 ArrayList<String> appOverlays = userSpecificOverlays.get(ai.packageName);
3798 if (appOverlays != null) {
3799 paths.addAll(appOverlays);
3802 ai.resourceDirs = paths.size() > 0 ? paths.toArray(new String[paths.size()]) : null;
3805 private String normalizePackageNameLPr(String packageName) {
3806 String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
3807 return normalizedPackageName != null ? normalizedPackageName : packageName;
3811 public void deletePreloadsFileCache() {
3812 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
3813 throw new SecurityException("Only system or settings may call deletePreloadsFileCache");
3815 File dir = Environment.getDataPreloadsFileCacheDirectory();
3816 Slog.i(TAG, "Deleting preloaded file cache " + dir);
3817 FileUtils.deleteContents(dir);
3821 public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
3822 final IPackageDataObserver observer) {
3823 mContext.enforceCallingOrSelfPermission(
3824 android.Manifest.permission.CLEAR_APP_CACHE, null);
3825 mHandler.post(() -> {
3826 boolean success = false;
3828 freeStorage(volumeUuid, freeStorageSize, 0);
3830 } catch (IOException e) {
3833 if (observer != null) {
3835 observer.onRemoveCompleted(null, success);
3836 } catch (RemoteException e) {
3844 public void freeStorage(final String volumeUuid, final long freeStorageSize,
3845 final IntentSender pi) {
3846 mContext.enforceCallingOrSelfPermission(
3847 android.Manifest.permission.CLEAR_APP_CACHE, TAG);
3848 mHandler.post(() -> {
3849 boolean success = false;
3851 freeStorage(volumeUuid, freeStorageSize, 0);
3853 } catch (IOException e) {
3858 pi.sendIntent(null, success ? 1 : 0, null, null, null);
3859 } catch (SendIntentException e) {
3867 * Blocking call to clear various types of cached data across the system
3868 * until the requested bytes are available.
3870 public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
3871 final StorageManager storage = mContext.getSystemService(StorageManager.class);
3872 final File file = storage.findPathForUuid(volumeUuid);
3873 if (file.getUsableSpace() >= bytes) return;
3875 if (ENABLE_FREE_CACHE_V2) {
3876 final boolean aggressive = (storageFlags
3877 & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
3878 final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
3881 // 1. Pre-flight to determine if we have any chance to succeed
3882 // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
3883 if (internalVolume && (aggressive || SystemProperties
3884 .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
3885 deletePreloadsFileCache();
3886 if (file.getUsableSpace() >= bytes) return;
3889 // 3. Consider parsed APK data (aggressive only)
3890 if (internalVolume && aggressive) {
3891 FileUtils.deleteContents(mCacheDir);
3892 if (file.getUsableSpace() >= bytes) return;
3895 // 4. Consider cached app data (above quotas)
3897 mInstaller.freeCache(volumeUuid, bytes, Installer.FLAG_FREE_CACHE_V2);
3898 } catch (InstallerException ignored) {
3900 if (file.getUsableSpace() >= bytes) return;
3902 // 5. Consider shared libraries with refcount=0 and age>2h
3903 // 6. Consider dexopt output (aggressive only)
3904 // 7. Consider ephemeral apps not used in last week
3906 // 8. Consider cached app data (below quotas)
3908 mInstaller.freeCache(volumeUuid, bytes, Installer.FLAG_FREE_CACHE_V2
3909 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
3910 } catch (InstallerException ignored) {
3912 if (file.getUsableSpace() >= bytes) return;
3914 // 9. Consider DropBox entries
3915 // 10. Consider ephemeral cookies
3919 mInstaller.freeCache(volumeUuid, bytes, 0);
3920 } catch (InstallerException ignored) {
3922 if (file.getUsableSpace() >= bytes) return;
3925 throw new IOException("Failed to free " + bytes + " on storage device at " + file);
3929 * Update given flags based on encryption status of current user.
3931 private int updateFlags(int flags, int userId) {
3932 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
3933 | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
3934 // Caller expressed an explicit opinion about what encryption
3935 // aware/unaware components they want to see, so fall through and
3936 // give them what they want
3938 // Caller expressed no opinion, so match based on user state
3939 if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
3940 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3942 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
3948 private UserManagerInternal getUserManagerInternal() {
3949 if (mUserManagerInternal == null) {
3950 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
3952 return mUserManagerInternal;
3955 private DeviceIdleController.LocalService getDeviceIdleController() {
3956 if (mDeviceIdleController == null) {
3957 mDeviceIdleController =
3958 LocalServices.getService(DeviceIdleController.LocalService.class);
3960 return mDeviceIdleController;
3964 * Update given flags when being used to request {@link PackageInfo}.
3966 private int updateFlagsForPackage(int flags, int userId, Object cookie) {
3967 final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
3968 boolean triaged = true;
3969 if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
3970 | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
3971 // Caller is asking for component details, so they'd better be
3972 // asking for specific encryption matching behavior, or be triaged
3973 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
3974 | PackageManager.MATCH_DIRECT_BOOT_AWARE
3975 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3979 if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
3980 | PackageManager.MATCH_SYSTEM_ONLY
3981 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3984 if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
3985 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
3986 "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
3987 + Debug.getCallers(5));
3988 } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
3989 && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
3990 // If the caller wants all packages and has a restricted profile associated with it,
3991 // then match all users. This is to make sure that launchers that need to access work
3992 // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
3993 // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
3994 flags |= PackageManager.MATCH_ANY_USER;
3996 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
3997 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
3998 + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4000 return updateFlags(flags, userId);
4004 * Update given flags when being used to request {@link ApplicationInfo}.
4006 private int updateFlagsForApplication(int flags, int userId, Object cookie) {
4007 return updateFlagsForPackage(flags, userId, cookie);
4011 * Update given flags when being used to request {@link ComponentInfo}.
4013 private int updateFlagsForComponent(int flags, int userId, Object cookie) {
4014 if (cookie instanceof Intent) {
4015 if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
4016 flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
4020 boolean triaged = true;
4021 // Caller is asking for component details, so they'd better be
4022 // asking for specific encryption matching behavior, or be triaged
4023 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4024 | PackageManager.MATCH_DIRECT_BOOT_AWARE
4025 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4028 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4029 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4030 + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4033 return updateFlags(flags, userId);
4037 * Update given intent when being used to request {@link ResolveInfo}.
4039 private Intent updateIntentForResolve(Intent intent) {
4040 if (intent.getSelector() != null) {
4041 intent = intent.getSelector();
4043 if (DEBUG_PREFERRED) {
4044 intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4050 * Update given flags when being used to request {@link ResolveInfo}.
4051 * <p>Instant apps are resolved specially, depending upon context. Minimally,
4052 * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
4053 * flag set. However, this flag is only honoured in three circumstances:
4055 * <li>when called from a system process</li>
4056 * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
4057 * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
4058 * action and a {@code android.intent.category.BROWSABLE} category</li>
4061 int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4062 boolean includeInstantApps) {
4063 // Safe mode means we shouldn't match any third-party components
4065 flags |= PackageManager.MATCH_SYSTEM_ONLY;
4067 if (getInstantAppPackageName(callingUid) != null) {
4068 // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
4069 flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4070 flags |= PackageManager.MATCH_INSTANT;
4072 // Otherwise, prevent leaking ephemeral components
4073 final boolean isSpecialProcess =
4074 callingUid == Process.SYSTEM_UID
4075 || callingUid == Process.SHELL_UID
4077 final boolean allowMatchInstant =
4079 && Intent.ACTION_VIEW.equals(intent.getAction())
4080 && intent.hasCategory(Intent.CATEGORY_BROWSABLE)
4081 && hasWebURI(intent))
4083 || mContext.checkCallingOrSelfPermission(
4084 android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED;
4085 flags &= ~PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4086 if (!allowMatchInstant) {
4087 flags &= ~PackageManager.MATCH_INSTANT;
4090 return updateFlagsForComponent(flags, userId, intent /*cookie*/);
4093 private ActivityInfo generateActivityInfo(ActivityInfo ai, int flags, PackageUserState state,
4095 ActivityInfo ret = PackageParser.generateActivityInfo(ai, flags, state, userId);
4097 rebaseEnabledOverlays(ret.applicationInfo, userId);
4102 private ActivityInfo generateActivityInfo(PackageParser.Activity a, int flags,
4103 PackageUserState state, int userId) {
4104 ActivityInfo ai = PackageParser.generateActivityInfo(a, flags, state, userId);
4106 rebaseEnabledOverlays(ai.applicationInfo, userId);
4112 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
4113 if (!sUserManager.exists(userId)) return null;
4114 flags = updateFlagsForComponent(flags, userId, component);
4115 enforceCrossUserPermission(Binder.getCallingUid(), userId,
4116 false /* requireFullPermission */, false /* checkShell */, "get activity info");
4117 synchronized (mPackages) {
4118 PackageParser.Activity a = mActivities.mActivities.get(component);
4120 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
4121 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4122 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4123 if (ps == null) return null;
4124 return generateActivityInfo(a, flags, ps.readUserState(userId), userId);
4126 if (mResolveComponentName.equals(component)) {
4127 return generateActivityInfo(mResolveActivity, flags, new PackageUserState(),
4135 public boolean activitySupportsIntent(ComponentName component, Intent intent,
4136 String resolvedType) {
4137 synchronized (mPackages) {
4138 if (component.equals(mResolveComponentName)) {
4139 // The resolver supports EVERYTHING!
4142 PackageParser.Activity a = mActivities.mActivities.get(component);
4146 for (int i=0; i<a.intents.size(); i++) {
4147 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
4148 intent.getData(), intent.getCategories(), TAG) >= 0) {
4157 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
4158 if (!sUserManager.exists(userId)) return null;
4159 flags = updateFlagsForComponent(flags, userId, component);
4160 enforceCrossUserPermission(Binder.getCallingUid(), userId,
4161 false /* requireFullPermission */, false /* checkShell */, "get receiver info");
4162 synchronized (mPackages) {
4163 PackageParser.Activity a = mReceivers.mActivities.get(component);
4164 if (DEBUG_PACKAGE_INFO) Log.v(
4165 TAG, "getReceiverInfo " + component + ": " + a);
4166 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4167 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4168 if (ps == null) return null;
4169 return generateActivityInfo(a, flags, ps.readUserState(userId), userId);
4176 public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(int flags, int userId) {
4177 if (!sUserManager.exists(userId)) return null;
4178 Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
4180 flags = updateFlagsForPackage(flags, userId, null);
4182 final boolean canSeeStaticLibraries =
4183 mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
4184 == PERMISSION_GRANTED
4185 || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
4186 == PERMISSION_GRANTED
4187 || mContext.checkCallingOrSelfPermission(REQUEST_INSTALL_PACKAGES)
4188 == PERMISSION_GRANTED
4189 || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
4190 == PERMISSION_GRANTED;
4192 synchronized (mPackages) {
4193 List<SharedLibraryInfo> result = null;
4195 final int libCount = mSharedLibraries.size();
4196 for (int i = 0; i < libCount; i++) {
4197 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4198 if (versionedLib == null) {
4202 final int versionCount = versionedLib.size();
4203 for (int j = 0; j < versionCount; j++) {
4204 SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4205 if (!canSeeStaticLibraries && libInfo.isStatic()) {
4208 final long identity = Binder.clearCallingIdentity();
4210 // TODO: We will change version code to long, so in the new API it is long
4211 PackageInfo packageInfo = getPackageInfoVersioned(
4212 libInfo.getDeclaringPackage(), flags, userId);
4213 if (packageInfo == null) {
4217 Binder.restoreCallingIdentity(identity);
4220 SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(),
4221 libInfo.getVersion(), libInfo.getType(), libInfo.getDeclaringPackage(),
4222 getPackagesUsingSharedLibraryLPr(libInfo, flags, userId));
4224 if (result == null) {
4225 result = new ArrayList<>();
4227 result.add(resLibInfo);
4231 return result != null ? new ParceledListSlice<>(result) : null;
4235 private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
4236 SharedLibraryInfo libInfo, int flags, int userId) {
4237 List<VersionedPackage> versionedPackages = null;
4238 final int packageCount = mSettings.mPackages.size();
4239 for (int i = 0; i < packageCount; i++) {
4240 PackageSetting ps = mSettings.mPackages.valueAt(i);
4246 if (!ps.getUserState().get(userId).isAvailable(flags)) {
4250 final String libName = libInfo.getName();
4251 if (libInfo.isStatic()) {
4252 final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
4256 if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getVersion()) {
4259 if (versionedPackages == null) {
4260 versionedPackages = new ArrayList<>();
4262 // If the dependent is a static shared lib, use the public package name
4263 String dependentPackageName = ps.name;
4264 if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4265 dependentPackageName = ps.pkg.manifestPackageName;
4267 versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
4268 } else if (ps.pkg != null) {
4269 if (ArrayUtils.contains(ps.pkg.usesLibraries, libName)
4270 || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) {
4271 if (versionedPackages == null) {
4272 versionedPackages = new ArrayList<>();
4274 versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
4279 return versionedPackages;
4283 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
4284 if (!sUserManager.exists(userId)) return null;
4285 flags = updateFlagsForComponent(flags, userId, component);
4286 enforceCrossUserPermission(Binder.getCallingUid(), userId,
4287 false /* requireFullPermission */, false /* checkShell */, "get service info");
4288 synchronized (mPackages) {
4289 PackageParser.Service s = mServices.mServices.get(component);
4290 if (DEBUG_PACKAGE_INFO) Log.v(
4291 TAG, "getServiceInfo " + component + ": " + s);
4292 if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
4293 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4294 if (ps == null) return null;
4295 ServiceInfo si = PackageParser.generateServiceInfo(s, flags,
4296 ps.readUserState(userId), userId);
4298 rebaseEnabledOverlays(si.applicationInfo, userId);
4307 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
4308 if (!sUserManager.exists(userId)) return null;
4309 flags = updateFlagsForComponent(flags, userId, component);
4310 enforceCrossUserPermission(Binder.getCallingUid(), userId,
4311 false /* requireFullPermission */, false /* checkShell */, "get provider info");
4312 synchronized (mPackages) {
4313 PackageParser.Provider p = mProviders.mProviders.get(component);
4314 if (DEBUG_PACKAGE_INFO) Log.v(
4315 TAG, "getProviderInfo " + component + ": " + p);
4316 if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
4317 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4318 if (ps == null) return null;
4319 ProviderInfo pi = PackageParser.generateProviderInfo(p, flags,
4320 ps.readUserState(userId), userId);
4322 rebaseEnabledOverlays(pi.applicationInfo, userId);
4331 public String[] getSystemSharedLibraryNames() {
4332 synchronized (mPackages) {
4333 Set<String> libs = null;
4334 final int libCount = mSharedLibraries.size();
4335 for (int i = 0; i < libCount; i++) {
4336 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4337 if (versionedLib == null) {
4340 final int versionCount = versionedLib.size();
4341 for (int j = 0; j < versionCount; j++) {
4342 SharedLibraryEntry libEntry = versionedLib.valueAt(j);
4343 if (!libEntry.info.isStatic()) {
4345 libs = new ArraySet<>();
4347 libs.add(libEntry.info.getName());
4350 PackageSetting ps = mSettings.getPackageLPr(libEntry.apk);
4351 if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
4352 UserHandle.getUserId(Binder.getCallingUid()))) {
4354 libs = new ArraySet<>();
4356 libs.add(libEntry.info.getName());
4363 String[] libsArray = new String[libs.size()];
4364 libs.toArray(libsArray);
4373 public @NonNull String getServicesSystemSharedLibraryPackageName() {
4374 synchronized (mPackages) {
4375 return mServicesSystemSharedLibraryPackageName;
4380 public @NonNull String getSharedSystemSharedLibraryPackageName() {
4381 synchronized (mPackages) {
4382 return mSharedSystemSharedLibraryPackageName;
4386 private void updateSequenceNumberLP(String packageName, int[] userList) {
4387 for (int i = userList.length - 1; i >= 0; --i) {
4388 final int userId = userList[i];
4389 SparseArray<String> changedPackages = mChangedPackages.get(userId);
4390 if (changedPackages == null) {
4391 changedPackages = new SparseArray<>();
4392 mChangedPackages.put(userId, changedPackages);
4394 Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
4395 if (sequenceNumbers == null) {
4396 sequenceNumbers = new HashMap<>();
4397 mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
4399 final Integer sequenceNumber = sequenceNumbers.get(packageName);
4400 if (sequenceNumber != null) {
4401 changedPackages.remove(sequenceNumber);
4403 changedPackages.put(mChangedPackagesSequenceNumber, packageName);
4404 sequenceNumbers.put(packageName, mChangedPackagesSequenceNumber);
4406 mChangedPackagesSequenceNumber++;
4410 public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
4411 synchronized (mPackages) {
4412 if (sequenceNumber >= mChangedPackagesSequenceNumber) {
4415 final SparseArray<String> changedPackages = mChangedPackages.get(userId);
4416 if (changedPackages == null) {
4419 final List<String> packageNames =
4420 new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
4421 for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
4422 final String packageName = changedPackages.get(i);
4423 if (packageName != null) {
4424 packageNames.add(packageName);
4427 return packageNames.isEmpty()
4428 ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
4433 public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
4434 ArrayList<FeatureInfo> res;
4435 synchronized (mAvailableFeatures) {
4436 res = new ArrayList<>(mAvailableFeatures.size() + 1);
4437 res.addAll(mAvailableFeatures.values());
4439 final FeatureInfo fi = new FeatureInfo();
4440 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
4441 FeatureInfo.GL_ES_VERSION_UNDEFINED);
4444 return new ParceledListSlice<>(res);
4448 public boolean hasSystemFeature(String name, int version) {
4449 synchronized (mAvailableFeatures) {
4450 final FeatureInfo feat = mAvailableFeatures.get(name);
4454 return feat.version >= version;
4460 public int checkPermission(String permName, String pkgName, int userId) {
4461 if (!sUserManager.exists(userId)) {
4462 return PackageManager.PERMISSION_DENIED;
4465 synchronized (mPackages) {
4466 final PackageParser.Package p = mPackages.get(pkgName);
4467 if (p != null && p.mExtras != null) {
4468 final PackageSetting ps = (PackageSetting) p.mExtras;
4469 final PermissionsState permissionsState = ps.getPermissionsState();
4470 if (permissionsState.hasPermission(permName, userId)) {
4471 return PackageManager.PERMISSION_GRANTED;
4473 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
4474 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
4475 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
4476 return PackageManager.PERMISSION_GRANTED;
4481 return PackageManager.PERMISSION_DENIED;
4485 public int checkUidPermission(String permName, int uid) {
4486 final int userId = UserHandle.getUserId(uid);
4488 if (!sUserManager.exists(userId)) {
4489 return PackageManager.PERMISSION_DENIED;
4492 synchronized (mPackages) {
4493 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4495 final SettingBase ps = (SettingBase) obj;
4496 final PermissionsState permissionsState = ps.getPermissionsState();
4497 if (permissionsState.hasPermission(permName, userId)) {
4498 return PackageManager.PERMISSION_GRANTED;
4500 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
4501 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
4502 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
4503 return PackageManager.PERMISSION_GRANTED;
4506 ArraySet<String> perms = mSystemPermissions.get(uid);
4507 if (perms != null) {
4508 if (perms.contains(permName)) {
4509 return PackageManager.PERMISSION_GRANTED;
4511 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
4512 .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
4513 return PackageManager.PERMISSION_GRANTED;
4519 return PackageManager.PERMISSION_DENIED;
4523 public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
4524 if (UserHandle.getCallingUserId() != userId) {
4525 mContext.enforceCallingPermission(
4526 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
4527 "isPermissionRevokedByPolicy for user " + userId);
4530 if (checkPermission(permission, packageName, userId)
4531 == PackageManager.PERMISSION_GRANTED) {
4535 final long identity = Binder.clearCallingIdentity();
4537 final int flags = getPermissionFlags(permission, packageName, userId);
4538 return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
4540 Binder.restoreCallingIdentity(identity);
4545 public String getPermissionControllerPackageName() {
4546 synchronized (mPackages) {
4547 return mRequiredInstallerPackage;
4552 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
4553 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
4554 * @param checkShell whether to prevent shell from access if there's a debugging restriction
4555 * @param message the message to log on security exception
4557 void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
4558 boolean checkShell, String message) {
4560 throw new IllegalArgumentException("Invalid userId " + userId);
4563 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
4565 if (userId == UserHandle.getUserId(callingUid)) return;
4566 if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
4567 if (requireFullPermission) {
4568 mContext.enforceCallingOrSelfPermission(
4569 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
4572 mContext.enforceCallingOrSelfPermission(
4573 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
4574 } catch (SecurityException se) {
4575 mContext.enforceCallingOrSelfPermission(
4576 android.Manifest.permission.INTERACT_ACROSS_USERS, message);
4582 void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
4583 if (callingUid == Process.SHELL_UID) {
4585 && sUserManager.hasUserRestriction(restriction, userHandle)) {
4586 throw new SecurityException("Shell does not have permission to access user "
4588 } else if (userHandle < 0) {
4589 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
4590 + Debug.getCallers(3));
4595 private BasePermission findPermissionTreeLP(String permName) {
4596 for(BasePermission bp : mSettings.mPermissionTrees.values()) {
4597 if (permName.startsWith(bp.name) &&
4598 permName.length() > bp.name.length() &&
4599 permName.charAt(bp.name.length()) == '.') {
4606 private BasePermission checkPermissionTreeLP(String permName) {
4607 if (permName != null) {
4608 BasePermission bp = findPermissionTreeLP(permName);
4610 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
4613 throw new SecurityException("Calling uid "
4614 + Binder.getCallingUid()
4615 + " is not allowed to add to permission tree "
4616 + bp.name + " owned by uid " + bp.uid);
4619 throw new SecurityException("No permission tree found for " + permName);
4622 static boolean compareStrings(CharSequence s1, CharSequence s2) {
4629 if (s1.getClass() != s2.getClass()) {
4632 return s1.equals(s2);
4635 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
4636 if (pi1.icon != pi2.icon) return false;
4637 if (pi1.logo != pi2.logo) return false;
4638 if (pi1.protectionLevel != pi2.protectionLevel) return false;
4639 if (!compareStrings(pi1.name, pi2.name)) return false;
4640 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
4641 // We'll take care of setting this one.
4642 if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
4643 // These are not currently stored in settings.
4644 //if (!compareStrings(pi1.group, pi2.group)) return false;
4645 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
4646 //if (pi1.labelRes != pi2.labelRes) return false;
4647 //if (pi1.descriptionRes != pi2.descriptionRes) return false;
4651 int permissionInfoFootprint(PermissionInfo info) {
4652 int size = info.name.length();
4653 if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
4654 if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
4658 int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
4660 for (BasePermission perm : mSettings.mPermissions.values()) {
4661 if (perm.uid == tree.uid) {
4662 size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
4668 void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
4669 // We calculate the max size of permissions defined by this uid and throw
4670 // if that plus the size of 'info' would exceed our stated maximum.
4671 if (tree.uid != Process.SYSTEM_UID) {
4672 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
4673 if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
4674 throw new SecurityException("Permission tree size cap exceeded");
4679 boolean addPermissionLocked(PermissionInfo info, boolean async) {
4680 if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
4681 throw new SecurityException("Label must be specified in permission");
4683 BasePermission tree = checkPermissionTreeLP(info.name);
4684 BasePermission bp = mSettings.mPermissions.get(info.name);
4685 boolean added = bp == null;
4686 boolean changed = true;
4687 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
4689 enforcePermissionCapLocked(info, tree);
4690 bp = new BasePermission(info.name, tree.sourcePackage,
4691 BasePermission.TYPE_DYNAMIC);
4692 } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
4693 throw new SecurityException(
4694 "Not allowed to modify non-dynamic permission "
4697 if (bp.protectionLevel == fixedLevel
4698 && bp.perm.owner.equals(tree.perm.owner)
4699 && bp.uid == tree.uid
4700 && comparePermissionInfos(bp.perm.info, info)) {
4704 bp.protectionLevel = fixedLevel;
4705 info = new PermissionInfo(info);
4706 info.protectionLevel = fixedLevel;
4707 bp.perm = new PackageParser.Permission(tree.perm.owner, info);
4708 bp.perm.info.packageName = tree.perm.info.packageName;
4711 mSettings.mPermissions.put(info.name, bp);
4715 mSettings.writeLPr();
4717 scheduleWriteSettingsLocked();
4724 public boolean addPermission(PermissionInfo info) {
4725 synchronized (mPackages) {
4726 return addPermissionLocked(info, false);
4731 public boolean addPermissionAsync(PermissionInfo info) {
4732 synchronized (mPackages) {
4733 return addPermissionLocked(info, true);
4738 public void removePermission(String name) {
4739 synchronized (mPackages) {
4740 checkPermissionTreeLP(name);
4741 BasePermission bp = mSettings.mPermissions.get(name);
4743 if (bp.type != BasePermission.TYPE_DYNAMIC) {
4744 throw new SecurityException(
4745 "Not allowed to modify non-dynamic permission "
4748 mSettings.mPermissions.remove(name);
4749 mSettings.writeLPr();
4754 private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg,
4755 BasePermission bp) {
4756 int index = pkg.requestedPermissions.indexOf(bp.name);
4758 throw new SecurityException("Package " + pkg.packageName
4759 + " has not requested permission " + bp.name);
4761 if (!bp.isRuntime() && !bp.isDevelopment()) {
4762 throw new SecurityException("Permission " + bp.name
4763 + " is not a changeable permission type");
4768 public void grantRuntimePermission(String packageName, String name, final int userId) {
4769 grantRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
4772 private void grantRuntimePermission(String packageName, String name, final int userId,
4773 boolean overridePolicy) {
4774 if (!sUserManager.exists(userId)) {
4775 Log.e(TAG, "No such user:" + userId);
4779 mContext.enforceCallingOrSelfPermission(
4780 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
4781 "grantRuntimePermission");
4783 enforceCrossUserPermission(Binder.getCallingUid(), userId,
4784 true /* requireFullPermission */, true /* checkShell */,
4785 "grantRuntimePermission");
4788 final SettingBase sb;
4790 synchronized (mPackages) {
4791 final PackageParser.Package pkg = mPackages.get(packageName);
4793 throw new IllegalArgumentException("Unknown package: " + packageName);
4796 final BasePermission bp = mSettings.mPermissions.get(name);
4798 throw new IllegalArgumentException("Unknown permission: " + name);
4801 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
4803 // If a permission review is required for legacy apps we represent
4804 // their permissions as always granted runtime ones since we need
4805 // to keep the review required permission flag per user while an
4806 // install permission's state is shared across all users.
4807 if (mPermissionReviewRequired
4808 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
4809 && bp.isRuntime()) {
4813 uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
4814 sb = (SettingBase) pkg.mExtras;
4816 throw new IllegalArgumentException("Unknown package: " + packageName);
4819 final PermissionsState permissionsState = sb.getPermissionsState();
4821 final int flags = permissionsState.getPermissionFlags(name, userId);
4822 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
4823 throw new SecurityException("Cannot grant system fixed permission "
4824 + name + " for package " + packageName);
4826 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
4827 throw new SecurityException("Cannot grant policy fixed permission "
4828 + name + " for package " + packageName);
4831 if (bp.isDevelopment()) {
4832 // Development permissions must be handled specially, since they are not
4833 // normal runtime permissions. For now they apply to all users.
4834 if (permissionsState.grantInstallPermission(bp) !=
4835 PermissionsState.PERMISSION_OPERATION_FAILURE) {
4836 scheduleWriteSettingsLocked();
4841 final PackageSetting ps = mSettings.mPackages.get(packageName);
4842 if (ps.getInstantApp(userId) && !bp.isInstant()) {
4843 throw new SecurityException("Cannot grant non-ephemeral permission"
4844 + name + " for package " + packageName);
4847 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
4848 Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
4852 final int result = permissionsState.grantRuntimePermission(bp, userId);
4854 case PermissionsState.PERMISSION_OPERATION_FAILURE: {
4858 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
4859 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
4860 mHandler.post(new Runnable() {
4863 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
4870 if (bp.isRuntime()) {
4871 logPermissionGranted(mContext, name, packageName);
4874 mOnPermissionChangeListeners.onPermissionsChanged(uid);
4876 // Not critical if that is lost - app has to request again.
4877 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
4880 // Only need to do this if user is initialized. Otherwise it's a new user
4881 // and there are no processes running as the user yet and there's no need
4882 // to make an expensive call to remount processes for the changed permissions.
4883 if (READ_EXTERNAL_STORAGE.equals(name)
4884 || WRITE_EXTERNAL_STORAGE.equals(name)) {
4885 final long token = Binder.clearCallingIdentity();
4887 if (sUserManager.isInitialized(userId)) {
4888 StorageManagerInternal storageManagerInternal = LocalServices.getService(
4889 StorageManagerInternal.class);
4890 storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
4893 Binder.restoreCallingIdentity(token);
4899 public void revokeRuntimePermission(String packageName, String name, int userId) {
4900 revokeRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
4903 private void revokeRuntimePermission(String packageName, String name, int userId,
4904 boolean overridePolicy) {
4905 if (!sUserManager.exists(userId)) {
4906 Log.e(TAG, "No such user:" + userId);
4910 mContext.enforceCallingOrSelfPermission(
4911 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
4912 "revokeRuntimePermission");
4914 enforceCrossUserPermission(Binder.getCallingUid(), userId,
4915 true /* requireFullPermission */, true /* checkShell */,
4916 "revokeRuntimePermission");
4920 synchronized (mPackages) {
4921 final PackageParser.Package pkg = mPackages.get(packageName);
4923 throw new IllegalArgumentException("Unknown package: " + packageName);
4926 final BasePermission bp = mSettings.mPermissions.get(name);
4928 throw new IllegalArgumentException("Unknown permission: " + name);
4931 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
4933 // If a permission review is required for legacy apps we represent
4934 // their permissions as always granted runtime ones since we need
4935 // to keep the review required permission flag per user while an
4936 // install permission's state is shared across all users.
4937 if (mPermissionReviewRequired
4938 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
4939 && bp.isRuntime()) {
4943 SettingBase sb = (SettingBase) pkg.mExtras;
4945 throw new IllegalArgumentException("Unknown package: " + packageName);
4948 final PermissionsState permissionsState = sb.getPermissionsState();
4950 final int flags = permissionsState.getPermissionFlags(name, userId);
4951 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
4952 throw new SecurityException("Cannot revoke system fixed permission "
4953 + name + " for package " + packageName);
4955 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
4956 throw new SecurityException("Cannot revoke policy fixed permission "
4957 + name + " for package " + packageName);
4960 if (bp.isDevelopment()) {
4961 // Development permissions must be handled specially, since they are not
4962 // normal runtime permissions. For now they apply to all users.
4963 if (permissionsState.revokeInstallPermission(bp) !=
4964 PermissionsState.PERMISSION_OPERATION_FAILURE) {
4965 scheduleWriteSettingsLocked();
4970 if (permissionsState.revokeRuntimePermission(bp, userId) ==
4971 PermissionsState.PERMISSION_OPERATION_FAILURE) {
4975 if (bp.isRuntime()) {
4976 logPermissionRevoked(mContext, name, packageName);
4979 mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
4981 // Critical, after this call app should never have the permission.
4982 mSettings.writeRuntimePermissionsForUserLPr(userId, true);
4984 appId = UserHandle.getAppId(pkg.applicationInfo.uid);
4987 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
4991 * Get the first event id for the permission.
4993 * <p>There are four events for each permission: <ul>
4994 * <li>Request permission: first id + 0</li>
4995 * <li>Grant permission: first id + 1</li>
4996 * <li>Request for permission denied: first id + 2</li>
4997 * <li>Revoke permission: first id + 3</li>
5000 * @param name name of the permission
5002 * @return The first event id for the permission
5004 private static int getBaseEventId(@NonNull String name) {
5005 int eventIdIndex = ALL_DANGEROUS_PERMISSIONS.indexOf(name);
5007 if (eventIdIndex == -1) {
5008 if (AppOpsManager.permissionToOpCode(name) == AppOpsManager.OP_NONE
5009 || "user".equals(Build.TYPE)) {
5010 Log.i(TAG, "Unknown permission " + name);
5012 return MetricsEvent.ACTION_PERMISSION_REQUEST_UNKNOWN;
5014 // Most likely #ALL_DANGEROUS_PERMISSIONS needs to be updated.
5017 // - EventLogger#ALL_DANGEROUS_PERMISSIONS
5018 // - metrics_constants.proto
5019 throw new IllegalStateException("Unknown permission " + name);
5023 return MetricsEvent.ACTION_PERMISSION_REQUEST_READ_CALENDAR + eventIdIndex * 4;
5027 * Log that a permission was revoked.
5029 * @param context Context of the caller
5030 * @param name name of the permission
5031 * @param packageName package permission if for
5033 private static void logPermissionRevoked(@NonNull Context context, @NonNull String name,
5034 @NonNull String packageName) {
5035 MetricsLogger.action(context, getBaseEventId(name) + 3, packageName);
5039 * Log that a permission request was granted.
5041 * @param context Context of the caller
5042 * @param name name of the permission
5043 * @param packageName package permission if for
5045 private static void logPermissionGranted(@NonNull Context context, @NonNull String name,
5046 @NonNull String packageName) {
5047 MetricsLogger.action(context, getBaseEventId(name) + 1, packageName);
5051 public void resetRuntimePermissions() {
5052 mContext.enforceCallingOrSelfPermission(
5053 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5054 "revokeRuntimePermission");
5056 int callingUid = Binder.getCallingUid();
5057 if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5058 mContext.enforceCallingOrSelfPermission(
5059 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5060 "resetRuntimePermissions");
5063 synchronized (mPackages) {
5064 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
5065 for (int userId : UserManagerService.getInstance().getUserIds()) {
5066 final int packageCount = mPackages.size();
5067 for (int i = 0; i < packageCount; i++) {
5068 PackageParser.Package pkg = mPackages.valueAt(i);
5069 if (!(pkg.mExtras instanceof PackageSetting)) {
5072 PackageSetting ps = (PackageSetting) pkg.mExtras;
5073 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
5080 public int getPermissionFlags(String name, String packageName, int userId) {
5081 if (!sUserManager.exists(userId)) {
5085 enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
5087 enforceCrossUserPermission(Binder.getCallingUid(), userId,
5088 true /* requireFullPermission */, false /* checkShell */,
5089 "getPermissionFlags");
5091 synchronized (mPackages) {
5092 final PackageParser.Package pkg = mPackages.get(packageName);
5097 final BasePermission bp = mSettings.mPermissions.get(name);
5102 SettingBase sb = (SettingBase) pkg.mExtras;
5107 PermissionsState permissionsState = sb.getPermissionsState();
5108 return permissionsState.getPermissionFlags(name, userId);
5113 public void updatePermissionFlags(String name, String packageName, int flagMask,
5114 int flagValues, int userId) {
5115 if (!sUserManager.exists(userId)) {
5119 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
5121 enforceCrossUserPermission(Binder.getCallingUid(), userId,
5122 true /* requireFullPermission */, true /* checkShell */,
5123 "updatePermissionFlags");
5125 // Only the system can change these flags and nothing else.
5126 if (getCallingUid() != Process.SYSTEM_UID) {
5127 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5128 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5129 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
5130 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
5131 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
5134 synchronized (mPackages) {
5135 final PackageParser.Package pkg = mPackages.get(packageName);
5137 throw new IllegalArgumentException("Unknown package: " + packageName);
5140 final BasePermission bp = mSettings.mPermissions.get(name);
5142 throw new IllegalArgumentException("Unknown permission: " + name);
5145 SettingBase sb = (SettingBase) pkg.mExtras;
5147 throw new IllegalArgumentException("Unknown package: " + packageName);
5150 PermissionsState permissionsState = sb.getPermissionsState();
5152 boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
5154 if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
5155 // Install and runtime permissions are stored in different places,
5156 // so figure out what permission changed and persist the change.
5157 if (permissionsState.getInstallPermissionState(name) != null) {
5158 scheduleWriteSettingsLocked();
5159 } else if (permissionsState.getRuntimePermissionState(name, userId) != null
5161 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5168 * Update the permission flags for all packages and runtime permissions of a user in order
5169 * to allow device or profile owner to remove POLICY_FIXED.
5172 public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
5173 if (!sUserManager.exists(userId)) {
5177 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps");
5179 enforceCrossUserPermission(Binder.getCallingUid(), userId,
5180 true /* requireFullPermission */, true /* checkShell */,
5181 "updatePermissionFlagsForAllApps");
5183 // Only the system can change system fixed flags.
5184 if (getCallingUid() != Process.SYSTEM_UID) {
5185 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5186 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5189 synchronized (mPackages) {
5190 boolean changed = false;
5191 final int packageCount = mPackages.size();
5192 for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
5193 final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
5194 SettingBase sb = (SettingBase) pkg.mExtras;
5198 PermissionsState permissionsState = sb.getPermissionsState();
5199 changed |= permissionsState.updatePermissionFlagsForAllPermissions(
5200 userId, flagMask, flagValues);
5203 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5208 private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
5209 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
5210 != PackageManager.PERMISSION_GRANTED
5211 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
5212 != PackageManager.PERMISSION_GRANTED) {
5213 throw new SecurityException(message + " requires "
5214 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
5215 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
5220 public boolean shouldShowRequestPermissionRationale(String permissionName,
5221 String packageName, int userId) {
5222 if (UserHandle.getCallingUserId() != userId) {
5223 mContext.enforceCallingPermission(
5224 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5225 "canShowRequestPermissionRationale for user " + userId);
5228 final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
5229 if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
5233 if (checkPermission(permissionName, packageName, userId)
5234 == PackageManager.PERMISSION_GRANTED) {
5240 final long identity = Binder.clearCallingIdentity();
5242 flags = getPermissionFlags(permissionName,
5243 packageName, userId);
5245 Binder.restoreCallingIdentity(identity);
5248 final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
5249 | PackageManager.FLAG_PERMISSION_POLICY_FIXED
5250 | PackageManager.FLAG_PERMISSION_USER_FIXED;
5252 if ((flags & fixedFlags) != 0) {
5256 return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
5260 public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5261 mContext.enforceCallingOrSelfPermission(
5262 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
5263 "addOnPermissionsChangeListener");
5265 synchronized (mPackages) {
5266 mOnPermissionChangeListeners.addListenerLocked(listener);
5271 public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5272 synchronized (mPackages) {
5273 mOnPermissionChangeListeners.removeListenerLocked(listener);
5278 public boolean isProtectedBroadcast(String actionName) {
5279 synchronized (mPackages) {
5280 if (mProtectedBroadcasts.contains(actionName)) {
5282 } else if (actionName != null) {
5283 // TODO: remove these terrible hacks
5284 if (actionName.startsWith("android.net.netmon.lingerExpired")
5285 || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
5286 || actionName.startsWith("com.android.internal.telephony.data-reconnect")
5287 || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
5296 public int checkSignatures(String pkg1, String pkg2) {
5297 synchronized (mPackages) {
5298 final PackageParser.Package p1 = mPackages.get(pkg1);
5299 final PackageParser.Package p2 = mPackages.get(pkg2);
5300 if (p1 == null || p1.mExtras == null
5301 || p2 == null || p2.mExtras == null) {
5302 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5304 return compareSignatures(p1.mSignatures, p2.mSignatures);
5309 public int checkUidSignatures(int uid1, int uid2) {
5310 // Map to base uids.
5311 uid1 = UserHandle.getAppId(uid1);
5312 uid2 = UserHandle.getAppId(uid2);
5314 synchronized (mPackages) {
5317 Object obj = mSettings.getUserIdLPr(uid1);
5319 if (obj instanceof SharedUserSetting) {
5320 s1 = ((SharedUserSetting)obj).signatures.mSignatures;
5321 } else if (obj instanceof PackageSetting) {
5322 s1 = ((PackageSetting)obj).signatures.mSignatures;
5324 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5327 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5329 obj = mSettings.getUserIdLPr(uid2);
5331 if (obj instanceof SharedUserSetting) {
5332 s2 = ((SharedUserSetting)obj).signatures.mSignatures;
5333 } else if (obj instanceof PackageSetting) {
5334 s2 = ((PackageSetting)obj).signatures.mSignatures;
5336 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5339 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5341 return compareSignatures(s1, s2);
5346 * This method should typically only be used when granting or revoking
5347 * permissions, since the app may immediately restart after this call.
5349 * If you're doing surgery on app code/data, use {@link PackageFreezer} to
5350 * guard your work against the app being relaunched.
5352 private void killUid(int appId, int userId, String reason) {
5353 final long identity = Binder.clearCallingIdentity();
5355 IActivityManager am = ActivityManager.getService();
5358 am.killUid(appId, userId, reason);
5359 } catch (RemoteException e) {
5360 /* ignore - same process */
5364 Binder.restoreCallingIdentity(identity);
5369 * Compares two sets of signatures. Returns:
5371 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
5373 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
5375 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
5377 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
5379 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
5381 static int compareSignatures(Signature[] s1, Signature[] s2) {
5384 ? PackageManager.SIGNATURE_NEITHER_SIGNED
5385 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
5389 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
5392 if (s1.length != s2.length) {
5393 return PackageManager.SIGNATURE_NO_MATCH;
5396 // Since both signature sets are of size 1, we can compare without HashSets.
5397 if (s1.length == 1) {
5398 return s1[0].equals(s2[0]) ?
5399 PackageManager.SIGNATURE_MATCH :
5400 PackageManager.SIGNATURE_NO_MATCH;
5403 ArraySet<Signature> set1 = new ArraySet<Signature>();
5404 for (Signature sig : s1) {
5407 ArraySet<Signature> set2 = new ArraySet<Signature>();
5408 for (Signature sig : s2) {
5411 // Make sure s2 contains all signatures in s1.
5412 if (set1.equals(set2)) {
5413 return PackageManager.SIGNATURE_MATCH;
5415 return PackageManager.SIGNATURE_NO_MATCH;
5419 * If the database version for this type of package (internal storage or
5420 * external storage) is less than the version where package signatures
5421 * were updated, return true.
5423 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5424 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5425 return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
5429 * Used for backward compatibility to make sure any packages with
5430 * certificate chains get upgraded to the new style. {@code existingSigs}
5431 * will be in the old format (since they were stored on disk from before the
5432 * system upgrade) and {@code scannedSigs} will be in the newer format.
5434 private int compareSignaturesCompat(PackageSignatures existingSigs,
5435 PackageParser.Package scannedPkg) {
5436 if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
5437 return PackageManager.SIGNATURE_NO_MATCH;
5440 ArraySet<Signature> existingSet = new ArraySet<Signature>();
5441 for (Signature sig : existingSigs.mSignatures) {
5442 existingSet.add(sig);
5444 ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
5445 for (Signature sig : scannedPkg.mSignatures) {
5447 Signature[] chainSignatures = sig.getChainSignatures();
5448 for (Signature chainSig : chainSignatures) {
5449 scannedCompatSet.add(chainSig);
5451 } catch (CertificateEncodingException e) {
5452 scannedCompatSet.add(sig);
5456 * Make sure the expanded scanned set contains all signatures in the
5459 if (scannedCompatSet.equals(existingSet)) {
5460 // Migrate the old signatures to the new scheme.
5461 existingSigs.assignSignatures(scannedPkg.mSignatures);
5462 // The new KeySets will be re-added later in the scanning process.
5463 synchronized (mPackages) {
5464 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
5466 return PackageManager.SIGNATURE_MATCH;
5468 return PackageManager.SIGNATURE_NO_MATCH;
5471 private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5472 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5473 return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
5476 private int compareSignaturesRecover(PackageSignatures existingSigs,
5477 PackageParser.Package scannedPkg) {
5478 if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
5479 return PackageManager.SIGNATURE_NO_MATCH;
5484 if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
5485 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
5486 + scannedPkg.packageName);
5487 return PackageManager.SIGNATURE_MATCH;
5489 } catch (CertificateException e) {
5490 msg = e.getMessage();
5493 logCriticalInfo(Log.INFO,
5494 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
5495 return PackageManager.SIGNATURE_NO_MATCH;
5499 public List<String> getAllPackages() {
5500 synchronized (mPackages) {
5501 return new ArrayList<String>(mPackages.keySet());
5506 public String[] getPackagesForUid(int uid) {
5507 final int userId = UserHandle.getUserId(uid);
5508 uid = UserHandle.getAppId(uid);
5510 synchronized (mPackages) {
5511 Object obj = mSettings.getUserIdLPr(uid);
5512 if (obj instanceof SharedUserSetting) {
5513 final SharedUserSetting sus = (SharedUserSetting) obj;
5514 final int N = sus.packages.size();
5515 String[] res = new String[N];
5516 final Iterator<PackageSetting> it = sus.packages.iterator();
5518 while (it.hasNext()) {
5519 PackageSetting ps = it.next();
5520 if (ps.getInstalled(userId)) {
5523 res = ArrayUtils.removeElement(String.class, res, res[i]);
5527 } else if (obj instanceof PackageSetting) {
5528 final PackageSetting ps = (PackageSetting) obj;
5529 if (ps.getInstalled(userId)) {
5530 return new String[]{ps.name};
5538 public String getNameForUid(int uid) {
5540 synchronized (mPackages) {
5541 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5542 if (obj instanceof SharedUserSetting) {
5543 final SharedUserSetting sus = (SharedUserSetting) obj;
5544 return sus.name + ":" + sus.userId;
5545 } else if (obj instanceof PackageSetting) {
5546 final PackageSetting ps = (PackageSetting) obj;
5554 public int getUidForSharedUser(String sharedUserName) {
5555 if(sharedUserName == null) {
5559 synchronized (mPackages) {
5560 SharedUserSetting suid;
5562 suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
5566 } catch (PackageManagerException ignore) {
5567 // can't happen, but, still need to catch it
5574 public int getFlagsForUid(int uid) {
5575 synchronized (mPackages) {
5576 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5577 if (obj instanceof SharedUserSetting) {
5578 final SharedUserSetting sus = (SharedUserSetting) obj;
5579 return sus.pkgFlags;
5580 } else if (obj instanceof PackageSetting) {
5581 final PackageSetting ps = (PackageSetting) obj;
5589 public int getPrivateFlagsForUid(int uid) {
5590 synchronized (mPackages) {
5591 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5592 if (obj instanceof SharedUserSetting) {
5593 final SharedUserSetting sus = (SharedUserSetting) obj;
5594 return sus.pkgPrivateFlags;
5595 } else if (obj instanceof PackageSetting) {
5596 final PackageSetting ps = (PackageSetting) obj;
5597 return ps.pkgPrivateFlags;
5604 public boolean isUidPrivileged(int uid) {
5605 uid = UserHandle.getAppId(uid);
5607 synchronized (mPackages) {
5608 Object obj = mSettings.getUserIdLPr(uid);
5609 if (obj instanceof SharedUserSetting) {
5610 final SharedUserSetting sus = (SharedUserSetting) obj;
5611 final Iterator<PackageSetting> it = sus.packages.iterator();
5612 while (it.hasNext()) {
5613 if (it.next().isPrivileged()) {
5617 } else if (obj instanceof PackageSetting) {
5618 final PackageSetting ps = (PackageSetting) obj;
5619 return ps.isPrivileged();
5626 public String[] getAppOpPermissionPackages(String permissionName) {
5627 synchronized (mPackages) {
5628 ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
5632 return pkgs.toArray(new String[pkgs.size()]);
5637 public ResolveInfo resolveIntent(Intent intent, String resolvedType,
5638 int flags, int userId) {
5639 return resolveIntentInternal(
5640 intent, resolvedType, flags, userId, false /*includeInstantApps*/);
5643 private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
5644 int flags, int userId, boolean includeInstantApps) {
5646 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
5648 if (!sUserManager.exists(userId)) return null;
5649 final int callingUid = Binder.getCallingUid();
5650 flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
5651 enforceCrossUserPermission(callingUid, userId,
5652 false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
5654 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
5655 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
5656 flags, userId, includeInstantApps);
5657 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5659 final ResolveInfo bestChoice =
5660 chooseBestActivity(intent, resolvedType, flags, query, userId);
5663 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5668 public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
5669 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
5670 throw new SecurityException(
5671 "findPersistentPreferredActivity can only be run by the system");
5673 if (!sUserManager.exists(userId)) {
5676 final int callingUid = Binder.getCallingUid();
5677 intent = updateIntentForResolve(intent);
5678 final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
5679 final int flags = updateFlagsForResolve(
5680 0, userId, intent, callingUid, false /*includeInstantApps*/);
5681 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5683 synchronized (mPackages) {
5684 return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
5690 public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
5691 IntentFilter filter, int match, ComponentName activity) {
5692 final int userId = UserHandle.getCallingUserId();
5693 if (DEBUG_PREFERRED) {
5694 Log.v(TAG, "setLastChosenActivity intent=" + intent
5695 + " resolvedType=" + resolvedType
5697 + " filter=" + filter
5699 + " activity=" + activity);
5700 filter.dump(new PrintStreamPrinter(System.out), " ");
5702 intent.setComponent(null);
5703 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5705 // Find any earlier preferred or last chosen entries and nuke them
5706 findPreferredActivity(intent, resolvedType,
5707 flags, query, 0, false, true, false, userId);
5708 // Add the new activity as the last chosen for this filter
5709 addPreferredActivityInternal(filter, match, null, activity, false, userId,
5710 "Setting last chosen");
5714 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
5715 final int userId = UserHandle.getCallingUserId();
5716 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
5717 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5719 return findPreferredActivity(intent, resolvedType, flags, query, 0,
5720 false, false, false, userId);
5724 * Returns whether or not instant apps have been disabled remotely.
5726 private boolean isEphemeralDisabled() {
5727 return mEphemeralAppsDisabled;
5730 private boolean isEphemeralAllowed(
5731 Intent intent, List<ResolveInfo> resolvedActivities, int userId,
5732 boolean skipPackageCheck) {
5733 final int callingUser = UserHandle.getCallingUserId();
5734 if (mInstantAppResolverConnection == null) {
5737 if (mInstantAppInstallerActivity == null) {
5740 if (intent.getComponent() != null) {
5743 if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
5746 if (!skipPackageCheck && intent.getPackage() != null) {
5749 final boolean isWebUri = hasWebURI(intent);
5750 if (!isWebUri || intent.getData().getHost() == null) {
5753 // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
5754 // Or if there's already an ephemeral app installed that handles the action
5755 synchronized (mPackages) {
5756 final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
5757 for (int n = 0; n < count; n++) {
5758 final ResolveInfo info = resolvedActivities.get(n);
5759 final String packageName = info.activityInfo.packageName;
5760 final PackageSetting ps = mSettings.mPackages.get(packageName);
5762 // only check domain verification status if the app is not a browser
5763 if (!info.handleAllWebDataURI) {
5764 // Try to get the status from User settings first
5765 final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
5766 final int status = (int) (packedStatus >> 32);
5767 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
5768 || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
5769 if (DEBUG_EPHEMERAL) {
5770 Slog.v(TAG, "DENY instant app;"
5771 + " pkg: " + packageName + ", status: " + status);
5776 if (ps.getInstantApp(userId)) {
5777 if (DEBUG_EPHEMERAL) {
5778 Slog.v(TAG, "DENY instant app installed;"
5779 + " pkg: " + packageName);
5786 // We've exhausted all ways to deny ephemeral application; let the system look for them.
5790 private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
5791 Intent origIntent, String resolvedType, String callingPackage,
5793 final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
5794 new InstantAppRequest(responseObj, origIntent, resolvedType,
5795 callingPackage, userId));
5796 mHandler.sendMessage(msg);
5799 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
5800 int flags, List<ResolveInfo> query, int userId) {
5801 if (query != null) {
5802 final int N = query.size();
5804 return query.get(0);
5806 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
5807 // If there is more than one activity with the same priority,
5808 // then let the user decide between them.
5809 ResolveInfo r0 = query.get(0);
5810 ResolveInfo r1 = query.get(1);
5811 if (DEBUG_INTENT_MATCHING || debug) {
5812 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
5813 + r1.activityInfo.name + "=" + r1.priority);
5815 // If the first activity has a higher priority, or a different
5816 // default, then it is always desirable to pick it.
5817 if (r0.priority != r1.priority
5818 || r0.preferredOrder != r1.preferredOrder
5819 || r0.isDefault != r1.isDefault) {
5820 return query.get(0);
5822 // If we have saved a preference for a preferred activity for
5823 // this Intent, use that.
5824 ResolveInfo ri = findPreferredActivity(intent, resolvedType,
5825 flags, query, r0.priority, true, false, debug, userId);
5829 // If we have an ephemeral app, use it
5830 for (int i = 0; i < N; i++) {
5832 if (ri.activityInfo.applicationInfo.isInstantApp()) {
5836 ri = new ResolveInfo(mResolveInfo);
5837 ri.activityInfo = new ActivityInfo(ri.activityInfo);
5838 ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
5839 // If all of the options come from the same package, show the application's
5840 // label and icon instead of the generic resolver's.
5841 // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
5842 // and then throw away the ResolveInfo itself, meaning that the caller loses
5843 // the resolvePackageName. Therefore the activityInfo.labelRes above provides
5844 // a fallback for this case; we only set the target package's resources on
5845 // the ResolveInfo, not the ActivityInfo.
5846 final String intentPackage = intent.getPackage();
5847 if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
5848 final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
5849 ri.resolvePackageName = intentPackage;
5850 if (userNeedsBadging(userId)) {
5851 ri.noResourceId = true;
5853 ri.icon = appi.icon;
5855 ri.iconResourceId = appi.icon;
5856 ri.labelRes = appi.labelRes;
5858 ri.activityInfo.applicationInfo = new ApplicationInfo(
5859 ri.activityInfo.applicationInfo);
5861 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
5862 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
5864 // Make sure that the resolver is displayable in car mode
5865 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
5866 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
5874 * Return true if the given list is not empty and all of its contents have
5875 * an activityInfo with the given package name.
5877 private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
5878 if (ArrayUtils.isEmpty(list)) {
5881 for (int i = 0, N = list.size(); i < N; i++) {
5882 final ResolveInfo ri = list.get(i);
5883 final ActivityInfo ai = ri != null ? ri.activityInfo : null;
5884 if (ai == null || !packageName.equals(ai.packageName)) {
5891 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
5892 int flags, List<ResolveInfo> query, boolean debug, int userId) {
5893 final int N = query.size();
5894 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
5896 // Get the list of persistent preferred activities that handle the intent
5897 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
5898 List<PersistentPreferredActivity> pprefs = ppir != null
5899 ? ppir.queryIntent(intent, resolvedType,
5900 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
5903 if (pprefs != null && pprefs.size() > 0) {
5904 final int M = pprefs.size();
5905 for (int i=0; i<M; i++) {
5906 final PersistentPreferredActivity ppa = pprefs.get(i);
5907 if (DEBUG_PREFERRED || debug) {
5908 Slog.v(TAG, "Checking PersistentPreferredActivity ds="
5909 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
5910 + "\n component=" + ppa.mComponent);
5911 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
5913 final ActivityInfo ai = getActivityInfo(ppa.mComponent,
5914 flags | MATCH_DISABLED_COMPONENTS, userId);
5915 if (DEBUG_PREFERRED || debug) {
5916 Slog.v(TAG, "Found persistent preferred activity:");
5918 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
5920 Slog.v(TAG, " null");
5924 // This previously registered persistent preferred activity
5925 // component is no longer known. Ignore it and do NOT remove it.
5928 for (int j=0; j<N; j++) {
5929 final ResolveInfo ri = query.get(j);
5930 if (!ri.activityInfo.applicationInfo.packageName
5931 .equals(ai.applicationInfo.packageName)) {
5934 if (!ri.activityInfo.name.equals(ai.name)) {
5937 // Found a persistent preference that can handle the intent.
5938 if (DEBUG_PREFERRED || debug) {
5939 Slog.v(TAG, "Returning persistent preferred activity: " +
5940 ri.activityInfo.packageName + "/" + ri.activityInfo.name);
5949 // TODO: handle preferred activities missing while user has amnesia
5950 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
5951 List<ResolveInfo> query, int priority, boolean always,
5952 boolean removeMatches, boolean debug, int userId) {
5953 if (!sUserManager.exists(userId)) return null;
5954 final int callingUid = Binder.getCallingUid();
5955 flags = updateFlagsForResolve(
5956 flags, userId, intent, callingUid, false /*includeInstantApps*/);
5957 intent = updateIntentForResolve(intent);
5959 synchronized (mPackages) {
5960 // Try to find a matching persistent preferred activity.
5961 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
5964 // If a persistent preferred activity matched, use it.
5969 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
5970 // Get the list of preferred activities that handle the intent
5971 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
5972 List<PreferredActivity> prefs = pir != null
5973 ? pir.queryIntent(intent, resolvedType,
5974 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
5977 if (prefs != null && prefs.size() > 0) {
5978 boolean changed = false;
5980 // First figure out how good the original match set is.
5981 // We will only allow preferred activities that came
5982 // from the same match quality.
5985 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
5987 final int N = query.size();
5988 for (int j=0; j<N; j++) {
5989 final ResolveInfo ri = query.get(j);
5990 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
5991 + ": 0x" + Integer.toHexString(match));
5992 if (ri.match > match) {
5997 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
5998 + Integer.toHexString(match));
6000 match &= IntentFilter.MATCH_CATEGORY_MASK;
6001 final int M = prefs.size();
6002 for (int i=0; i<M; i++) {
6003 final PreferredActivity pa = prefs.get(i);
6004 if (DEBUG_PREFERRED || debug) {
6005 Slog.v(TAG, "Checking PreferredActivity ds="
6006 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
6007 + "\n component=" + pa.mPref.mComponent);
6008 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
6010 if (pa.mPref.mMatch != match) {
6011 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
6012 + Integer.toHexString(pa.mPref.mMatch));
6015 // If it's not an "always" type preferred activity and that's what we're
6016 // looking for, skip it.
6017 if (always && !pa.mPref.mAlways) {
6018 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
6021 final ActivityInfo ai = getActivityInfo(
6022 pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
6023 | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
6025 if (DEBUG_PREFERRED || debug) {
6026 Slog.v(TAG, "Found preferred activity:");
6028 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
6030 Slog.v(TAG, " null");
6034 // This previously registered preferred activity
6035 // component is no longer known. Most likely an update
6036 // to the app was installed and in the new version this
6037 // component no longer exists. Clean it up by removing
6038 // it from the preferred activities list, and skip it.
6039 Slog.w(TAG, "Removing dangling preferred activity: "
6040 + pa.mPref.mComponent);
6041 pir.removeFilter(pa);
6045 for (int j=0; j<N; j++) {
6046 final ResolveInfo ri = query.get(j);
6047 if (!ri.activityInfo.applicationInfo.packageName
6048 .equals(ai.applicationInfo.packageName)) {
6051 if (!ri.activityInfo.name.equals(ai.name)) {
6055 if (removeMatches) {
6056 pir.removeFilter(pa);
6058 if (DEBUG_PREFERRED) {
6059 Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
6064 // Okay we found a previously set preferred or last chosen app.
6065 // If the result set is different from when this
6066 // was created, we need to clear it and re-ask the
6067 // user their preference, if we're looking for an "always" type entry.
6068 if (always && !pa.mPref.sameSet(query)) {
6069 Slog.i(TAG, "Result set changed, dropping preferred activity for "
6070 + intent + " type " + resolvedType);
6071 if (DEBUG_PREFERRED) {
6072 Slog.v(TAG, "Removing preferred activity since set changed "
6073 + pa.mPref.mComponent);
6075 pir.removeFilter(pa);
6076 // Re-add the filter as a "last chosen" entry (!always)
6077 PreferredActivity lastChosen = new PreferredActivity(
6078 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
6079 pir.addFilter(lastChosen);
6084 // Yay! Either the set matched or we're looking for the last chosen
6085 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
6086 + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6092 if (DEBUG_PREFERRED) {
6093 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
6095 scheduleWritePackageRestrictionsLocked(userId);
6100 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
6105 * Returns if intent can be forwarded from the sourceUserId to the targetUserId
6108 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
6110 mContext.enforceCallingOrSelfPermission(
6111 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
6112 List<CrossProfileIntentFilter> matches =
6113 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
6114 if (matches != null) {
6115 int size = matches.size();
6116 for (int i = 0; i < size; i++) {
6117 if (matches.get(i).getTargetUserId() == targetUserId) return true;
6120 if (hasWebURI(intent)) {
6121 // cross-profile app linking works only towards the parent.
6122 final int callingUid = Binder.getCallingUid();
6123 final UserInfo parent = getProfileParent(sourceUserId);
6124 synchronized(mPackages) {
6125 int flags = updateFlagsForResolve(0, parent.id, intent, callingUid,
6126 false /*includeInstantApps*/);
6127 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
6128 intent, resolvedType, flags, sourceUserId, parent.id);
6129 return xpDomainInfo != null;
6135 private UserInfo getProfileParent(int userId) {
6136 final long identity = Binder.clearCallingIdentity();
6138 return sUserManager.getProfileParent(userId);
6140 Binder.restoreCallingIdentity(identity);
6144 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
6145 String resolvedType, int userId) {
6146 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
6147 if (resolver != null) {
6148 return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
6154 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
6155 String resolvedType, int flags, int userId) {
6157 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6159 return new ParceledListSlice<>(
6160 queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
6162 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6167 * Returns the package name of the calling Uid if it's an instant app. If it isn't
6168 * instant, returns {@code null}.
6170 private String getInstantAppPackageName(int callingUid) {
6171 // If the caller is an isolated app use the owner's uid for the lookup.
6172 if (Process.isIsolated(callingUid)) {
6173 callingUid = mIsolatedOwners.get(callingUid);
6175 final int appId = UserHandle.getAppId(callingUid);
6176 synchronized (mPackages) {
6177 final Object obj = mSettings.getUserIdLPr(appId);
6178 if (obj instanceof PackageSetting) {
6179 final PackageSetting ps = (PackageSetting) obj;
6180 final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
6181 return isInstantApp ? ps.pkg.packageName : null;
6187 private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6188 String resolvedType, int flags, int userId) {
6189 return queryIntentActivitiesInternal(intent, resolvedType, flags, userId, false);
6192 private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6193 String resolvedType, int flags, int userId, boolean includeInstantApps) {
6194 if (!sUserManager.exists(userId)) return Collections.emptyList();
6195 final int callingUid = Binder.getCallingUid();
6196 final String instantAppPkgName = getInstantAppPackageName(callingUid);
6197 flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
6198 enforceCrossUserPermission(callingUid, userId,
6199 false /* requireFullPermission */, false /* checkShell */,
6200 "query intent activities");
6201 ComponentName comp = intent.getComponent();
6203 if (intent.getSelector() != null) {
6204 intent = intent.getSelector();
6205 comp = intent.getComponent();
6210 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6211 final ActivityInfo ai = getActivityInfo(comp, flags, userId);
6213 // When specifying an explicit component, we prevent the activity from being
6214 // used when either 1) the calling package is normal and the activity is within
6215 // an ephemeral application or 2) the calling package is ephemeral and the
6216 // activity is not visible to ephemeral applications.
6217 final boolean matchInstantApp =
6218 (flags & PackageManager.MATCH_INSTANT) != 0;
6219 final boolean matchVisibleToInstantAppOnly =
6220 (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
6221 final boolean isCallerInstantApp =
6222 instantAppPkgName != null;
6223 final boolean isTargetSameInstantApp =
6224 comp.getPackageName().equals(instantAppPkgName);
6225 final boolean isTargetInstantApp =
6226 (ai.applicationInfo.privateFlags
6227 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
6228 final boolean isTargetHiddenFromInstantApp =
6229 (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0;
6230 final boolean blockResolution =
6231 !isTargetSameInstantApp
6232 && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
6233 || (matchVisibleToInstantAppOnly && isCallerInstantApp
6234 && isTargetHiddenFromInstantApp));
6235 if (!blockResolution) {
6236 final ResolveInfo ri = new ResolveInfo();
6237 ri.activityInfo = ai;
6241 return applyPostResolutionFilter(list, instantAppPkgName);
6245 boolean sortResult = false;
6246 boolean addEphemeral = false;
6247 List<ResolveInfo> result;
6248 final String pkgName = intent.getPackage();
6249 final boolean ephemeralDisabled = isEphemeralDisabled();
6250 synchronized (mPackages) {
6251 if (pkgName == null) {
6252 List<CrossProfileIntentFilter> matchingFilters =
6253 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
6254 // Check for results that need to skip the current profile.
6255 ResolveInfo xpResolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent,
6256 resolvedType, flags, userId);
6257 if (xpResolveInfo != null) {
6258 List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
6259 xpResult.add(xpResolveInfo);
6260 return applyPostResolutionFilter(
6261 filterIfNotSystemUser(xpResult, userId), instantAppPkgName);
6264 // Check for results in the current profile.
6265 result = filterIfNotSystemUser(mActivities.queryIntent(
6266 intent, resolvedType, flags, userId), userId);
6267 addEphemeral = !ephemeralDisabled
6268 && isEphemeralAllowed(intent, result, userId, false /*skipPackageCheck*/);
6269 // Check for cross profile results.
6270 boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
6271 xpResolveInfo = queryCrossProfileIntents(
6272 matchingFilters, intent, resolvedType, flags, userId,
6273 hasNonNegativePriorityResult);
6274 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
6275 boolean isVisibleToUser = filterIfNotSystemUser(
6276 Collections.singletonList(xpResolveInfo), userId).size() > 0;
6277 if (isVisibleToUser) {
6278 result.add(xpResolveInfo);
6282 if (hasWebURI(intent)) {
6283 CrossProfileDomainInfo xpDomainInfo = null;
6284 final UserInfo parent = getProfileParent(userId);
6285 if (parent != null) {
6286 xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
6287 flags, userId, parent.id);
6289 if (xpDomainInfo != null) {
6290 if (xpResolveInfo != null) {
6291 // If we didn't remove it, the cross-profile ResolveInfo would be twice
6293 result.remove(xpResolveInfo);
6295 if (result.size() == 0 && !addEphemeral) {
6296 // No result in current profile, but found candidate in parent user.
6297 // And we are not going to add emphemeral app, so we can return the
6298 // result straight away.
6299 result.add(xpDomainInfo.resolveInfo);
6300 return applyPostResolutionFilter(result, instantAppPkgName);
6302 } else if (result.size() <= 1 && !addEphemeral) {
6303 // No result in parent user and <= 1 result in current profile, and we
6304 // are not going to add emphemeral app, so we can return the result without
6305 // further processing.
6306 return applyPostResolutionFilter(result, instantAppPkgName);
6308 // We have more than one candidate (combining results from current and parent
6309 // profile), so we need filtering and sorting.
6310 result = filterCandidatesWithDomainPreferredActivitiesLPr(
6311 intent, flags, result, xpDomainInfo, userId);
6315 final PackageParser.Package pkg = mPackages.get(pkgName);
6317 return applyPostResolutionFilter(filterIfNotSystemUser(
6318 mActivities.queryIntentForPackage(
6319 intent, resolvedType, flags, pkg.activities, userId),
6320 userId), instantAppPkgName);
6322 // the caller wants to resolve for a particular package; however, there
6323 // were no installed results, so, try to find an ephemeral result
6324 addEphemeral = !ephemeralDisabled
6325 && isEphemeralAllowed(
6326 intent, null /*result*/, userId, true /*skipPackageCheck*/);
6327 result = new ArrayList<ResolveInfo>();
6332 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
6333 final InstantAppRequest requestObject = new InstantAppRequest(
6334 null /*responseObj*/, intent /*origIntent*/, resolvedType,
6335 null /*callingPackage*/, userId);
6336 final AuxiliaryResolveInfo auxiliaryResponse =
6337 InstantAppResolver.doInstantAppResolutionPhaseOne(
6338 mContext, mInstantAppResolverConnection, requestObject);
6339 if (auxiliaryResponse != null) {
6340 if (DEBUG_EPHEMERAL) {
6341 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
6343 final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
6344 final PackageSetting ps =
6345 mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
6347 ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
6348 mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
6349 ephemeralInstaller.activityInfo.launchToken = auxiliaryResponse.token;
6350 ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
6351 // make sure this resolver is the default
6352 ephemeralInstaller.isDefault = true;
6353 ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6354 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6355 // add a non-generic filter
6356 ephemeralInstaller.filter = new IntentFilter(intent.getAction());
6357 ephemeralInstaller.filter.addDataPath(
6358 intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
6359 ephemeralInstaller.instantAppAvailable = true;
6360 result.add(ephemeralInstaller);
6363 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6366 Collections.sort(result, mResolvePrioritySorter);
6368 return applyPostResolutionFilter(result, instantAppPkgName);
6371 private static class CrossProfileDomainInfo {
6372 /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
6373 ResolveInfo resolveInfo;
6374 /* Best domain verification status of the activities found in the other profile */
6375 int bestDomainVerificationStatus;
6378 private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
6379 String resolvedType, int flags, int sourceUserId, int parentUserId) {
6380 if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
6384 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
6385 resolvedType, flags, parentUserId);
6387 if (resultTargetUser == null || resultTargetUser.isEmpty()) {
6390 CrossProfileDomainInfo result = null;
6391 int size = resultTargetUser.size();
6392 for (int i = 0; i < size; i++) {
6393 ResolveInfo riTargetUser = resultTargetUser.get(i);
6394 // Intent filter verification is only for filters that specify a host. So don't return
6395 // those that handle all web uris.
6396 if (riTargetUser.handleAllWebDataURI) {
6399 String packageName = riTargetUser.activityInfo.packageName;
6400 PackageSetting ps = mSettings.mPackages.get(packageName);
6404 long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
6405 int status = (int)(verificationState >> 32);
6406 if (result == null) {
6407 result = new CrossProfileDomainInfo();
6408 result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
6409 sourceUserId, parentUserId);
6410 result.bestDomainVerificationStatus = status;
6412 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
6413 result.bestDomainVerificationStatus);
6416 // Don't consider matches with status NEVER across profiles.
6417 if (result != null && result.bestDomainVerificationStatus
6418 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6425 * Verification statuses are ordered from the worse to the best, except for
6426 * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
6428 private int bestDomainVerificationStatus(int status1, int status2) {
6429 if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6432 if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6435 return (int) MathUtils.max(status1, status2);
6438 private boolean isUserEnabled(int userId) {
6439 long callingId = Binder.clearCallingIdentity();
6441 UserInfo userInfo = sUserManager.getUserInfo(userId);
6442 return userInfo != null && userInfo.isEnabled();
6444 Binder.restoreCallingIdentity(callingId);
6449 * Filter out activities with systemUserOnly flag set, when current user is not System.
6451 * @return filtered list
6453 private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
6454 if (userId == UserHandle.USER_SYSTEM) {
6455 return resolveInfos;
6457 for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6458 ResolveInfo info = resolveInfos.get(i);
6459 if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
6460 resolveInfos.remove(i);
6463 return resolveInfos;
6467 * Filters out ephemeral activities.
6468 * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
6469 * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
6471 * @param resolveInfos The pre-filtered list of resolved activities
6472 * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
6474 * @return A filtered list of resolved activities.
6476 private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
6477 String ephemeralPkgName) {
6478 // TODO: When adding on-demand split support for non-instant apps, remove this check
6479 // and always apply post filtering
6480 if (ephemeralPkgName == null) {
6481 return resolveInfos;
6483 for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6484 final ResolveInfo info = resolveInfos.get(i);
6485 final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
6486 // allow activities that are defined in the provided package
6487 if (isEphemeralApp && ephemeralPkgName.equals(info.activityInfo.packageName)) {
6488 if (info.activityInfo.splitName != null
6489 && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
6490 info.activityInfo.splitName)) {
6491 // requested activity is defined in a split that hasn't been installed yet.
6492 // add the installer to the resolve list
6493 if (DEBUG_EPHEMERAL) {
6494 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
6496 final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
6497 installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
6498 info.activityInfo.packageName, info.activityInfo.splitName,
6499 info.activityInfo.applicationInfo.versionCode);
6500 // make sure this resolver is the default
6501 installerInfo.isDefault = true;
6502 installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6503 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6504 // add a non-generic filter
6505 installerInfo.filter = new IntentFilter();
6506 // load resources from the correct package
6507 installerInfo.resolvePackageName = info.getComponentInfo().packageName;
6508 resolveInfos.set(i, installerInfo);
6512 // allow activities that have been explicitly exposed to ephemeral apps
6514 && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0)) {
6517 resolveInfos.remove(i);
6519 return resolveInfos;
6523 * @param resolveInfos list of resolve infos in descending priority order
6524 * @return if the list contains a resolve info with non-negative priority
6526 private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
6527 return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
6530 private static boolean hasWebURI(Intent intent) {
6531 if (intent.getData() == null) {
6534 final String scheme = intent.getScheme();
6535 if (TextUtils.isEmpty(scheme)) {
6538 return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
6541 private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
6542 int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
6544 final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
6546 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
6547 Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
6551 ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
6552 ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
6553 ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
6554 ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
6555 ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
6556 ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
6558 synchronized (mPackages) {
6559 final int count = candidates.size();
6560 // First, try to use linked apps. Partition the candidates into four lists:
6561 // one for the final results, one for the "do not use ever", one for "undefined status"
6562 // and finally one for "browser app type".
6563 for (int n=0; n<count; n++) {
6564 ResolveInfo info = candidates.get(n);
6565 String packageName = info.activityInfo.packageName;
6566 PackageSetting ps = mSettings.mPackages.get(packageName);
6568 // Add to the special match all list (Browser use case)
6569 if (info.handleAllWebDataURI) {
6570 matchAllList.add(info);
6573 // Try to get the status from User settings first
6574 long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6575 int status = (int)(packedStatus >> 32);
6576 int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
6577 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
6578 if (DEBUG_DOMAIN_VERIFICATION || debug) {
6579 Slog.i(TAG, " + always: " + info.activityInfo.packageName
6580 + " : linkgen=" + linkGeneration);
6582 // Use link-enabled generation as preferredOrder, i.e.
6583 // prefer newly-enabled over earlier-enabled.
6584 info.preferredOrder = linkGeneration;
6585 alwaysList.add(info);
6586 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6587 if (DEBUG_DOMAIN_VERIFICATION || debug) {
6588 Slog.i(TAG, " + never: " + info.activityInfo.packageName);
6590 neverList.add(info);
6591 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6592 if (DEBUG_DOMAIN_VERIFICATION || debug) {
6593 Slog.i(TAG, " + always-ask: " + info.activityInfo.packageName);
6595 alwaysAskList.add(info);
6596 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
6597 status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
6598 if (DEBUG_DOMAIN_VERIFICATION || debug) {
6599 Slog.i(TAG, " + ask: " + info.activityInfo.packageName);
6601 undefinedList.add(info);
6606 // We'll want to include browser possibilities in a few cases
6607 boolean includeBrowser = false;
6609 // First try to add the "always" resolution(s) for the current user, if any
6610 if (alwaysList.size() > 0) {
6611 result.addAll(alwaysList);
6613 // Add all undefined apps as we want them to appear in the disambiguation dialog.
6614 result.addAll(undefinedList);
6615 // Maybe add one for the other profile.
6616 if (xpDomainInfo != null && (
6617 xpDomainInfo.bestDomainVerificationStatus
6618 != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
6619 result.add(xpDomainInfo.resolveInfo);
6621 includeBrowser = true;
6624 // The presence of any 'always ask' alternatives means we'll also offer browsers.
6625 // If there were 'always' entries their preferred order has been set, so we also
6626 // back that off to make the alternatives equivalent
6627 if (alwaysAskList.size() > 0) {
6628 for (ResolveInfo i : result) {
6629 i.preferredOrder = 0;
6631 result.addAll(alwaysAskList);
6632 includeBrowser = true;
6635 if (includeBrowser) {
6636 // Also add browsers (all of them or only the default one)
6637 if (DEBUG_DOMAIN_VERIFICATION) {
6638 Slog.v(TAG, " ...including browsers in candidate set");
6640 if ((matchFlags & MATCH_ALL) != 0) {
6641 result.addAll(matchAllList);
6643 // Browser/generic handling case. If there's a default browser, go straight
6644 // to that (but only if there is no other higher-priority match).
6645 final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
6646 int maxMatchPrio = 0;
6647 ResolveInfo defaultBrowserMatch = null;
6648 final int numCandidates = matchAllList.size();
6649 for (int n = 0; n < numCandidates; n++) {
6650 ResolveInfo info = matchAllList.get(n);
6651 // track the highest overall match priority...
6652 if (info.priority > maxMatchPrio) {
6653 maxMatchPrio = info.priority;
6655 // ...and the highest-priority default browser match
6656 if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
6657 if (defaultBrowserMatch == null
6658 || (defaultBrowserMatch.priority < info.priority)) {
6660 Slog.v(TAG, "Considering default browser match " + info);
6662 defaultBrowserMatch = info;
6666 if (defaultBrowserMatch != null
6667 && defaultBrowserMatch.priority >= maxMatchPrio
6668 && !TextUtils.isEmpty(defaultBrowserPackageName))
6671 Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
6673 result.add(defaultBrowserMatch);
6675 result.addAll(matchAllList);
6679 // If there is nothing selected, add all candidates and remove the ones that the user
6680 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
6681 if (result.size() == 0) {
6682 result.addAll(candidates);
6683 result.removeAll(neverList);
6687 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
6688 Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
6690 for (ResolveInfo info : result) {
6691 Slog.v(TAG, " + " + info.activityInfo);
6697 // Returns a packed value as a long:
6699 // high 'int'-sized word: link status: undefined/ask/never/always.
6700 // low 'int'-sized word: relative priority among 'always' results.
6701 private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
6702 long result = ps.getDomainVerificationStatusForUser(userId);
6703 // if none available, get the master status
6704 if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
6705 if (ps.getIntentFilterVerificationInfo() != null) {
6706 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
6712 private ResolveInfo querySkipCurrentProfileIntents(
6713 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
6714 int flags, int sourceUserId) {
6715 if (matchingFilters != null) {
6716 int size = matchingFilters.size();
6717 for (int i = 0; i < size; i ++) {
6718 CrossProfileIntentFilter filter = matchingFilters.get(i);
6719 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
6720 // Checking if there are activities in the target user that can handle the
6722 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
6723 resolvedType, flags, sourceUserId);
6724 if (resolveInfo != null) {
6733 // Return matching ResolveInfo in target user if any.
6734 private ResolveInfo queryCrossProfileIntents(
6735 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
6736 int flags, int sourceUserId, boolean matchInCurrentProfile) {
6737 if (matchingFilters != null) {
6738 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
6739 // match the same intent. For performance reasons, it is better not to
6740 // run queryIntent twice for the same userId
6741 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
6742 int size = matchingFilters.size();
6743 for (int i = 0; i < size; i++) {
6744 CrossProfileIntentFilter filter = matchingFilters.get(i);
6745 int targetUserId = filter.getTargetUserId();
6746 boolean skipCurrentProfile =
6747 (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
6748 boolean skipCurrentProfileIfNoMatchFound =
6749 (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
6750 if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
6751 && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
6752 // Checking if there are activities in the target user that can handle the
6754 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
6755 resolvedType, flags, sourceUserId);
6756 if (resolveInfo != null) return resolveInfo;
6757 alreadyTriedUserIds.put(targetUserId, true);
6765 * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
6766 * will forward the intent to the filter's target user.
6767 * Otherwise, returns null.
6769 private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
6770 String resolvedType, int flags, int sourceUserId) {
6771 int targetUserId = filter.getTargetUserId();
6772 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
6773 resolvedType, flags, targetUserId);
6774 if (resultTargetUser != null && isUserEnabled(targetUserId)) {
6775 // If all the matches in the target profile are suspended, return null.
6776 for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
6777 if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
6778 & ApplicationInfo.FLAG_SUSPENDED) == 0) {
6779 return createForwardingResolveInfoUnchecked(filter, sourceUserId,
6787 private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
6788 int sourceUserId, int targetUserId) {
6789 ResolveInfo forwardingResolveInfo = new ResolveInfo();
6790 long ident = Binder.clearCallingIdentity();
6791 boolean targetIsProfile;
6793 targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
6795 Binder.restoreCallingIdentity(ident);
6798 if (targetIsProfile) {
6799 className = FORWARD_INTENT_TO_MANAGED_PROFILE;
6801 className = FORWARD_INTENT_TO_PARENT;
6803 ComponentName forwardingActivityComponentName = new ComponentName(
6804 mAndroidApplication.packageName, className);
6805 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
6807 if (!targetIsProfile) {
6808 forwardingActivityInfo.showUserIcon = targetUserId;
6809 forwardingResolveInfo.noResourceId = true;
6811 forwardingResolveInfo.activityInfo = forwardingActivityInfo;
6812 forwardingResolveInfo.priority = 0;
6813 forwardingResolveInfo.preferredOrder = 0;
6814 forwardingResolveInfo.match = 0;
6815 forwardingResolveInfo.isDefault = true;
6816 forwardingResolveInfo.filter = filter;
6817 forwardingResolveInfo.targetUserId = targetUserId;
6818 return forwardingResolveInfo;
6822 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
6823 Intent[] specifics, String[] specificTypes, Intent intent,
6824 String resolvedType, int flags, int userId) {
6825 return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
6826 specificTypes, intent, resolvedType, flags, userId));
6829 private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
6830 Intent[] specifics, String[] specificTypes, Intent intent,
6831 String resolvedType, int flags, int userId) {
6832 if (!sUserManager.exists(userId)) return Collections.emptyList();
6833 final int callingUid = Binder.getCallingUid();
6834 flags = updateFlagsForResolve(flags, userId, intent, callingUid,
6835 false /*includeInstantApps*/);
6836 enforceCrossUserPermission(callingUid, userId,
6837 false /*requireFullPermission*/, false /*checkShell*/,
6838 "query intent activity options");
6839 final String resultsAction = intent.getAction();
6841 final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
6842 | PackageManager.GET_RESOLVED_FILTER, userId);
6844 if (DEBUG_INTENT_MATCHING) {
6845 Log.v(TAG, "Query " + intent + ": " + results);
6848 int specificsPos = 0;
6851 // todo: note that the algorithm used here is O(N^2). This
6852 // isn't a problem in our current environment, but if we start running
6853 // into situations where we have more than 5 or 10 matches then this
6854 // should probably be changed to something smarter...
6856 // First we go through and resolve each of the specific items
6857 // that were supplied, taking care of removing any corresponding
6858 // duplicate items in the generic resolve list.
6859 if (specifics != null) {
6860 for (int i=0; i<specifics.length; i++) {
6861 final Intent sintent = specifics[i];
6862 if (sintent == null) {
6866 if (DEBUG_INTENT_MATCHING) {
6867 Log.v(TAG, "Specific #" + i + ": " + sintent);
6870 String action = sintent.getAction();
6871 if (resultsAction != null && resultsAction.equals(action)) {
6872 // If this action was explicitly requested, then don't
6873 // remove things that have it.
6877 ResolveInfo ri = null;
6878 ActivityInfo ai = null;
6880 ComponentName comp = sintent.getComponent();
6884 specificTypes != null ? specificTypes[i] : null,
6889 if (ri == mResolveInfo) {
6890 // ACK! Must do something better with this.
6892 ai = ri.activityInfo;
6893 comp = new ComponentName(ai.applicationInfo.packageName,
6896 ai = getActivityInfo(comp, flags, userId);
6902 // Look for any generic query activities that are duplicates
6903 // of this specific one, and remove them from the results.
6904 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
6907 for (j=specificsPos; j<N; j++) {
6908 ResolveInfo sri = results.get(j);
6909 if ((sri.activityInfo.name.equals(comp.getClassName())
6910 && sri.activityInfo.applicationInfo.packageName.equals(
6911 comp.getPackageName()))
6912 || (action != null && sri.filter.matchAction(action))) {
6914 if (DEBUG_INTENT_MATCHING) Log.v(
6915 TAG, "Removing duplicate item from " + j
6916 + " due to specific " + specificsPos);
6925 // Add this specific item to its proper place.
6927 ri = new ResolveInfo();
6928 ri.activityInfo = ai;
6930 results.add(specificsPos, ri);
6931 ri.specificIndex = i;
6936 // Now we go through the remaining generic results and remove any
6937 // duplicate actions that are found here.
6939 for (int i=specificsPos; i<N-1; i++) {
6940 final ResolveInfo rii = results.get(i);
6941 if (rii.filter == null) {
6945 // Iterate over all of the actions of this result's intent
6946 // filter... typically this should be just one.
6947 final Iterator<String> it = rii.filter.actionsIterator();
6951 while (it.hasNext()) {
6952 final String action = it.next();
6953 if (resultsAction != null && resultsAction.equals(action)) {
6954 // If this action was explicitly requested, then don't
6955 // remove things that have it.
6958 for (int j=i+1; j<N; j++) {
6959 final ResolveInfo rij = results.get(j);
6960 if (rij.filter != null && rij.filter.hasAction(action)) {
6962 if (DEBUG_INTENT_MATCHING) Log.v(
6963 TAG, "Removing duplicate item from " + j
6964 + " due to action " + action + " at " + i);
6971 // If the caller didn't request filter information, drop it now
6972 // so we don't have to marshall/unmarshall it.
6973 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
6978 // Filter out the caller activity if so requested.
6979 if (caller != null) {
6981 for (int i=0; i<N; i++) {
6982 ActivityInfo ainfo = results.get(i).activityInfo;
6983 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
6984 && caller.getClassName().equals(ainfo.name)) {
6991 // If the caller didn't request filter information,
6992 // drop them now so we don't have to
6993 // marshall/unmarshall it.
6994 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
6996 for (int i=0; i<N; i++) {
6997 results.get(i).filter = null;
7001 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
7006 public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
7007 String resolvedType, int flags, int userId) {
7008 return new ParceledListSlice<>(
7009 queryIntentReceiversInternal(intent, resolvedType, flags, userId));
7012 private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
7013 String resolvedType, int flags, int userId) {
7014 if (!sUserManager.exists(userId)) return Collections.emptyList();
7015 final int callingUid = Binder.getCallingUid();
7016 flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7017 false /*includeInstantApps*/);
7018 ComponentName comp = intent.getComponent();
7020 if (intent.getSelector() != null) {
7021 intent = intent.getSelector();
7022 comp = intent.getComponent();
7026 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7027 ActivityInfo ai = getReceiverInfo(comp, flags, userId);
7029 ResolveInfo ri = new ResolveInfo();
7030 ri.activityInfo = ai;
7037 synchronized (mPackages) {
7038 String pkgName = intent.getPackage();
7039 if (pkgName == null) {
7040 return mReceivers.queryIntent(intent, resolvedType, flags, userId);
7042 final PackageParser.Package pkg = mPackages.get(pkgName);
7044 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
7047 return Collections.emptyList();
7052 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
7053 final int callingUid = Binder.getCallingUid();
7054 return resolveServiceInternal(
7055 intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
7058 private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
7059 int userId, int callingUid, boolean includeInstantApps) {
7060 if (!sUserManager.exists(userId)) return null;
7061 flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
7062 List<ResolveInfo> query = queryIntentServicesInternal(
7063 intent, resolvedType, flags, userId, callingUid, includeInstantApps);
7064 if (query != null) {
7065 if (query.size() >= 1) {
7066 // If there is more than one service with the same priority,
7067 // just arbitrarily pick the first one.
7068 return query.get(0);
7075 public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
7076 String resolvedType, int flags, int userId) {
7077 final int callingUid = Binder.getCallingUid();
7078 return new ParceledListSlice<>(queryIntentServicesInternal(
7079 intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
7082 private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
7083 String resolvedType, int flags, int userId, int callingUid,
7084 boolean includeInstantApps) {
7085 if (!sUserManager.exists(userId)) return Collections.emptyList();
7086 final String instantAppPkgName = getInstantAppPackageName(callingUid);
7087 flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
7088 ComponentName comp = intent.getComponent();
7090 if (intent.getSelector() != null) {
7091 intent = intent.getSelector();
7092 comp = intent.getComponent();
7096 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7097 final ServiceInfo si = getServiceInfo(comp, flags, userId);
7099 // When specifying an explicit component, we prevent the service from being
7100 // used when either 1) the service is in an instant application and the
7101 // caller is not the same instant application or 2) the calling package is
7102 // ephemeral and the activity is not visible to ephemeral applications.
7103 final boolean matchInstantApp =
7104 (flags & PackageManager.MATCH_INSTANT) != 0;
7105 final boolean matchVisibleToInstantAppOnly =
7106 (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7107 final boolean isCallerInstantApp =
7108 instantAppPkgName != null;
7109 final boolean isTargetSameInstantApp =
7110 comp.getPackageName().equals(instantAppPkgName);
7111 final boolean isTargetInstantApp =
7112 (si.applicationInfo.privateFlags
7113 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7114 final boolean isTargetHiddenFromInstantApp =
7115 (si.flags & ServiceInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0;
7116 final boolean blockResolution =
7117 !isTargetSameInstantApp
7118 && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7119 || (matchVisibleToInstantAppOnly && isCallerInstantApp
7120 && isTargetHiddenFromInstantApp));
7121 if (!blockResolution) {
7122 final ResolveInfo ri = new ResolveInfo();
7123 ri.serviceInfo = si;
7131 synchronized (mPackages) {
7132 String pkgName = intent.getPackage();
7133 if (pkgName == null) {
7134 return applyPostServiceResolutionFilter(
7135 mServices.queryIntent(intent, resolvedType, flags, userId),
7138 final PackageParser.Package pkg = mPackages.get(pkgName);
7140 return applyPostServiceResolutionFilter(
7141 mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
7145 return Collections.emptyList();
7149 private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
7150 String instantAppPkgName) {
7151 // TODO: When adding on-demand split support for non-instant apps, remove this check
7152 // and always apply post filtering
7153 if (instantAppPkgName == null) {
7154 return resolveInfos;
7156 for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7157 final ResolveInfo info = resolveInfos.get(i);
7158 final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
7159 // allow services that are defined in the provided package
7160 if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
7161 if (info.serviceInfo.splitName != null
7162 && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
7163 info.serviceInfo.splitName)) {
7164 // requested service is defined in a split that hasn't been installed yet.
7165 // add the installer to the resolve list
7166 if (DEBUG_EPHEMERAL) {
7167 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7169 final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7170 installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7171 info.serviceInfo.packageName, info.serviceInfo.splitName,
7172 info.serviceInfo.applicationInfo.versionCode);
7173 // make sure this resolver is the default
7174 installerInfo.isDefault = true;
7175 installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7176 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7177 // add a non-generic filter
7178 installerInfo.filter = new IntentFilter();
7179 // load resources from the correct package
7180 installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7181 resolveInfos.set(i, installerInfo);
7185 // allow services that have been explicitly exposed to ephemeral apps
7187 && ((info.serviceInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0)) {
7190 resolveInfos.remove(i);
7192 return resolveInfos;
7196 public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
7197 String resolvedType, int flags, int userId) {
7198 return new ParceledListSlice<>(
7199 queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
7202 private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
7203 Intent intent, String resolvedType, int flags, int userId) {
7204 if (!sUserManager.exists(userId)) return Collections.emptyList();
7205 final int callingUid = Binder.getCallingUid();
7206 final String instantAppPkgName = getInstantAppPackageName(callingUid);
7207 flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7208 false /*includeInstantApps*/);
7209 ComponentName comp = intent.getComponent();
7211 if (intent.getSelector() != null) {
7212 intent = intent.getSelector();
7213 comp = intent.getComponent();
7217 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7218 final ProviderInfo pi = getProviderInfo(comp, flags, userId);
7220 // When specifying an explicit component, we prevent the provider from being
7221 // used when either 1) the provider is in an instant application and the
7222 // caller is not the same instant application or 2) the calling package is an
7223 // instant application and the provider is not visible to instant applications.
7224 final boolean matchInstantApp =
7225 (flags & PackageManager.MATCH_INSTANT) != 0;
7226 final boolean matchVisibleToInstantAppOnly =
7227 (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7228 final boolean isCallerInstantApp =
7229 instantAppPkgName != null;
7230 final boolean isTargetSameInstantApp =
7231 comp.getPackageName().equals(instantAppPkgName);
7232 final boolean isTargetInstantApp =
7233 (pi.applicationInfo.privateFlags
7234 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7235 final boolean isTargetHiddenFromInstantApp =
7236 (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0;
7237 final boolean blockResolution =
7238 !isTargetSameInstantApp
7239 && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7240 || (matchVisibleToInstantAppOnly && isCallerInstantApp
7241 && isTargetHiddenFromInstantApp));
7242 if (!blockResolution) {
7243 final ResolveInfo ri = new ResolveInfo();
7244 ri.providerInfo = pi;
7252 synchronized (mPackages) {
7253 String pkgName = intent.getPackage();
7254 if (pkgName == null) {
7255 return applyPostContentProviderResolutionFilter(
7256 mProviders.queryIntent(intent, resolvedType, flags, userId),
7259 final PackageParser.Package pkg = mPackages.get(pkgName);
7261 return applyPostContentProviderResolutionFilter(
7262 mProviders.queryIntentForPackage(
7263 intent, resolvedType, flags, pkg.providers, userId),
7266 return Collections.emptyList();
7270 private List<ResolveInfo> applyPostContentProviderResolutionFilter(
7271 List<ResolveInfo> resolveInfos, String instantAppPkgName) {
7272 // TODO: When adding on-demand split support for non-instant applications, remove
7273 // this check and always apply post filtering
7274 if (instantAppPkgName == null) {
7275 return resolveInfos;
7277 for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7278 final ResolveInfo info = resolveInfos.get(i);
7279 final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
7280 // allow providers that are defined in the provided package
7281 if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
7282 if (info.providerInfo.splitName != null
7283 && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
7284 info.providerInfo.splitName)) {
7285 // requested provider is defined in a split that hasn't been installed yet.
7286 // add the installer to the resolve list
7287 if (DEBUG_EPHEMERAL) {
7288 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7290 final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7291 installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7292 info.providerInfo.packageName, info.providerInfo.splitName,
7293 info.providerInfo.applicationInfo.versionCode);
7294 // make sure this resolver is the default
7295 installerInfo.isDefault = true;
7296 installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7297 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7298 // add a non-generic filter
7299 installerInfo.filter = new IntentFilter();
7300 // load resources from the correct package
7301 installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7302 resolveInfos.set(i, installerInfo);
7306 // allow providers that have been explicitly exposed to instant applications
7308 && ((info.providerInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0)) {
7311 resolveInfos.remove(i);
7313 return resolveInfos;
7317 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
7318 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7319 flags = updateFlagsForPackage(flags, userId, null);
7320 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7321 enforceCrossUserPermission(Binder.getCallingUid(), userId,
7322 true /* requireFullPermission */, false /* checkShell */,
7323 "get installed packages");
7326 synchronized (mPackages) {
7327 ArrayList<PackageInfo> list;
7328 if (listUninstalled) {
7329 list = new ArrayList<>(mSettings.mPackages.size());
7330 for (PackageSetting ps : mSettings.mPackages.values()) {
7331 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
7334 final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7340 list = new ArrayList<>(mPackages.size());
7341 for (PackageParser.Package p : mPackages.values()) {
7342 if (filterSharedLibPackageLPr((PackageSetting) p.mExtras,
7343 Binder.getCallingUid(), userId)) {
7346 final PackageInfo pi = generatePackageInfo((PackageSetting)
7347 p.mExtras, flags, userId);
7354 return new ParceledListSlice<>(list);
7358 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
7359 String[] permissions, boolean[] tmp, int flags, int userId) {
7361 final PermissionsState permissionsState = ps.getPermissionsState();
7362 for (int i=0; i<permissions.length; i++) {
7363 final String permission = permissions[i];
7364 if (permissionsState.hasPermission(permission, userId)) {
7371 if (numMatch == 0) {
7374 final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7376 // The above might return null in cases of uninstalled apps or install-state
7377 // skew across users/profiles.
7379 if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
7380 if (numMatch == permissions.length) {
7381 pi.requestedPermissions = permissions;
7383 pi.requestedPermissions = new String[numMatch];
7385 for (int i=0; i<permissions.length; i++) {
7387 pi.requestedPermissions[numMatch] = permissions[i];
7398 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
7399 String[] permissions, int flags, int userId) {
7400 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7401 flags = updateFlagsForPackage(flags, userId, permissions);
7402 enforceCrossUserPermission(Binder.getCallingUid(), userId,
7403 true /* requireFullPermission */, false /* checkShell */,
7404 "get packages holding permissions");
7405 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7408 synchronized (mPackages) {
7409 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
7410 boolean[] tmpBools = new boolean[permissions.length];
7411 if (listUninstalled) {
7412 for (PackageSetting ps : mSettings.mPackages.values()) {
7413 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7417 for (PackageParser.Package pkg : mPackages.values()) {
7418 PackageSetting ps = (PackageSetting)pkg.mExtras;
7420 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7426 return new ParceledListSlice<PackageInfo>(list);
7431 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
7432 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7433 flags = updateFlagsForApplication(flags, userId, null);
7434 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7437 synchronized (mPackages) {
7438 ArrayList<ApplicationInfo> list;
7439 if (listUninstalled) {
7440 list = new ArrayList<>(mSettings.mPackages.size());
7441 for (PackageSetting ps : mSettings.mPackages.values()) {
7443 int effectiveFlags = flags;
7444 if (ps.isSystem()) {
7445 effectiveFlags |= PackageManager.MATCH_ANY_USER;
7447 if (ps.pkg != null) {
7448 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
7451 ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
7452 ps.readUserState(userId), userId);
7454 rebaseEnabledOverlays(ai, userId);
7455 ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
7458 // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
7459 // and already converts to externally visible package name
7460 ai = generateApplicationInfoFromSettingsLPw(ps.name,
7461 Binder.getCallingUid(), effectiveFlags, userId);
7468 list = new ArrayList<>(mPackages.size());
7469 for (PackageParser.Package p : mPackages.values()) {
7470 if (p.mExtras != null) {
7471 PackageSetting ps = (PackageSetting) p.mExtras;
7472 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
7475 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
7476 ps.readUserState(userId), userId);
7478 rebaseEnabledOverlays(ai, userId);
7479 ai.packageName = resolveExternalPackageNameLPr(p);
7486 return new ParceledListSlice<>(list);
7491 public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
7492 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7496 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
7497 "getEphemeralApplications");
7498 enforceCrossUserPermission(Binder.getCallingUid(), userId,
7499 true /* requireFullPermission */, false /* checkShell */,
7500 "getEphemeralApplications");
7501 synchronized (mPackages) {
7502 List<InstantAppInfo> instantApps = mInstantAppRegistry
7503 .getInstantAppsLPr(userId);
7504 if (instantApps != null) {
7505 return new ParceledListSlice<>(instantApps);
7512 public boolean isInstantApp(String packageName, int userId) {
7513 enforceCrossUserPermission(Binder.getCallingUid(), userId,
7514 true /* requireFullPermission */, false /* checkShell */,
7516 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7519 int uid = Binder.getCallingUid();
7520 if (Process.isIsolated(uid)) {
7521 uid = mIsolatedOwners.get(uid);
7524 synchronized (mPackages) {
7525 final PackageSetting ps = mSettings.mPackages.get(packageName);
7526 PackageParser.Package pkg = mPackages.get(packageName);
7527 final boolean returnAllowed =
7529 && (isCallerSameApp(packageName, uid)
7530 || mContext.checkCallingOrSelfPermission(
7531 android.Manifest.permission.ACCESS_INSTANT_APPS)
7532 == PERMISSION_GRANTED
7533 || mInstantAppRegistry.isInstantAccessGranted(
7534 userId, UserHandle.getAppId(uid), ps.appId));
7535 if (returnAllowed) {
7536 return ps.getInstantApp(userId);
7543 public byte[] getInstantAppCookie(String packageName, int userId) {
7544 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7548 enforceCrossUserPermission(Binder.getCallingUid(), userId,
7549 true /* requireFullPermission */, false /* checkShell */,
7550 "getInstantAppCookie");
7551 if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
7554 synchronized (mPackages) {
7555 return mInstantAppRegistry.getInstantAppCookieLPw(
7556 packageName, userId);
7561 public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
7562 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7566 enforceCrossUserPermission(Binder.getCallingUid(), userId,
7567 true /* requireFullPermission */, true /* checkShell */,
7568 "setInstantAppCookie");
7569 if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
7572 synchronized (mPackages) {
7573 return mInstantAppRegistry.setInstantAppCookieLPw(
7574 packageName, cookie, userId);
7579 public Bitmap getInstantAppIcon(String packageName, int userId) {
7580 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7584 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
7585 "getInstantAppIcon");
7587 enforceCrossUserPermission(Binder.getCallingUid(), userId,
7588 true /* requireFullPermission */, false /* checkShell */,
7589 "getInstantAppIcon");
7591 synchronized (mPackages) {
7592 return mInstantAppRegistry.getInstantAppIconLPw(
7593 packageName, userId);
7597 private boolean isCallerSameApp(String packageName, int uid) {
7598 PackageParser.Package pkg = mPackages.get(packageName);
7600 && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
7604 public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
7605 return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
7608 private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
7609 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
7612 synchronized (mPackages) {
7613 final Iterator<PackageParser.Package> i = mPackages.values().iterator();
7614 final int userId = UserHandle.getCallingUserId();
7615 while (i.hasNext()) {
7616 final PackageParser.Package p = i.next();
7617 if (p.applicationInfo == null) continue;
7619 final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
7620 && !p.applicationInfo.isDirectBootAware();
7621 final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
7622 && p.applicationInfo.isDirectBootAware();
7624 if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
7625 && (!mSafeMode || isSystemApp(p))
7626 && (matchesUnaware || matchesAware)) {
7627 PackageSetting ps = mSettings.mPackages.get(p.packageName);
7629 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
7630 ps.readUserState(userId), userId);
7632 rebaseEnabledOverlays(ai, userId);
7644 public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
7645 if (!sUserManager.exists(userId)) return null;
7646 flags = updateFlagsForComponent(flags, userId, name);
7647 final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid());
7649 synchronized (mPackages) {
7650 final PackageParser.Provider provider = mProvidersByAuthority.get(name);
7651 PackageSetting ps = provider != null
7652 ? mSettings.mPackages.get(provider.owner.packageName)
7655 final boolean isInstantApp = ps.getInstantApp(userId);
7656 // normal application; filter out instant application provider
7657 if (instantAppPkgName == null && isInstantApp) {
7660 // instant application; filter out other instant applications
7661 if (instantAppPkgName != null
7663 && !provider.owner.packageName.equals(instantAppPkgName)) {
7666 // instant application; filter out non-exposed provider
7667 if (instantAppPkgName != null
7668 && (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0) {
7671 // provider not enabled
7672 if (!mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)) {
7675 return PackageParser.generateProviderInfo(
7676 provider, flags, ps.readUserState(userId), userId);
7686 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
7688 synchronized (mPackages) {
7689 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
7690 .entrySet().iterator();
7691 final int userId = UserHandle.getCallingUserId();
7692 while (i.hasNext()) {
7693 Map.Entry<String, PackageParser.Provider> entry = i.next();
7694 PackageParser.Provider p = entry.getValue();
7695 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
7697 if (ps != null && p.syncable
7698 && (!mSafeMode || (p.info.applicationInfo.flags
7699 &ApplicationInfo.FLAG_SYSTEM) != 0)) {
7700 ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
7701 ps.readUserState(userId), userId);
7703 outNames.add(entry.getKey());
7712 public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
7713 int uid, int flags, String metaDataKey) {
7714 final int userId = processName != null ? UserHandle.getUserId(uid)
7715 : UserHandle.getCallingUserId();
7716 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7717 flags = updateFlagsForComponent(flags, userId, processName);
7719 ArrayList<ProviderInfo> finalList = null;
7721 synchronized (mPackages) {
7722 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
7723 while (i.hasNext()) {
7724 final PackageParser.Provider p = i.next();
7725 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
7726 if (ps != null && p.info.authority != null
7727 && (processName == null
7728 || (p.info.processName.equals(processName)
7729 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
7730 && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
7732 // See PM.queryContentProviders()'s javadoc for why we have the metaData
7734 if (metaDataKey != null
7735 && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
7739 if (finalList == null) {
7740 finalList = new ArrayList<ProviderInfo>(3);
7742 ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
7743 ps.readUserState(userId), userId);
7745 finalList.add(info);
7751 if (finalList != null) {
7752 Collections.sort(finalList, mProviderInitOrderSorter);
7753 return new ParceledListSlice<ProviderInfo>(finalList);
7756 return ParceledListSlice.emptyList();
7760 public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) {
7762 synchronized (mPackages) {
7763 final PackageParser.Instrumentation i = mInstrumentation.get(name);
7764 return PackageParser.generateInstrumentationInfo(i, flags);
7769 public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
7770 String targetPackage, int flags) {
7771 return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
7774 private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
7776 ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
7779 synchronized (mPackages) {
7780 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
7781 while (i.hasNext()) {
7782 final PackageParser.Instrumentation p = i.next();
7783 if (targetPackage == null
7784 || targetPackage.equals(p.info.targetPackage)) {
7785 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
7797 private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
7798 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + dir.getAbsolutePath() + "]");
7800 scanDirLI(dir, parseFlags, scanFlags, currentTime);
7802 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7806 private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
7807 final File[] files = dir.listFiles();
7808 if (ArrayUtils.isEmpty(files)) {
7809 Log.d(TAG, "No files in app dir " + dir);
7813 if (DEBUG_PACKAGE_SCANNING) {
7814 Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
7815 + " flags=0x" + Integer.toHexString(parseFlags));
7817 ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
7818 mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir, mPackageParserCallback);
7820 // Submit files for parsing in parallel
7822 for (File file : files) {
7823 final boolean isPackage = (isApkFile(file) || file.isDirectory())
7824 && !PackageInstallerService.isStageName(file.getName());
7826 // Ignore entries which are not packages
7829 parallelPackageParser.submit(file, parseFlags);
7833 // Process results one by one
7834 for (; fileCount > 0; fileCount--) {
7835 ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
7836 Throwable throwable = parseResult.throwable;
7837 int errorCode = PackageManager.INSTALL_SUCCEEDED;
7839 if (throwable == null) {
7840 // Static shared libraries have synthetic package names
7841 if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
7842 renameStaticSharedLibraryPackage(parseResult.pkg);
7845 if (errorCode == PackageManager.INSTALL_SUCCEEDED) {
7846 scanPackageLI(parseResult.pkg, parseResult.scanFile, parseFlags, scanFlags,
7849 } catch (PackageManagerException e) {
7850 errorCode = e.error;
7851 Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
7853 } else if (throwable instanceof PackageParser.PackageParserException) {
7854 PackageParser.PackageParserException e = (PackageParser.PackageParserException)
7856 errorCode = e.error;
7857 Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
7859 throw new IllegalStateException("Unexpected exception occurred while parsing "
7860 + parseResult.scanFile, throwable);
7863 // Delete invalid userdata apps
7864 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
7865 errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) {
7866 logCriticalInfo(Log.WARN,
7867 "Deleting invalid package at " + parseResult.scanFile);
7868 removeCodePathLI(parseResult.scanFile);
7871 parallelPackageParser.close();
7874 private static File getSettingsProblemFile() {
7875 File dataDir = Environment.getDataDirectory();
7876 File systemDir = new File(dataDir, "system");
7877 File fname = new File(systemDir, "uiderrors.txt");
7881 static void reportSettingsProblem(int priority, String msg) {
7882 logCriticalInfo(priority, msg);
7885 public static void logCriticalInfo(int priority, String msg) {
7886 Slog.println(priority, TAG, msg);
7887 EventLogTags.writePmCriticalInfo(msg);
7889 File fname = getSettingsProblemFile();
7890 FileOutputStream out = new FileOutputStream(fname, true);
7891 PrintWriter pw = new FastPrintWriter(out);
7892 SimpleDateFormat formatter = new SimpleDateFormat();
7893 String dateString = formatter.format(new Date(System.currentTimeMillis()));
7894 pw.println(dateString + ": " + msg);
7896 FileUtils.setPermissions(
7898 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
7900 } catch (java.io.IOException e) {
7904 private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) {
7905 if (srcFile.isDirectory()) {
7906 final File baseFile = new File(pkg.baseCodePath);
7907 long maxModifiedTime = baseFile.lastModified();
7908 if (pkg.splitCodePaths != null) {
7909 for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) {
7910 final File splitFile = new File(pkg.splitCodePaths[i]);
7911 maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified());
7914 return maxModifiedTime;
7916 return srcFile.lastModified();
7919 private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile,
7920 final int policyFlags) throws PackageManagerException {
7921 // When upgrading from pre-N MR1, verify the package time stamp using the package
7922 // directory and not the APK file.
7923 final long lastModifiedTime = mIsPreNMR1Upgrade
7924 ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg, srcFile);
7926 && ps.codePath.equals(srcFile)
7927 && ps.timeStamp == lastModifiedTime
7928 && !isCompatSignatureUpdateNeeded(pkg)
7929 && !isRecoverSignatureUpdateNeeded(pkg)) {
7930 long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
7931 KeySetManagerService ksms = mSettings.mKeySetManagerService;
7932 ArraySet<PublicKey> signingKs;
7933 synchronized (mPackages) {
7934 signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
7936 if (ps.signatures.mSignatures != null
7937 && ps.signatures.mSignatures.length != 0
7938 && signingKs != null) {
7939 // Optimization: reuse the existing cached certificates
7940 // if the package appears to be unchanged.
7941 pkg.mSignatures = ps.signatures.mSignatures;
7942 pkg.mSigningKeys = signingKs;
7946 Slog.w(TAG, "PackageSetting for " + ps.name
7947 + " is missing signatures. Collecting certs again to recover them.");
7949 Slog.i(TAG, srcFile.toString() + " changed; collecting certs");
7953 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
7954 PackageParser.collectCertificates(pkg, policyFlags);
7955 } catch (PackageParserException e) {
7956 throw PackageManagerException.from(e);
7958 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7963 * Traces a package scan.
7964 * @see #scanPackageLI(File, int, int, long, UserHandle)
7966 private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
7967 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
7968 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
7970 return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
7972 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7977 * Scans a package and returns the newly parsed package.
7978 * Returns {@code null} in case of errors and the error code is stored in mLastScanError
7980 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
7981 long currentTime, UserHandle user) throws PackageManagerException {
7982 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
7983 PackageParser pp = new PackageParser();
7984 pp.setSeparateProcesses(mSeparateProcesses);
7985 pp.setOnlyCoreApps(mOnlyCore);
7986 pp.setDisplayMetrics(mMetrics);
7987 pp.setCallback(mPackageParserCallback);
7989 if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
7990 parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
7993 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
7994 final PackageParser.Package pkg;
7996 pkg = pp.parsePackage(scanFile, parseFlags);
7997 } catch (PackageParserException e) {
7998 throw PackageManagerException.from(e);
8000 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8003 // Static shared libraries have synthetic package names
8004 if (pkg.applicationInfo.isStaticSharedLibrary()) {
8005 renameStaticSharedLibraryPackage(pkg);
8008 return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
8012 * Scans a package and returns the newly parsed package.
8013 * @throws PackageManagerException on a parse error.
8015 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile,
8016 final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
8017 throws PackageManagerException {
8018 // If the package has children and this is the first dive in the function
8019 // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
8020 // packages (parent and children) would be successfully scanned before the
8021 // actual scan since scanning mutates internal state and we want to atomically
8022 // install the package and its children.
8023 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
8024 if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
8025 scanFlags |= SCAN_CHECK_ONLY;
8028 scanFlags &= ~SCAN_CHECK_ONLY;
8032 PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags,
8033 scanFlags, currentTime, user);
8035 // Scan the children
8036 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8037 for (int i = 0; i < childCount; i++) {
8038 PackageParser.Package childPackage = pkg.childPackages.get(i);
8039 scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags,
8044 if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8045 return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user);
8052 * Scans a package and returns the newly parsed package.
8053 * @throws PackageManagerException on a parse error.
8055 private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile,
8056 int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
8057 throws PackageManagerException {
8058 PackageSetting ps = null;
8059 PackageSetting updatedPkg;
8061 synchronized (mPackages) {
8062 // Look to see if we already know about this package.
8063 String oldName = mSettings.getRenamedPackageLPr(pkg.packageName);
8064 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
8065 // This package has been renamed to its original name. Let's
8067 ps = mSettings.getPackageLPr(oldName);
8069 // If there was no original package, see one for the real package name.
8071 ps = mSettings.getPackageLPr(pkg.packageName);
8073 // Check to see if this package could be hiding/updating a system
8074 // package. Must look for it either under the original or real
8075 // package name depending on our state.
8076 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
8077 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
8079 // If this is a package we don't know about on the system partition, we
8080 // may need to remove disabled child packages on the system partition
8081 // or may need to not add child packages if the parent apk is updated
8082 // on the data partition and no longer defines this child package.
8083 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
8084 // If this is a parent package for an updated system app and this system
8085 // app got an OTA update which no longer defines some of the child packages
8086 // we have to prune them from the disabled system packages.
8087 PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
8088 if (disabledPs != null) {
8089 final int scannedChildCount = (pkg.childPackages != null)
8090 ? pkg.childPackages.size() : 0;
8091 final int disabledChildCount = disabledPs.childPackageNames != null
8092 ? disabledPs.childPackageNames.size() : 0;
8093 for (int i = 0; i < disabledChildCount; i++) {
8094 String disabledChildPackageName = disabledPs.childPackageNames.get(i);
8095 boolean disabledPackageAvailable = false;
8096 for (int j = 0; j < scannedChildCount; j++) {
8097 PackageParser.Package childPkg = pkg.childPackages.get(j);
8098 if (childPkg.packageName.equals(disabledChildPackageName)) {
8099 disabledPackageAvailable = true;
8103 if (!disabledPackageAvailable) {
8104 mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
8111 boolean updatedPkgBetter = false;
8112 // First check if this is a system package that may involve an update
8113 if (updatedPkg != null && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
8114 // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
8115 // it needs to drop FLAG_PRIVILEGED.
8116 if (locationIsPrivileged(scanFile)) {
8117 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
8119 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
8122 if (ps != null && !ps.codePath.equals(scanFile)) {
8123 // The path has changed from what was last scanned... check the
8124 // version of the new path against what we have stored to determine
8126 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
8127 if (pkg.mVersionCode <= ps.versionCode) {
8128 // The system package has been updated and the code path does not match
8129 // Ignore entry. Skip it.
8130 if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile
8131 + " ignored: updated version " + ps.versionCode
8132 + " better than this " + pkg.mVersionCode);
8133 if (!updatedPkg.codePath.equals(scanFile)) {
8134 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
8135 + ps.name + " changing from " + updatedPkg.codePathString
8136 + " to " + scanFile);
8137 updatedPkg.codePath = scanFile;
8138 updatedPkg.codePathString = scanFile.toString();
8139 updatedPkg.resourcePath = scanFile;
8140 updatedPkg.resourcePathString = scanFile.toString();
8142 updatedPkg.pkg = pkg;
8143 updatedPkg.versionCode = pkg.mVersionCode;
8145 // Update the disabled system child packages to point to the package too.
8146 final int childCount = updatedPkg.childPackageNames != null
8147 ? updatedPkg.childPackageNames.size() : 0;
8148 for (int i = 0; i < childCount; i++) {
8149 String childPackageName = updatedPkg.childPackageNames.get(i);
8150 PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr(
8152 if (updatedChildPkg != null) {
8153 updatedChildPkg.pkg = pkg;
8154 updatedChildPkg.versionCode = pkg.mVersionCode;
8158 throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
8159 + scanFile + " ignored: updated version " + ps.versionCode
8160 + " better than this " + pkg.mVersionCode);
8162 // The current app on the system partition is better than
8163 // what we have updated to on the data partition; switch
8164 // back to the system partition version.
8165 // At this point, its safely assumed that package installation for
8166 // apps in system partition will go through. If not there won't be a working
8167 // version of the app
8169 synchronized (mPackages) {
8170 // Just remove the loaded entries from package lists.
8171 mPackages.remove(ps.name);
8174 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
8175 + " reverting from " + ps.codePathString
8176 + ": new version " + pkg.mVersionCode
8177 + " better than installed " + ps.versionCode);
8179 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
8180 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
8181 synchronized (mInstallLock) {
8182 args.cleanUpResourcesLI();
8184 synchronized (mPackages) {
8185 mSettings.enableSystemPackageLPw(ps.name);
8187 updatedPkgBetter = true;
8192 if (updatedPkg != null) {
8193 // An updated system app will not have the PARSE_IS_SYSTEM flag set
8195 policyFlags |= PackageParser.PARSE_IS_SYSTEM;
8197 // An updated privileged app will not have the PARSE_IS_PRIVILEGED
8198 // flag set initially
8199 if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
8200 policyFlags |= PackageParser.PARSE_IS_PRIVILEGED;
8204 // Verify certificates against what was last scanned
8205 collectCertificatesLI(ps, pkg, scanFile, policyFlags);
8208 * A new system app appeared, but we already had a non-system one of the
8209 * same name installed earlier.
8211 boolean shouldHideSystemApp = false;
8212 if (updatedPkg == null && ps != null
8213 && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
8215 * Check to make sure the signatures match first. If they don't,
8216 * wipe the installed application and its data.
8218 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
8219 != PackageManager.SIGNATURE_MATCH) {
8220 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
8221 + " signatures don't match existing userdata copy; removing");
8222 try (PackageFreezer freezer = freezePackage(pkg.packageName,
8223 "scanPackageInternalLI")) {
8224 deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
8229 * If the newly-added system app is an older version than the
8230 * already installed version, hide it. It will be scanned later
8231 * and re-added like an update.
8233 if (pkg.mVersionCode <= ps.versionCode) {
8234 shouldHideSystemApp = true;
8235 logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
8236 + " but new version " + pkg.mVersionCode + " better than installed "
8237 + ps.versionCode + "; hiding system");
8240 * The newly found system app is a newer version that the
8241 * one previously installed. Simply remove the
8242 * already-installed application and replace it with our own
8243 * while keeping the application data.
8245 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
8246 + " reverting from " + ps.codePathString + ": new version "
8247 + pkg.mVersionCode + " better than installed " + ps.versionCode);
8248 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
8249 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
8250 synchronized (mInstallLock) {
8251 args.cleanUpResourcesLI();
8257 // The apk is forward locked (not public) if its code and resources
8258 // are kept in different files. (except for app in either system or
8260 // TODO grab this value from PackageSettings
8261 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
8262 if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
8263 policyFlags |= PackageParser.PARSE_FORWARD_LOCK;
8267 // TODO: extend to support forward-locked splits
8268 String resourcePath = null;
8269 String baseResourcePath = null;
8270 if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
8271 if (ps != null && ps.resourcePathString != null) {
8272 resourcePath = ps.resourcePathString;
8273 baseResourcePath = ps.resourcePathString;
8275 // Should not happen at all. Just log an error.
8276 Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
8279 resourcePath = pkg.codePath;
8280 baseResourcePath = pkg.baseCodePath;
8283 // Set application objects path explicitly.
8284 pkg.setApplicationVolumeUuid(pkg.volumeUuid);
8285 pkg.setApplicationInfoCodePath(pkg.codePath);
8286 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
8287 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
8288 pkg.setApplicationInfoResourcePath(resourcePath);
8289 pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
8290 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
8292 final int userId = ((user == null) ? 0 : user.getIdentifier());
8293 if (ps != null && ps.getInstantApp(userId)) {
8294 scanFlags |= SCAN_AS_INSTANT_APP;
8297 // Note that we invoke the following method only if we are about to unpack an application
8298 PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags
8299 | SCAN_UPDATE_SIGNATURE, currentTime, user);
8302 * If the system app should be overridden by a previously installed
8303 * data, hide the system app now and let the /data/app scan pick it up
8306 if (shouldHideSystemApp) {
8307 synchronized (mPackages) {
8308 mSettings.disableSystemPackageLPw(pkg.packageName, true);
8315 private void renameStaticSharedLibraryPackage(PackageParser.Package pkg) {
8316 // Derive the new package synthetic package name
8317 pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER
8318 + pkg.staticSharedLibVersion);
8321 private static String fixProcessName(String defProcessName,
8322 String processName) {
8323 if (processName == null) {
8324 return defProcessName;
8329 private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
8330 throws PackageManagerException {
8331 if (pkgSetting.signatures.mSignatures != null) {
8332 // Already existing package. Make sure signatures match
8333 boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
8334 == PackageManager.SIGNATURE_MATCH;
8336 match = compareSignaturesCompat(pkgSetting.signatures, pkg)
8337 == PackageManager.SIGNATURE_MATCH;
8340 match = compareSignaturesRecover(pkgSetting.signatures, pkg)
8341 == PackageManager.SIGNATURE_MATCH;
8344 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
8345 + pkg.packageName + " signatures do not match the "
8346 + "previously installed version; ignoring!");
8350 // Check for shared user signatures
8351 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
8352 // Already existing package. Make sure signatures match
8353 boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
8354 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
8356 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
8357 == PackageManager.SIGNATURE_MATCH;
8360 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
8361 == PackageManager.SIGNATURE_MATCH;
8364 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
8365 "Package " + pkg.packageName
8366 + " has no signatures that match those in shared user "
8367 + pkgSetting.sharedUser.name + "; ignoring!");
8373 * Enforces that only the system UID or root's UID can call a method exposed
8376 * @param message used as message if SecurityException is thrown
8377 * @throws SecurityException if the caller is not system or root
8379 private static final void enforceSystemOrRoot(String message) {
8380 final int uid = Binder.getCallingUid();
8381 if (uid != Process.SYSTEM_UID && uid != 0) {
8382 throw new SecurityException(message);
8387 public void performFstrimIfNeeded() {
8388 enforceSystemOrRoot("Only the system can request fstrim");
8390 // Before everything else, see whether we need to fstrim.
8392 IStorageManager sm = PackageHelper.getStorageManager();
8394 boolean doTrim = false;
8395 final long interval = android.provider.Settings.Global.getLong(
8396 mContext.getContentResolver(),
8397 android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
8398 DEFAULT_MANDATORY_FSTRIM_INTERVAL);
8400 final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
8401 if (timeSinceLast > interval) {
8403 Slog.w(TAG, "No disk maintenance in " + timeSinceLast
8404 + "; running immediately");
8408 final boolean dexOptDialogShown;
8409 synchronized (mPackages) {
8410 dexOptDialogShown = mDexOptDialogShown;
8412 if (!isFirstBoot() && dexOptDialogShown) {
8414 ActivityManager.getService().showBootMessage(
8415 mContext.getResources().getString(
8416 R.string.android_upgrading_fstrim), true);
8417 } catch (RemoteException e) {
8420 sm.runMaintenance();
8423 Slog.e(TAG, "storageManager service unavailable!");
8425 } catch (RemoteException e) {
8426 // Can't happen; StorageManagerService is local
8431 public void updatePackagesIfNeeded() {
8432 enforceSystemOrRoot("Only the system can request package update");
8434 // We need to re-extract after an OTA.
8435 boolean causeUpgrade = isUpgrade();
8437 // First boot or factory reset.
8438 // Note: we also handle devices that are upgrading to N right now as if it is their
8439 // first boot, as they do not have profile data.
8440 boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
8442 // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
8443 boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
8445 if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
8449 List<PackageParser.Package> pkgs;
8450 synchronized (mPackages) {
8451 pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
8454 final long startTime = System.nanoTime();
8455 final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
8456 getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT));
8458 final int elapsedTimeSeconds =
8459 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
8461 MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
8462 MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
8463 MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
8464 MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
8465 MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
8469 * Performs dexopt on the set of packages in {@code packages} and returns an int array
8470 * containing statistics about the invocation. The array consists of three elements,
8471 * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
8472 * and {@code numberOfPackagesFailed}.
8474 private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
8475 String compilerFilter) {
8477 int numberOfPackagesVisited = 0;
8478 int numberOfPackagesOptimized = 0;
8479 int numberOfPackagesSkipped = 0;
8480 int numberOfPackagesFailed = 0;
8481 final int numberOfPackagesToDexopt = pkgs.size();
8483 for (PackageParser.Package pkg : pkgs) {
8484 numberOfPackagesVisited++;
8486 if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
8488 Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
8490 numberOfPackagesSkipped++;
8495 Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
8496 numberOfPackagesToDexopt + ": " + pkg.packageName);
8501 ActivityManager.getService().showBootMessage(
8502 mContext.getResources().getString(R.string.android_upgrading_apk,
8503 numberOfPackagesVisited, numberOfPackagesToDexopt), true);
8504 } catch (RemoteException e) {
8506 synchronized (mPackages) {
8507 mDexOptDialogShown = true;
8511 // If the OTA updates a system app which was previously preopted to a non-preopted state
8512 // the app might end up being verified at runtime. That's because by default the apps
8513 // are verify-profile but for preopted apps there's no profile.
8514 // Do a hacky check to ensure that if we have no profiles (a reasonable indication
8515 // that before the OTA the app was preopted) the app gets compiled with a non-profile
8516 // filter (by default interpret-only).
8517 // Note that at this stage unused apps are already filtered.
8518 if (isSystemApp(pkg) &&
8519 DexFile.isProfileGuidedCompilerFilter(compilerFilter) &&
8520 !Environment.getReferenceProfile(pkg.packageName).exists()) {
8521 compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter);
8524 // checkProfiles is false to avoid merging profiles during boot which
8525 // might interfere with background compilation (b/28612421).
8526 // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
8527 // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
8528 // trade-off worth doing to save boot time work.
8529 int dexOptStatus = performDexOptTraced(pkg.packageName,
8530 false /* checkProfiles */,
8533 switch (dexOptStatus) {
8534 case PackageDexOptimizer.DEX_OPT_PERFORMED:
8535 numberOfPackagesOptimized++;
8537 case PackageDexOptimizer.DEX_OPT_SKIPPED:
8538 numberOfPackagesSkipped++;
8540 case PackageDexOptimizer.DEX_OPT_FAILED:
8541 numberOfPackagesFailed++;
8544 Log.e(TAG, "Unexpected dexopt return code " + dexOptStatus);
8549 return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
8550 numberOfPackagesFailed };
8554 public void notifyPackageUse(String packageName, int reason) {
8555 synchronized (mPackages) {
8556 PackageParser.Package p = mPackages.get(packageName);
8560 p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
8565 public void notifyDexLoad(String loadingPackageName, List<String> dexPaths, String loaderIsa) {
8566 int userId = UserHandle.getCallingUserId();
8567 ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
8569 Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
8570 + loadingPackageName + ", user=" + userId);
8573 mDexManager.notifyDexLoad(ai, dexPaths, loaderIsa, userId);
8576 // TODO: this is not used nor needed. Delete it.
8578 public boolean performDexOptIfNeeded(String packageName) {
8579 int dexOptStatus = performDexOptTraced(packageName,
8580 false /* checkProfiles */, getFullCompilerFilter(), false /* force */);
8581 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
8585 public boolean performDexOpt(String packageName,
8586 boolean checkProfiles, int compileReason, boolean force) {
8587 int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
8588 getCompilerFilterForReason(compileReason), force);
8589 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
8593 public boolean performDexOptMode(String packageName,
8594 boolean checkProfiles, String targetCompilerFilter, boolean force) {
8595 int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
8596 targetCompilerFilter, force);
8597 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
8600 private int performDexOptTraced(String packageName,
8601 boolean checkProfiles, String targetCompilerFilter, boolean force) {
8602 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
8604 return performDexOptInternal(packageName, checkProfiles,
8605 targetCompilerFilter, force);
8607 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8611 // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
8612 // if the package can now be considered up to date for the given filter.
8613 private int performDexOptInternal(String packageName,
8614 boolean checkProfiles, String targetCompilerFilter, boolean force) {
8615 PackageParser.Package p;
8616 synchronized (mPackages) {
8617 p = mPackages.get(packageName);
8619 // Package could not be found. Report failure.
8620 return PackageDexOptimizer.DEX_OPT_FAILED;
8622 mPackageUsage.maybeWriteAsync(mPackages);
8623 mCompilerStats.maybeWriteAsync();
8625 long callingId = Binder.clearCallingIdentity();
8627 synchronized (mInstallLock) {
8628 return performDexOptInternalWithDependenciesLI(p, checkProfiles,
8629 targetCompilerFilter, force);
8632 Binder.restoreCallingIdentity(callingId);
8636 public ArraySet<String> getOptimizablePackages() {
8637 ArraySet<String> pkgs = new ArraySet<String>();
8638 synchronized (mPackages) {
8639 for (PackageParser.Package p : mPackages.values()) {
8640 if (PackageDexOptimizer.canOptimizePackage(p)) {
8641 pkgs.add(p.packageName);
8648 private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
8649 boolean checkProfiles, String targetCompilerFilter,
8651 // Select the dex optimizer based on the force parameter.
8652 // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
8653 // allocate an object here.
8654 PackageDexOptimizer pdo = force
8655 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
8656 : mPackageDexOptimizer;
8658 // Dexopt all dependencies first. Note: we ignore the return value and march on
8660 // Note that we are going to call performDexOpt on those libraries as many times as
8661 // they are referenced in packages. When we do a batch of performDexOpt (for example
8662 // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
8663 // and the first package that uses the library will dexopt it. The
8664 // others will see that the compiled code for the library is up to date.
8665 Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
8666 final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
8667 if (!deps.isEmpty()) {
8668 for (PackageParser.Package depPackage : deps) {
8669 // TODO: Analyze and investigate if we (should) profile libraries.
8670 pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
8671 false /* checkProfiles */,
8672 targetCompilerFilter,
8673 getOrCreateCompilerPackageStats(depPackage),
8674 true /* isUsedByOtherApps */);
8677 return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles,
8678 targetCompilerFilter, getOrCreateCompilerPackageStats(p),
8679 mDexManager.isUsedByOtherApps(p.packageName));
8682 // Performs dexopt on the used secondary dex files belonging to the given package.
8683 // Returns true if all dex files were process successfully (which could mean either dexopt or
8684 // skip). Returns false if any of the files caused errors.
8686 public boolean performDexOptSecondary(String packageName, String compilerFilter,
8688 mDexManager.reconcileSecondaryDexFiles(packageName);
8689 return mDexManager.dexoptSecondaryDex(packageName, compilerFilter, force);
8692 public boolean performDexOptSecondary(String packageName, int compileReason,
8694 return mDexManager.dexoptSecondaryDex(packageName, compileReason, force);
8698 * Reconcile the information we have about the secondary dex files belonging to
8699 * {@code packagName} and the actual dex files. For all dex files that were
8700 * deleted, update the internal records and delete the generated oat files.
8703 public void reconcileSecondaryDexFiles(String packageName) {
8704 mDexManager.reconcileSecondaryDexFiles(packageName);
8707 // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
8708 // a reference there.
8709 /*package*/ DexManager getDexManager() {
8714 * Execute the background dexopt job immediately.
8717 public boolean runBackgroundDexoptJob() {
8718 return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext);
8721 List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
8722 if (p.usesLibraries != null || p.usesOptionalLibraries != null
8723 || p.usesStaticLibraries != null) {
8724 ArrayList<PackageParser.Package> retValue = new ArrayList<>();
8725 Set<String> collectedNames = new HashSet<>();
8726 findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
8732 return Collections.emptyList();
8736 private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
8737 ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
8738 if (!collectedNames.contains(p.packageName)) {
8739 collectedNames.add(p.packageName);
8742 if (p.usesLibraries != null) {
8743 findSharedNonSystemLibrariesRecursive(p.usesLibraries,
8744 null, collected, collectedNames);
8746 if (p.usesOptionalLibraries != null) {
8747 findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries,
8748 null, collected, collectedNames);
8750 if (p.usesStaticLibraries != null) {
8751 findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries,
8752 p.usesStaticLibrariesVersions, collected, collectedNames);
8757 private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, int[] versions,
8758 ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
8759 final int libNameCount = libs.size();
8760 for (int i = 0; i < libNameCount; i++) {
8761 String libName = libs.get(i);
8762 int version = (versions != null && versions.length == libNameCount)
8763 ? versions[i] : PackageManager.VERSION_CODE_HIGHEST;
8764 PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version);
8765 if (libPkg != null) {
8766 findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
8771 private PackageParser.Package findSharedNonSystemLibrary(String name, int version) {
8772 synchronized (mPackages) {
8773 SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version);
8774 if (libEntry != null) {
8775 return mPackages.get(libEntry.apk);
8781 private SharedLibraryEntry getSharedLibraryEntryLPr(String name, int version) {
8782 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
8783 if (versionedLib == null) {
8786 return versionedLib.get(version);
8789 private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
8790 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
8791 pkg.staticSharedLibName);
8792 if (versionedLib == null) {
8795 int previousLibVersion = -1;
8796 final int versionCount = versionedLib.size();
8797 for (int i = 0; i < versionCount; i++) {
8798 final int libVersion = versionedLib.keyAt(i);
8799 if (libVersion < pkg.staticSharedLibVersion) {
8800 previousLibVersion = Math.max(previousLibVersion, libVersion);
8803 if (previousLibVersion >= 0) {
8804 return versionedLib.get(previousLibVersion);
8809 public void shutdown() {
8810 mPackageUsage.writeNow(mPackages);
8811 mCompilerStats.writeNow();
8815 public void dumpProfiles(String packageName) {
8816 PackageParser.Package pkg;
8817 synchronized (mPackages) {
8818 pkg = mPackages.get(packageName);
8820 throw new IllegalArgumentException("Unknown package: " + packageName);
8823 /* Only the shell, root, or the app user should be able to dump profiles. */
8824 int callingUid = Binder.getCallingUid();
8825 if (callingUid != Process.SHELL_UID &&
8826 callingUid != Process.ROOT_UID &&
8827 callingUid != pkg.applicationInfo.uid) {
8828 throw new SecurityException("dumpProfiles");
8831 synchronized (mInstallLock) {
8832 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
8833 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
8835 List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
8836 String codePaths = TextUtils.join(";", allCodePaths);
8837 mInstaller.dumpProfiles(sharedGid, packageName, codePaths);
8838 } catch (InstallerException e) {
8839 Slog.w(TAG, "Failed to dump profiles", e);
8841 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8846 public void forceDexOpt(String packageName) {
8847 enforceSystemOrRoot("forceDexOpt");
8849 PackageParser.Package pkg;
8850 synchronized (mPackages) {
8851 pkg = mPackages.get(packageName);
8853 throw new IllegalArgumentException("Unknown package: " + packageName);
8857 synchronized (mInstallLock) {
8858 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
8860 // Whoever is calling forceDexOpt wants a fully compiled package.
8861 // Don't use profiles since that may cause compilation to be skipped.
8862 final int res = performDexOptInternalWithDependenciesLI(pkg,
8863 false /* checkProfiles */, getCompilerFilterForReason(REASON_FORCED_DEXOPT),
8866 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8867 if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
8868 throw new IllegalStateException("Failed to dexopt: " + res);
8873 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
8874 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8875 Slog.w(TAG, "Unable to update from " + oldPkg.name
8876 + " to " + newPkg.packageName
8877 + ": old package not in system partition");
8879 } else if (mPackages.get(oldPkg.name) != null) {
8880 Slog.w(TAG, "Unable to update from " + oldPkg.name
8881 + " to " + newPkg.packageName
8882 + ": old package still exists");
8888 void removeCodePathLI(File codePath) {
8889 if (codePath.isDirectory()) {
8891 mInstaller.rmPackageDir(codePath.getAbsolutePath());
8892 } catch (InstallerException e) {
8893 Slog.w(TAG, "Failed to remove code path", e);
8900 private int[] resolveUserIds(int userId) {
8901 return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
8904 private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
8906 Slog.wtf(TAG, "Package was null!", new Throwable());
8909 clearAppDataLeafLIF(pkg, userId, flags);
8910 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8911 for (int i = 0; i < childCount; i++) {
8912 clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
8916 private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
8917 final PackageSetting ps;
8918 synchronized (mPackages) {
8919 ps = mSettings.mPackages.get(pkg.packageName);
8921 for (int realUserId : resolveUserIds(userId)) {
8922 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
8924 mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
8926 } catch (InstallerException e) {
8927 Slog.w(TAG, String.valueOf(e));
8932 private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
8934 Slog.wtf(TAG, "Package was null!", new Throwable());
8937 destroyAppDataLeafLIF(pkg, userId, flags);
8938 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8939 for (int i = 0; i < childCount; i++) {
8940 destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
8944 private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
8945 final PackageSetting ps;
8946 synchronized (mPackages) {
8947 ps = mSettings.mPackages.get(pkg.packageName);
8949 for (int realUserId : resolveUserIds(userId)) {
8950 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
8952 mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
8954 } catch (InstallerException e) {
8955 Slog.w(TAG, String.valueOf(e));
8957 mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
8961 private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
8963 Slog.wtf(TAG, "Package was null!", new Throwable());
8966 destroyAppProfilesLeafLIF(pkg);
8967 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8968 for (int i = 0; i < childCount; i++) {
8969 destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
8973 private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
8975 mInstaller.destroyAppProfiles(pkg.packageName);
8976 } catch (InstallerException e) {
8977 Slog.w(TAG, String.valueOf(e));
8981 private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
8983 Slog.wtf(TAG, "Package was null!", new Throwable());
8986 clearAppProfilesLeafLIF(pkg);
8987 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8988 for (int i = 0; i < childCount; i++) {
8989 clearAppProfilesLeafLIF(pkg.childPackages.get(i));
8993 private void clearAppProfilesLeafLIF(PackageParser.Package pkg) {
8995 mInstaller.clearAppProfiles(pkg.packageName);
8996 } catch (InstallerException e) {
8997 Slog.w(TAG, String.valueOf(e));
9001 private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
9002 long lastUpdateTime) {
9003 // Set parent install/update time
9004 PackageSetting ps = (PackageSetting) pkg.mExtras;
9006 ps.firstInstallTime = firstInstallTime;
9007 ps.lastUpdateTime = lastUpdateTime;
9009 // Set children install/update time
9010 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9011 for (int i = 0; i < childCount; i++) {
9012 PackageParser.Package childPkg = pkg.childPackages.get(i);
9013 ps = (PackageSetting) childPkg.mExtras;
9015 ps.firstInstallTime = firstInstallTime;
9016 ps.lastUpdateTime = lastUpdateTime;
9021 private void addSharedLibraryLPr(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
9022 PackageParser.Package changingLib) {
9023 if (file.path != null) {
9024 usesLibraryFiles.add(file.path);
9027 PackageParser.Package p = mPackages.get(file.apk);
9028 if (changingLib != null && changingLib.packageName.equals(file.apk)) {
9029 // If we are doing this while in the middle of updating a library apk,
9030 // then we need to make sure to use that new apk for determining the
9031 // dependencies here. (We haven't yet finished committing the new apk
9032 // to the package manager state.)
9033 if (p == null || p.packageName.equals(changingLib.packageName)) {
9038 usesLibraryFiles.addAll(p.getAllCodePaths());
9042 private void updateSharedLibrariesLPr(PackageParser.Package pkg,
9043 PackageParser.Package changingLib) throws PackageManagerException {
9047 ArraySet<String> usesLibraryFiles = null;
9048 if (pkg.usesLibraries != null) {
9049 usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries,
9050 null, null, pkg.packageName, changingLib, true, null);
9052 if (pkg.usesStaticLibraries != null) {
9053 usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries,
9054 pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests,
9055 pkg.packageName, changingLib, true, usesLibraryFiles);
9057 if (pkg.usesOptionalLibraries != null) {
9058 usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries,
9059 null, null, pkg.packageName, changingLib, false, usesLibraryFiles);
9061 if (!ArrayUtils.isEmpty(usesLibraryFiles)) {
9062 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
9064 pkg.usesLibraryFiles = null;
9068 private ArraySet<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
9069 @Nullable int[] requiredVersions, @Nullable String[] requiredCertDigests,
9070 @NonNull String packageName, @Nullable PackageParser.Package changingLib,
9071 boolean required, @Nullable ArraySet<String> outUsedLibraries)
9072 throws PackageManagerException {
9073 final int libCount = requestedLibraries.size();
9074 for (int i = 0; i < libCount; i++) {
9075 final String libName = requestedLibraries.get(i);
9076 final int libVersion = requiredVersions != null ? requiredVersions[i]
9077 : SharedLibraryInfo.VERSION_UNDEFINED;
9078 final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion);
9079 if (libEntry == null) {
9081 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9082 "Package " + packageName + " requires unavailable shared library "
9083 + libName + "; failing!");
9085 Slog.w(TAG, "Package " + packageName
9086 + " desires unavailable shared library "
9087 + libName + "; ignoring!");
9090 if (requiredVersions != null && requiredCertDigests != null) {
9091 if (libEntry.info.getVersion() != requiredVersions[i]) {
9092 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9093 "Package " + packageName + " requires unavailable static shared"
9094 + " library " + libName + " version "
9095 + libEntry.info.getVersion() + "; failing!");
9098 PackageParser.Package libPkg = mPackages.get(libEntry.apk);
9099 if (libPkg == null) {
9100 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9101 "Package " + packageName + " requires unavailable static shared"
9102 + " library; failing!");
9105 String expectedCertDigest = requiredCertDigests[i];
9106 String libCertDigest = PackageUtils.computeCertSha256Digest(
9107 libPkg.mSignatures[0]);
9108 if (!libCertDigest.equalsIgnoreCase(expectedCertDigest)) {
9109 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9110 "Package " + packageName + " requires differently signed" +
9111 " static shared library; failing!");
9115 if (outUsedLibraries == null) {
9116 outUsedLibraries = new ArraySet<>();
9118 addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib);
9121 return outUsedLibraries;
9124 private static boolean hasString(List<String> list, List<String> which) {
9128 for (int i=list.size()-1; i>=0; i--) {
9129 for (int j=which.size()-1; j>=0; j--) {
9130 if (which.get(j).equals(list.get(i))) {
9138 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
9139 PackageParser.Package changingPkg) {
9140 ArrayList<PackageParser.Package> res = null;
9141 for (PackageParser.Package pkg : mPackages.values()) {
9142 if (changingPkg != null
9143 && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
9144 && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
9145 && !ArrayUtils.contains(pkg.usesStaticLibraries,
9146 changingPkg.staticSharedLibName)) {
9150 res = new ArrayList<>();
9154 updateSharedLibrariesLPr(pkg, changingPkg);
9155 } catch (PackageManagerException e) {
9156 // If a system app update or an app and a required lib missing we
9157 // delete the package and for updated system apps keep the data as
9158 // it is better for the user to reinstall than to be in an limbo
9159 // state. Also libs disappearing under an app should never happen
9161 if (!pkg.isSystemApp() || pkg.isUpdatedSystemApp()) {
9162 final int flags = pkg.isUpdatedSystemApp()
9163 ? PackageManager.DELETE_KEEP_DATA : 0;
9164 deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
9165 flags , null, true, null);
9167 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
9174 * Derive the value of the {@code cpuAbiOverride} based on the provided
9175 * value and an optional stored value from the package settings.
9177 private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
9178 String cpuAbiOverride = null;
9180 if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
9181 cpuAbiOverride = null;
9182 } else if (abiOverride != null) {
9183 cpuAbiOverride = abiOverride;
9184 } else if (settings != null) {
9185 cpuAbiOverride = settings.cpuAbiOverrideString;
9188 return cpuAbiOverride;
9191 private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
9192 final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
9193 throws PackageManagerException {
9194 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
9195 // If the package has children and this is the first dive in the function
9196 // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
9197 // whether all packages (parent and children) would be successfully scanned
9198 // before the actual scan since scanning mutates internal state and we want
9199 // to atomically install the package and its children.
9200 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9201 if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
9202 scanFlags |= SCAN_CHECK_ONLY;
9205 scanFlags &= ~SCAN_CHECK_ONLY;
9208 final PackageParser.Package scannedPkg;
9211 scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user);
9212 // Scan the children
9213 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9214 for (int i = 0; i < childCount; i++) {
9215 PackageParser.Package childPkg = pkg.childPackages.get(i);
9216 scanPackageLI(childPkg, policyFlags,
9217 scanFlags, currentTime, user);
9220 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9223 if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9224 return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user);
9230 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags,
9231 int scanFlags, long currentTime, @Nullable UserHandle user)
9232 throws PackageManagerException {
9233 boolean success = false;
9235 final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags,
9240 if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
9241 // DELETE_DATA_ON_FAILURES is only used by frozen paths
9242 destroyAppDataLIF(pkg, UserHandle.USER_ALL,
9243 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
9244 destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
9250 * Returns {@code true} if the given file contains code. Otherwise {@code false}.
9252 private static boolean apkHasCode(String fileName) {
9253 StrictJarFile jarFile = null;
9255 jarFile = new StrictJarFile(fileName,
9256 false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
9257 return jarFile.findEntry("classes.dex") != null;
9258 } catch (IOException ignore) {
9261 if (jarFile != null) {
9264 } catch (IOException ignore) {}
9270 * Enforces code policy for the package. This ensures that if an APK has
9271 * declared hasCode="true" in its manifest that the APK actually contains
9274 * @throws PackageManagerException If bytecode could not be found when it should exist
9276 private static void assertCodePolicy(PackageParser.Package pkg)
9277 throws PackageManagerException {
9278 final boolean shouldHaveCode =
9279 (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
9280 if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
9281 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
9282 "Package " + pkg.baseCodePath + " code is missing");
9285 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
9286 for (int i = 0; i < pkg.splitCodePaths.length; i++) {
9287 final boolean splitShouldHaveCode =
9288 (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
9289 if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
9290 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
9291 "Package " + pkg.splitCodePaths[i] + " code is missing");
9297 private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,
9298 final int policyFlags, final int scanFlags, long currentTime, @Nullable UserHandle user)
9299 throws PackageManagerException {
9300 if (DEBUG_PACKAGE_SCANNING) {
9301 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
9302 Log.d(TAG, "Scanning package " + pkg.packageName);
9305 applyPolicy(pkg, policyFlags);
9307 assertPackageIsValid(pkg, policyFlags, scanFlags);
9309 // Initialize package source and resource directories
9310 final File scanFile = new File(pkg.codePath);
9311 final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
9312 final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
9314 SharedUserSetting suid = null;
9315 PackageSetting pkgSetting = null;
9317 // Getting the package setting may have a side-effect, so if we
9318 // are only checking if scan would succeed, stash a copy of the
9319 // old setting to restore at the end.
9320 PackageSetting nonMutatedPs = null;
9322 // We keep references to the derived CPU Abis from settings in oder to reuse
9323 // them in the case where we're not upgrading or booting for the first time.
9324 String primaryCpuAbiFromSettings = null;
9325 String secondaryCpuAbiFromSettings = null;
9328 synchronized (mPackages) {
9329 if (pkg.mSharedUserId != null) {
9330 // SIDE EFFECTS; may potentially allocate a new shared user
9331 suid = mSettings.getSharedUserLPw(
9332 pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
9333 if (DEBUG_PACKAGE_SCANNING) {
9334 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
9335 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
9336 + "): packages=" + suid.packages);
9340 // Check if we are renaming from an original package name.
9341 PackageSetting origPackage = null;
9342 String realName = null;
9343 if (pkg.mOriginalPackages != null) {
9344 // This package may need to be renamed to a previously
9345 // installed name. Let's check on that...
9346 final String renamed = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
9347 if (pkg.mOriginalPackages.contains(renamed)) {
9348 // This package had originally been installed as the
9349 // original name, and we have already taken care of
9350 // transitioning to the new one. Just update the new
9351 // one to continue using the old name.
9352 realName = pkg.mRealPackage;
9353 if (!pkg.packageName.equals(renamed)) {
9354 // Callers into this function may have already taken
9355 // care of renaming the package; only do it here if
9356 // it is not already done.
9357 pkg.setPackageName(renamed);
9360 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
9361 if ((origPackage = mSettings.getPackageLPr(
9362 pkg.mOriginalPackages.get(i))) != null) {
9363 // We do have the package already installed under its
9364 // original name... should we use it?
9365 if (!verifyPackageUpdateLPr(origPackage, pkg)) {
9366 // New package is not compatible with original.
9369 } else if (origPackage.sharedUser != null) {
9370 // Make sure uid is compatible between packages.
9371 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
9372 Slog.w(TAG, "Unable to migrate data from " + origPackage.name
9373 + " to " + pkg.packageName + ": old uid "
9374 + origPackage.sharedUser.name
9375 + " differs from " + pkg.mSharedUserId);
9379 // TODO: Add case when shared user id is added [b/28144775]
9381 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
9382 + pkg.packageName + " to old name " + origPackage.name);
9390 if (mTransferedPackages.contains(pkg.packageName)) {
9391 Slog.w(TAG, "Package " + pkg.packageName
9392 + " was transferred to another, but its .apk remains");
9395 // See comments in nonMutatedPs declaration
9396 if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9397 PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
9398 if (foundPs != null) {
9399 nonMutatedPs = new PackageSetting(foundPs);
9403 if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) == 0) {
9404 PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
9405 if (foundPs != null) {
9406 primaryCpuAbiFromSettings = foundPs.primaryCpuAbiString;
9407 secondaryCpuAbiFromSettings = foundPs.secondaryCpuAbiString;
9411 pkgSetting = mSettings.getPackageLPr(pkg.packageName);
9412 if (pkgSetting != null && pkgSetting.sharedUser != suid) {
9413 PackageManagerService.reportSettingsProblem(Log.WARN,
9414 "Package " + pkg.packageName + " shared user changed from "
9415 + (pkgSetting.sharedUser != null
9416 ? pkgSetting.sharedUser.name : "<nothing>")
9418 + (suid != null ? suid.name : "<nothing>")
9419 + "; replacing with new");
9422 final PackageSetting oldPkgSetting =
9423 pkgSetting == null ? null : new PackageSetting(pkgSetting);
9424 final PackageSetting disabledPkgSetting =
9425 mSettings.getDisabledSystemPkgLPr(pkg.packageName);
9427 String[] usesStaticLibraries = null;
9428 if (pkg.usesStaticLibraries != null) {
9429 usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
9430 pkg.usesStaticLibraries.toArray(usesStaticLibraries);
9433 if (pkgSetting == null) {
9434 final String parentPackageName = (pkg.parentPackage != null)
9435 ? pkg.parentPackage.packageName : null;
9436 final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
9437 // REMOVE SharedUserSetting from method; update in a separate call
9438 pkgSetting = Settings.createNewSetting(pkg.packageName, origPackage,
9439 disabledPkgSetting, realName, suid, destCodeFile, destResourceFile,
9440 pkg.applicationInfo.nativeLibraryRootDir, pkg.applicationInfo.primaryCpuAbi,
9441 pkg.applicationInfo.secondaryCpuAbi, pkg.mVersionCode,
9442 pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, user,
9443 true /*allowInstall*/, instantApp, parentPackageName,
9444 pkg.getChildPackageNames(), UserManagerService.getInstance(),
9445 usesStaticLibraries, pkg.usesStaticLibrariesVersions);
9446 // SIDE EFFECTS; updates system state; move elsewhere
9447 if (origPackage != null) {
9448 mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name);
9450 mSettings.addUserToSettingLPw(pkgSetting);
9452 // REMOVE SharedUserSetting from method; update in a separate call.
9454 // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
9455 // secondaryCpuAbi are not known at this point so we always update them
9456 // to null here, only to reset them at a later point.
9457 Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, suid, destCodeFile,
9458 pkg.applicationInfo.nativeLibraryDir, pkg.applicationInfo.primaryCpuAbi,
9459 pkg.applicationInfo.secondaryCpuAbi, pkg.applicationInfo.flags,
9460 pkg.applicationInfo.privateFlags, pkg.getChildPackageNames(),
9461 UserManagerService.getInstance(), usesStaticLibraries,
9462 pkg.usesStaticLibrariesVersions);
9464 // SIDE EFFECTS; persists system state to files on disk; move elsewhere
9465 mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
9467 // SIDE EFFECTS; modifies system state; move elsewhere
9468 if (pkgSetting.origPackage != null) {
9469 // If we are first transitioning from an original package,
9470 // fix up the new package's name now. We need to do this after
9471 // looking up the package under its new name, so getPackageLP
9472 // can take care of fiddling things correctly.
9473 pkg.setPackageName(origPackage.name);
9475 // File a report about this.
9476 String msg = "New package " + pkgSetting.realName
9477 + " renamed to replace old package " + pkgSetting.name;
9478 reportSettingsProblem(Log.WARN, msg);
9480 // Make a note of it.
9481 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9482 mTransferedPackages.add(origPackage.name);
9485 // No longer need to retain this.
9486 pkgSetting.origPackage = null;
9489 // SIDE EFFECTS; modifies system state; move elsewhere
9490 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) {
9491 // Make a note of it.
9492 mTransferedPackages.add(pkg.packageName);
9495 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
9496 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
9499 if ((scanFlags & SCAN_BOOTING) == 0
9500 && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9501 // Check all shared libraries and map to their actual file path.
9502 // We only do this here for apps not on a system dir, because those
9503 // are the only ones that can fail an install due to this. We
9504 // will take care of the system apps by updating all of their
9505 // library paths after the scan is done. Also during the initial
9506 // scan don't update any libs as we do this wholesale after all
9507 // apps are scanned to avoid dependency based scanning.
9508 updateSharedLibrariesLPr(pkg, null);
9511 if (mFoundPolicyFile) {
9512 SELinuxMMAC.assignSeInfoValue(pkg);
9514 pkg.applicationInfo.uid = pkgSetting.appId;
9515 pkg.mExtras = pkgSetting;
9518 // Static shared libs have same package with different versions where
9519 // we internally use a synthetic package name to allow multiple versions
9520 // of the same package, therefore we need to compare signatures against
9521 // the package setting for the latest library version.
9522 PackageSetting signatureCheckPs = pkgSetting;
9523 if (pkg.applicationInfo.isStaticSharedLibrary()) {
9524 SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
9525 if (libraryEntry != null) {
9526 signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
9530 if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
9531 if (checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
9532 // We just determined the app is signed correctly, so bring
9533 // over the latest parsed certs.
9534 pkgSetting.signatures.mSignatures = pkg.mSignatures;
9536 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9537 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
9538 "Package " + pkg.packageName + " upgrade keys do not match the "
9539 + "previously installed version");
9541 pkgSetting.signatures.mSignatures = pkg.mSignatures;
9542 String msg = "System package " + pkg.packageName
9543 + " signature changed; retaining data.";
9544 reportSettingsProblem(Log.WARN, msg);
9549 // SIDE EFFECTS; compareSignaturesCompat() changes KeysetManagerService
9550 verifySignaturesLP(signatureCheckPs, pkg);
9551 // We just determined the app is signed correctly, so bring
9552 // over the latest parsed certs.
9553 pkgSetting.signatures.mSignatures = pkg.mSignatures;
9554 } catch (PackageManagerException e) {
9555 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9558 // The signature has changed, but this package is in the system
9559 // image... let's recover!
9560 pkgSetting.signatures.mSignatures = pkg.mSignatures;
9561 // However... if this package is part of a shared user, but it
9562 // doesn't match the signature of the shared user, let's fail.
9563 // What this means is that you can't change the signatures
9564 // associated with an overall shared user, which doesn't seem all
9565 // that unreasonable.
9566 if (signatureCheckPs.sharedUser != null) {
9567 if (compareSignatures(signatureCheckPs.sharedUser.signatures.mSignatures,
9568 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
9569 throw new PackageManagerException(
9570 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
9571 "Signature mismatch for shared user: "
9572 + pkgSetting.sharedUser);
9575 // File a report about this.
9576 String msg = "System package " + pkg.packageName
9577 + " signature changed; retaining data.";
9578 reportSettingsProblem(Log.WARN, msg);
9582 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
9583 // This package wants to adopt ownership of permissions from
9585 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
9586 final String origName = pkg.mAdoptPermissions.get(i);
9587 final PackageSetting orig = mSettings.getPackageLPr(origName);
9589 if (verifyPackageUpdateLPr(orig, pkg)) {
9590 Slog.i(TAG, "Adopting permissions from " + origName + " to "
9592 // SIDE EFFECTS; updates permissions system state; move elsewhere
9593 mSettings.transferPermissionsLPw(origName, pkg.packageName);
9600 pkg.applicationInfo.processName = fixProcessName(
9601 pkg.applicationInfo.packageName,
9602 pkg.applicationInfo.processName);
9604 if (pkg != mPlatformPackage) {
9605 // Get all of our default paths setup
9606 pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
9609 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
9611 if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
9612 if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) {
9613 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
9615 pkg, scanFile, cpuAbiOverride, true /*extractLibs*/, mAppLib32InstallDir);
9616 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9618 // Some system apps still use directory structure for native libraries
9619 // in which case we might end up not detecting abi solely based on apk
9620 // structure. Try to detect abi based on directory structure.
9621 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
9622 pkg.applicationInfo.primaryCpuAbi == null) {
9623 setBundledAppAbisAndRoots(pkg, pkgSetting);
9624 setNativeLibraryPaths(pkg, mAppLib32InstallDir);
9627 // This is not a first boot or an upgrade, don't bother deriving the
9628 // ABI during the scan. Instead, trust the value that was stored in the
9630 pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
9631 pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
9633 setNativeLibraryPaths(pkg, mAppLib32InstallDir);
9635 if (DEBUG_ABI_SELECTION) {
9636 Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
9637 pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
9638 pkg.applicationInfo.secondaryCpuAbi);
9642 if ((scanFlags & SCAN_MOVE) != 0) {
9643 // We haven't run dex-opt for this move (since we've moved the compiled output too)
9644 // but we already have this packages package info in the PackageSetting. We just
9645 // use that and derive the native library path based on the new codepath.
9646 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
9647 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
9650 // Set native library paths again. For moves, the path will be updated based on the
9651 // ABIs we've determined above. For non-moves, the path will be updated based on the
9652 // ABIs we determined during compilation, but the path will depend on the final
9653 // package path (after the rename away from the stage path).
9654 setNativeLibraryPaths(pkg, mAppLib32InstallDir);
9657 // This is a special case for the "system" package, where the ABI is
9658 // dictated by the zygote configuration (and init.rc). We should keep track
9659 // of this ABI so that we can deal with "normal" applications that run under
9660 // the same UID correctly.
9661 if (mPlatformPackage == pkg) {
9662 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
9663 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
9666 // If there's a mismatch between the abi-override in the package setting
9667 // and the abiOverride specified for the install. Warn about this because we
9668 // would've already compiled the app without taking the package setting into
9670 if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
9671 if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
9672 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
9673 " for package " + pkg.packageName);
9677 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
9678 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
9679 pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
9681 // Copy the derived override back to the parsed package, so that we can
9682 // update the package settings accordingly.
9683 pkg.cpuAbiOverride = cpuAbiOverride;
9685 if (DEBUG_ABI_SELECTION) {
9686 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
9687 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
9688 + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
9691 // Push the derived path down into PackageSettings so we know what to
9692 // clean up at uninstall time.
9693 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
9695 if (DEBUG_ABI_SELECTION) {
9696 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
9697 " primary=" + pkg.applicationInfo.primaryCpuAbi +
9698 " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
9701 // SIDE EFFECTS; removes DEX files from disk; move elsewhere
9702 if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
9703 // We don't do this here during boot because we can do it all
9704 // at once after scanning all existing packages.
9706 // We also do this *before* we perform dexopt on this package, so that
9707 // we can avoid redundant dexopts, and also to make sure we've got the
9708 // code and package path correct.
9709 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
9712 if (mFactoryTest && pkg.requestedPermissions.contains(
9713 android.Manifest.permission.FACTORY_TEST)) {
9714 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
9717 if (isSystemApp(pkg)) {
9718 pkgSetting.isOrphaned = true;
9721 // Take care of first install / last update times.
9722 final long scanFileTime = getLastModifiedTime(pkg, scanFile);
9723 if (currentTime != 0) {
9724 if (pkgSetting.firstInstallTime == 0) {
9725 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
9726 } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
9727 pkgSetting.lastUpdateTime = currentTime;
9729 } else if (pkgSetting.firstInstallTime == 0) {
9730 // We need *something*. Take time time stamp of the file.
9731 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
9732 } else if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
9733 if (scanFileTime != pkgSetting.timeStamp) {
9734 // A package on the system image has changed; consider this
9736 pkgSetting.lastUpdateTime = scanFileTime;
9739 pkgSetting.setTimeStamp(scanFileTime);
9741 if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9742 if (nonMutatedPs != null) {
9743 synchronized (mPackages) {
9744 mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs);
9748 final int userId = user == null ? 0 : user.getIdentifier();
9749 // Modify state for the given package setting
9750 commitPackageSettings(pkg, pkgSetting, user, scanFlags,
9751 (policyFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
9752 if (pkgSetting.getInstantApp(userId)) {
9753 mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
9760 * Applies policy to the parsed package based upon the given policy flags.
9761 * Ensures the package is in a good state.
9763 * Implementation detail: This method must NOT have any side effect. It would
9764 * ideally be static, but, it requires locks to read system state.
9766 private void applyPolicy(PackageParser.Package pkg, int policyFlags) {
9767 if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
9768 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
9769 if (pkg.applicationInfo.isDirectBootAware()) {
9770 // we're direct boot aware; set for all components
9771 for (PackageParser.Service s : pkg.services) {
9772 s.info.encryptionAware = s.info.directBootAware = true;
9774 for (PackageParser.Provider p : pkg.providers) {
9775 p.info.encryptionAware = p.info.directBootAware = true;
9777 for (PackageParser.Activity a : pkg.activities) {
9778 a.info.encryptionAware = a.info.directBootAware = true;
9780 for (PackageParser.Activity r : pkg.receivers) {
9781 r.info.encryptionAware = r.info.directBootAware = true;
9785 // Only allow system apps to be flagged as core apps.
9786 pkg.coreApp = false;
9787 // clear flags not applicable to regular apps
9788 pkg.applicationInfo.privateFlags &=
9789 ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
9790 pkg.applicationInfo.privateFlags &=
9791 ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
9793 pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0;
9795 if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
9796 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
9799 if (!isSystemApp(pkg)) {
9800 // Only system apps can use these features.
9801 pkg.mOriginalPackages = null;
9802 pkg.mRealPackage = null;
9803 pkg.mAdoptPermissions = null;
9808 * Asserts the parsed package is valid according to the given policy. If the
9809 * package is invalid, for whatever reason, throws {@link PackageManagerException}.
9811 * Implementation detail: This method must NOT have any side effects. It would
9812 * ideally be static, but, it requires locks to read system state.
9814 * @throws PackageManagerException If the package fails any of the validation checks
9816 private void assertPackageIsValid(PackageParser.Package pkg, int policyFlags, int scanFlags)
9817 throws PackageManagerException {
9818 if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
9819 assertCodePolicy(pkg);
9822 if (pkg.applicationInfo.getCodePath() == null ||
9823 pkg.applicationInfo.getResourcePath() == null) {
9824 // Bail out. The resource and code paths haven't been set.
9825 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
9826 "Code and resource paths haven't been set correctly");
9829 // Make sure we're not adding any bogus keyset info
9830 KeySetManagerService ksms = mSettings.mKeySetManagerService;
9831 ksms.assertScannedPackageValid(pkg);
9833 synchronized (mPackages) {
9834 // The special "android" package can only be defined once
9835 if (pkg.packageName.equals("android")) {
9836 if (mAndroidApplication != null) {
9837 Slog.w(TAG, "*************************************************");
9838 Slog.w(TAG, "Core android package being redefined. Skipping.");
9839 Slog.w(TAG, " codePath=" + pkg.codePath);
9840 Slog.w(TAG, "*************************************************");
9841 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
9842 "Core android package being redefined. Skipping.");
9846 // A package name must be unique; don't allow duplicates
9847 if (mPackages.containsKey(pkg.packageName)) {
9848 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
9849 "Application package " + pkg.packageName
9850 + " already installed. Skipping duplicate.");
9853 if (pkg.applicationInfo.isStaticSharedLibrary()) {
9854 // Static libs have a synthetic package name containing the version
9855 // but we still want the base name to be unique.
9856 if (mPackages.containsKey(pkg.manifestPackageName)) {
9857 throw new PackageManagerException(
9858 "Duplicate static shared lib provider package");
9861 // Static shared libraries should have at least O target SDK
9862 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
9863 throw new PackageManagerException(
9864 "Packages declaring static-shared libs must target O SDK or higher");
9867 // Package declaring static a shared lib cannot be instant apps
9868 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
9869 throw new PackageManagerException(
9870 "Packages declaring static-shared libs cannot be instant apps");
9873 // Package declaring static a shared lib cannot be renamed since the package
9874 // name is synthetic and apps can't code around package manager internals.
9875 if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) {
9876 throw new PackageManagerException(
9877 "Packages declaring static-shared libs cannot be renamed");
9880 // Package declaring static a shared lib cannot declare child packages
9881 if (!ArrayUtils.isEmpty(pkg.childPackages)) {
9882 throw new PackageManagerException(
9883 "Packages declaring static-shared libs cannot have child packages");
9886 // Package declaring static a shared lib cannot declare dynamic libs
9887 if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
9888 throw new PackageManagerException(
9889 "Packages declaring static-shared libs cannot declare dynamic libs");
9892 // Package declaring static a shared lib cannot declare shared users
9893 if (pkg.mSharedUserId != null) {
9894 throw new PackageManagerException(
9895 "Packages declaring static-shared libs cannot declare shared users");
9898 // Static shared libs cannot declare activities
9899 if (!pkg.activities.isEmpty()) {
9900 throw new PackageManagerException(
9901 "Static shared libs cannot declare activities");
9904 // Static shared libs cannot declare services
9905 if (!pkg.services.isEmpty()) {
9906 throw new PackageManagerException(
9907 "Static shared libs cannot declare services");
9910 // Static shared libs cannot declare providers
9911 if (!pkg.providers.isEmpty()) {
9912 throw new PackageManagerException(
9913 "Static shared libs cannot declare content providers");
9916 // Static shared libs cannot declare receivers
9917 if (!pkg.receivers.isEmpty()) {
9918 throw new PackageManagerException(
9919 "Static shared libs cannot declare broadcast receivers");
9922 // Static shared libs cannot declare permission groups
9923 if (!pkg.permissionGroups.isEmpty()) {
9924 throw new PackageManagerException(
9925 "Static shared libs cannot declare permission groups");
9928 // Static shared libs cannot declare permissions
9929 if (!pkg.permissions.isEmpty()) {
9930 throw new PackageManagerException(
9931 "Static shared libs cannot declare permissions");
9934 // Static shared libs cannot declare protected broadcasts
9935 if (pkg.protectedBroadcasts != null) {
9936 throw new PackageManagerException(
9937 "Static shared libs cannot declare protected broadcasts");
9940 // Static shared libs cannot be overlay targets
9941 if (pkg.mOverlayTarget != null) {
9942 throw new PackageManagerException(
9943 "Static shared libs cannot be overlay targets");
9946 // The version codes must be ordered as lib versions
9947 int minVersionCode = Integer.MIN_VALUE;
9948 int maxVersionCode = Integer.MAX_VALUE;
9950 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
9951 pkg.staticSharedLibName);
9952 if (versionedLib != null) {
9953 final int versionCount = versionedLib.size();
9954 for (int i = 0; i < versionCount; i++) {
9955 SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
9956 // TODO: We will change version code to long, so in the new API it is long
9957 final int libVersionCode = (int) libInfo.getDeclaringPackage()
9959 if (libInfo.getVersion() < pkg.staticSharedLibVersion) {
9960 minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
9961 } else if (libInfo.getVersion() > pkg.staticSharedLibVersion) {
9962 maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
9964 minVersionCode = maxVersionCode = libVersionCode;
9969 if (pkg.mVersionCode < minVersionCode || pkg.mVersionCode > maxVersionCode) {
9970 throw new PackageManagerException("Static shared"
9971 + " lib version codes must be ordered as lib versions");
9975 // Only privileged apps and updated privileged apps can add child packages.
9976 if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
9977 if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) {
9978 throw new PackageManagerException("Only privileged apps can add child "
9979 + "packages. Ignoring package " + pkg.packageName);
9981 final int childCount = pkg.childPackages.size();
9982 for (int i = 0; i < childCount; i++) {
9983 PackageParser.Package childPkg = pkg.childPackages.get(i);
9984 if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
9985 childPkg.packageName)) {
9986 throw new PackageManagerException("Can't override child of "
9987 + "another disabled app. Ignoring package " + pkg.packageName);
9992 // If we're only installing presumed-existing packages, require that the
9993 // scanned APK is both already known and at the path previously established
9994 // for it. Previously unknown packages we pick up normally, but if we have an
9995 // a priori expectation about this package's install presence, enforce it.
9996 // With a singular exception for new system packages. When an OTA contains
9997 // a new system package, we allow the codepath to change from a system location
9998 // to the user-installed location. If we don't allow this change, any newer,
9999 // user-installed version of the application will be ignored.
10000 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
10001 if (mExpectingBetter.containsKey(pkg.packageName)) {
10002 logCriticalInfo(Log.WARN,
10003 "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
10005 PackageSetting known = mSettings.getPackageLPr(pkg.packageName);
10006 if (known != null) {
10007 if (DEBUG_PACKAGE_SCANNING) {
10008 Log.d(TAG, "Examining " + pkg.codePath
10009 + " and requiring known paths " + known.codePathString
10010 + " & " + known.resourcePathString);
10012 if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
10013 || !pkg.applicationInfo.getResourcePath().equals(
10014 known.resourcePathString)) {
10015 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
10016 "Application package " + pkg.packageName
10017 + " found at " + pkg.applicationInfo.getCodePath()
10018 + " but expected at " + known.codePathString
10025 // Verify that this new package doesn't have any content providers
10026 // that conflict with existing packages. Only do this if the
10027 // package isn't already installed, since we don't want to break
10028 // things that are installed.
10029 if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
10030 final int N = pkg.providers.size();
10032 for (i=0; i<N; i++) {
10033 PackageParser.Provider p = pkg.providers.get(i);
10034 if (p.info.authority != null) {
10035 String names[] = p.info.authority.split(";");
10036 for (int j = 0; j < names.length; j++) {
10037 if (mProvidersByAuthority.containsKey(names[j])) {
10038 PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
10039 final String otherPackageName =
10040 ((other != null && other.getComponentName() != null) ?
10041 other.getComponentName().getPackageName() : "?");
10042 throw new PackageManagerException(
10043 INSTALL_FAILED_CONFLICTING_PROVIDER,
10044 "Can't install because provider name " + names[j]
10045 + " (in package " + pkg.applicationInfo.packageName
10046 + ") is already used by " + otherPackageName);
10055 private boolean addSharedLibraryLPw(String path, String apk, String name, int version,
10056 int type, String declaringPackageName, int declaringVersionCode) {
10057 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10058 if (versionedLib == null) {
10059 versionedLib = new SparseArray<>();
10060 mSharedLibraries.put(name, versionedLib);
10061 if (type == SharedLibraryInfo.TYPE_STATIC) {
10062 mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
10064 } else if (versionedLib.indexOfKey(version) >= 0) {
10067 SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name,
10068 version, type, declaringPackageName, declaringVersionCode);
10069 versionedLib.put(version, libEntry);
10073 private boolean removeSharedLibraryLPw(String name, int version) {
10074 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10075 if (versionedLib == null) {
10078 final int libIdx = versionedLib.indexOfKey(version);
10082 SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx);
10083 versionedLib.remove(version);
10084 if (versionedLib.size() <= 0) {
10085 mSharedLibraries.remove(name);
10086 if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) {
10087 mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage()
10088 .getPackageName());
10095 * Adds a scanned package to the system. When this method is finished, the package will
10096 * be available for query, resolution, etc...
10098 private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting,
10099 UserHandle user, int scanFlags, boolean chatty) throws PackageManagerException {
10100 final String pkgName = pkg.packageName;
10101 if (mCustomResolverComponentName != null &&
10102 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
10103 setUpCustomResolverActivity(pkg);
10106 if (pkg.packageName.equals("android")) {
10107 synchronized (mPackages) {
10108 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10109 // Set up information for our fall-back user intent resolution activity.
10110 mPlatformPackage = pkg;
10111 pkg.mVersionCode = mSdkVersion;
10112 mAndroidApplication = pkg.applicationInfo;
10113 if (!mResolverReplaced) {
10114 mResolveActivity.applicationInfo = mAndroidApplication;
10115 mResolveActivity.name = ResolverActivity.class.getName();
10116 mResolveActivity.packageName = mAndroidApplication.packageName;
10117 mResolveActivity.processName = "system:ui";
10118 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
10119 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
10120 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
10121 mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
10122 mResolveActivity.exported = true;
10123 mResolveActivity.enabled = true;
10124 mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
10125 mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
10126 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
10127 | ActivityInfo.CONFIG_SCREEN_LAYOUT
10128 | ActivityInfo.CONFIG_ORIENTATION
10129 | ActivityInfo.CONFIG_KEYBOARD
10130 | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
10131 mResolveInfo.activityInfo = mResolveActivity;
10132 mResolveInfo.priority = 0;
10133 mResolveInfo.preferredOrder = 0;
10134 mResolveInfo.match = 0;
10135 mResolveComponentName = new ComponentName(
10136 mAndroidApplication.packageName, mResolveActivity.name);
10142 ArrayList<PackageParser.Package> clientLibPkgs = null;
10144 synchronized (mPackages) {
10145 boolean hasStaticSharedLibs = false;
10147 // Any app can add new static shared libraries
10148 if (pkg.staticSharedLibName != null) {
10149 // Static shared libs don't allow renaming as they have synthetic package
10150 // names to allow install of multiple versions, so use name from manifest.
10151 if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName,
10152 pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC,
10153 pkg.manifestPackageName, pkg.mVersionCode)) {
10154 hasStaticSharedLibs = true;
10156 Slog.w(TAG, "Package " + pkg.packageName + " library "
10157 + pkg.staticSharedLibName + " already exists; skipping");
10159 // Static shared libs cannot be updated once installed since they
10160 // use synthetic package name which includes the version code, so
10161 // not need to update other packages's shared lib dependencies.
10164 if (!hasStaticSharedLibs
10165 && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10166 // Only system apps can add new dynamic shared libraries.
10167 if (pkg.libraryNames != null) {
10168 for (int i = 0; i < pkg.libraryNames.size(); i++) {
10169 String name = pkg.libraryNames.get(i);
10170 boolean allowed = false;
10171 if (pkg.isUpdatedSystemApp()) {
10172 // New library entries can only be added through the
10173 // system image. This is important to get rid of a lot
10174 // of nasty edge cases: for example if we allowed a non-
10175 // system update of the app to add a library, then uninstalling
10176 // the update would make the library go away, and assumptions
10177 // we made such as through app install filtering would now
10178 // have allowed apps on the device which aren't compatible
10179 // with it. Better to just have the restriction here, be
10180 // conservative, and create many fewer cases that can negatively
10181 // impact the user experience.
10182 final PackageSetting sysPs = mSettings
10183 .getDisabledSystemPkgLPr(pkg.packageName);
10184 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
10185 for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
10186 if (name.equals(sysPs.pkg.libraryNames.get(j))) {
10196 if (!addSharedLibraryLPw(null, pkg.packageName, name,
10197 SharedLibraryInfo.VERSION_UNDEFINED,
10198 SharedLibraryInfo.TYPE_DYNAMIC,
10199 pkg.packageName, pkg.mVersionCode)) {
10200 Slog.w(TAG, "Package " + pkg.packageName + " library "
10201 + name + " already exists; skipping");
10204 Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
10205 + name + " that is not declared on system image; skipping");
10209 if ((scanFlags & SCAN_BOOTING) == 0) {
10210 // If we are not booting, we need to update any applications
10211 // that are clients of our shared library. If we are booting,
10212 // this will all be done once the scan is complete.
10213 clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
10219 if ((scanFlags & SCAN_BOOTING) != 0) {
10220 // No apps can run during boot scan, so they don't need to be frozen
10221 } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
10222 // Caller asked to not kill app, so it's probably not frozen
10223 } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
10224 // Caller asked us to ignore frozen check for some reason; they
10225 // probably didn't know the package name
10227 // We're doing major surgery on this package, so it better be frozen
10228 // right now to keep it from launching
10229 checkPackageFrozen(pkgName);
10232 // Also need to kill any apps that are dependent on the library.
10233 if (clientLibPkgs != null) {
10234 for (int i=0; i<clientLibPkgs.size(); i++) {
10235 PackageParser.Package clientPkg = clientLibPkgs.get(i);
10236 killApplication(clientPkg.applicationInfo.packageName,
10237 clientPkg.applicationInfo.uid, "update lib");
10242 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
10244 synchronized (mPackages) {
10245 // We don't expect installation to fail beyond this point
10247 // Add the new setting to mSettings
10248 mSettings.insertPackageSettingLPw(pkgSetting, pkg);
10249 // Add the new setting to mPackages
10250 mPackages.put(pkg.applicationInfo.packageName, pkg);
10251 // Make sure we don't accidentally delete its data.
10252 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
10253 while (iter.hasNext()) {
10254 PackageCleanItem item = iter.next();
10255 if (pkgName.equals(item.packageName)) {
10260 // Add the package's KeySets to the global KeySetManagerService
10261 KeySetManagerService ksms = mSettings.mKeySetManagerService;
10262 ksms.addScannedPackageLPw(pkg);
10264 int N = pkg.providers.size();
10265 StringBuilder r = null;
10267 for (i=0; i<N; i++) {
10268 PackageParser.Provider p = pkg.providers.get(i);
10269 p.info.processName = fixProcessName(pkg.applicationInfo.processName,
10270 p.info.processName);
10271 mProviders.addProvider(p);
10272 p.syncable = p.info.isSyncable;
10273 if (p.info.authority != null) {
10274 String names[] = p.info.authority.split(";");
10275 p.info.authority = null;
10276 for (int j = 0; j < names.length; j++) {
10277 if (j == 1 && p.syncable) {
10278 // We only want the first authority for a provider to possibly be
10279 // syncable, so if we already added this provider using a different
10280 // authority clear the syncable flag. We copy the provider before
10281 // changing it because the mProviders object contains a reference
10282 // to a provider that we don't want to change.
10283 // Only do this for the second authority since the resulting provider
10284 // object can be the same for all future authorities for this provider.
10285 p = new PackageParser.Provider(p);
10286 p.syncable = false;
10288 if (!mProvidersByAuthority.containsKey(names[j])) {
10289 mProvidersByAuthority.put(names[j], p);
10290 if (p.info.authority == null) {
10291 p.info.authority = names[j];
10293 p.info.authority = p.info.authority + ";" + names[j];
10295 if (DEBUG_PACKAGE_SCANNING) {
10297 Log.d(TAG, "Registered content provider: " + names[j]
10298 + ", className = " + p.info.name + ", isSyncable = "
10299 + p.info.isSyncable);
10302 PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
10303 Slog.w(TAG, "Skipping provider name " + names[j] +
10304 " (in package " + pkg.applicationInfo.packageName +
10305 "): name already used by "
10306 + ((other != null && other.getComponentName() != null)
10307 ? other.getComponentName().getPackageName() : "?"));
10313 r = new StringBuilder(256);
10317 r.append(p.info.name);
10321 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r);
10324 N = pkg.services.size();
10326 for (i=0; i<N; i++) {
10327 PackageParser.Service s = pkg.services.get(i);
10328 s.info.processName = fixProcessName(pkg.applicationInfo.processName,
10329 s.info.processName);
10330 mServices.addService(s);
10333 r = new StringBuilder(256);
10337 r.append(s.info.name);
10341 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r);
10344 N = pkg.receivers.size();
10346 for (i=0; i<N; i++) {
10347 PackageParser.Activity a = pkg.receivers.get(i);
10348 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
10349 a.info.processName);
10350 mReceivers.addActivity(a, "receiver");
10353 r = new StringBuilder(256);
10357 r.append(a.info.name);
10361 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r);
10364 N = pkg.activities.size();
10366 for (i=0; i<N; i++) {
10367 PackageParser.Activity a = pkg.activities.get(i);
10368 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
10369 a.info.processName);
10370 mActivities.addActivity(a, "activity");
10373 r = new StringBuilder(256);
10377 r.append(a.info.name);
10381 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r);
10384 N = pkg.permissionGroups.size();
10386 for (i=0; i<N; i++) {
10387 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
10388 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
10389 final String curPackageName = cur == null ? null : cur.info.packageName;
10390 // Dont allow ephemeral apps to define new permission groups.
10391 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10392 Slog.w(TAG, "Permission group " + pg.info.name + " from package "
10393 + pg.info.packageName
10394 + " ignored: instant apps cannot define new permission groups.");
10397 final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
10398 if (cur == null || isPackageUpdate) {
10399 mPermissionGroups.put(pg.info.name, pg);
10402 r = new StringBuilder(256);
10406 if (isPackageUpdate) {
10409 r.append(pg.info.name);
10412 Slog.w(TAG, "Permission group " + pg.info.name + " from package "
10413 + pg.info.packageName + " ignored: original from "
10414 + cur.info.packageName);
10417 r = new StringBuilder(256);
10422 r.append(pg.info.name);
10427 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r);
10430 N = pkg.permissions.size();
10432 for (i=0; i<N; i++) {
10433 PackageParser.Permission p = pkg.permissions.get(i);
10435 // Dont allow ephemeral apps to define new permissions.
10436 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10437 Slog.w(TAG, "Permission " + p.info.name + " from package "
10438 + p.info.packageName
10439 + " ignored: instant apps cannot define new permissions.");
10443 // Assume by default that we did not install this permission into the system.
10444 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
10446 // Now that permission groups have a special meaning, we ignore permission
10447 // groups for legacy apps to prevent unexpected behavior. In particular,
10448 // permissions for one app being granted to someone just becase they happen
10449 // to be in a group defined by another app (before this had no implications).
10450 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
10451 p.group = mPermissionGroups.get(p.info.group);
10452 // Warn for a permission in an unknown group.
10453 if (p.info.group != null && p.group == null) {
10454 Slog.w(TAG, "Permission " + p.info.name + " from package "
10455 + p.info.packageName + " in an unknown group " + p.info.group);
10459 ArrayMap<String, BasePermission> permissionMap =
10460 p.tree ? mSettings.mPermissionTrees
10461 : mSettings.mPermissions;
10462 BasePermission bp = permissionMap.get(p.info.name);
10464 // Allow system apps to redefine non-system permissions
10465 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
10466 final boolean currentOwnerIsSystem = (bp.perm != null
10467 && isSystemApp(bp.perm.owner));
10468 if (isSystemApp(p.owner)) {
10469 if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
10470 // It's a built-in permission and no owner, take ownership now
10471 bp.packageSetting = pkgSetting;
10473 bp.uid = pkg.applicationInfo.uid;
10474 bp.sourcePackage = p.info.packageName;
10475 p.info.flags |= PermissionInfo.FLAG_INSTALLED;
10476 } else if (!currentOwnerIsSystem) {
10477 String msg = "New decl " + p.owner + " of permission "
10478 + p.info.name + " is system; overriding " + bp.sourcePackage;
10479 reportSettingsProblem(Log.WARN, msg);
10486 bp = new BasePermission(p.info.name, p.info.packageName,
10487 BasePermission.TYPE_NORMAL);
10488 permissionMap.put(p.info.name, bp);
10491 if (bp.perm == null) {
10492 if (bp.sourcePackage == null
10493 || bp.sourcePackage.equals(p.info.packageName)) {
10494 BasePermission tree = findPermissionTreeLP(p.info.name);
10496 || tree.sourcePackage.equals(p.info.packageName)) {
10497 bp.packageSetting = pkgSetting;
10499 bp.uid = pkg.applicationInfo.uid;
10500 bp.sourcePackage = p.info.packageName;
10501 p.info.flags |= PermissionInfo.FLAG_INSTALLED;
10504 r = new StringBuilder(256);
10508 r.append(p.info.name);
10511 Slog.w(TAG, "Permission " + p.info.name + " from package "
10512 + p.info.packageName + " ignored: base tree "
10513 + tree.name + " is from package "
10514 + tree.sourcePackage);
10517 Slog.w(TAG, "Permission " + p.info.name + " from package "
10518 + p.info.packageName + " ignored: original from "
10519 + bp.sourcePackage);
10521 } else if (chatty) {
10523 r = new StringBuilder(256);
10528 r.append(p.info.name);
10530 if (bp.perm == p) {
10531 bp.protectionLevel = p.info.protectionLevel;
10536 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r);
10539 N = pkg.instrumentation.size();
10541 for (i=0; i<N; i++) {
10542 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
10543 a.info.packageName = pkg.applicationInfo.packageName;
10544 a.info.sourceDir = pkg.applicationInfo.sourceDir;
10545 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
10546 a.info.splitNames = pkg.splitNames;
10547 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
10548 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
10549 a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
10550 a.info.dataDir = pkg.applicationInfo.dataDir;
10551 a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
10552 a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
10553 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
10554 a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
10555 mInstrumentation.put(a.getComponentName(), a);
10558 r = new StringBuilder(256);
10562 r.append(a.info.name);
10566 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r);
10569 if (pkg.protectedBroadcasts != null) {
10570 N = pkg.protectedBroadcasts.size();
10571 for (i=0; i<N; i++) {
10572 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
10577 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10581 * Derive the ABI of a non-system package located at {@code scanFile}. This information
10582 * is derived purely on the basis of the contents of {@code scanFile} and
10583 * {@code cpuAbiOverride}.
10585 * If {@code extractLibs} is true, native libraries are extracted from the app if required.
10587 private static void derivePackageAbi(PackageParser.Package pkg, File scanFile,
10588 String cpuAbiOverride, boolean extractLibs,
10589 File appLib32InstallDir)
10590 throws PackageManagerException {
10591 // Give ourselves some initial paths; we'll come back for another
10592 // pass once we've determined ABI below.
10593 setNativeLibraryPaths(pkg, appLib32InstallDir);
10595 // We would never need to extract libs for forward-locked and external packages,
10596 // since the container service will do it for us. We shouldn't attempt to
10597 // extract libs from system app when it was not updated.
10598 if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
10599 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
10600 extractLibs = false;
10603 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
10604 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
10606 NativeLibraryHelper.Handle handle = null;
10608 handle = NativeLibraryHelper.Handle.create(pkg);
10609 // TODO(multiArch): This can be null for apps that didn't go through the
10610 // usual installation process. We can calculate it again, like we
10611 // do during install time.
10613 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
10615 final File nativeLibraryRoot = new File(nativeLibraryRootStr);
10617 // Null out the abis so that they can be recalculated.
10618 pkg.applicationInfo.primaryCpuAbi = null;
10619 pkg.applicationInfo.secondaryCpuAbi = null;
10620 if (isMultiArch(pkg.applicationInfo)) {
10621 // Warn if we've set an abiOverride for multi-lib packages..
10622 // By definition, we need to copy both 32 and 64 bit libraries for
10624 if (pkg.cpuAbiOverride != null
10625 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
10626 Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
10629 int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
10630 int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
10631 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
10633 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
10634 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
10635 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
10636 useIsaSpecificSubdirs);
10638 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
10639 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
10641 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10644 maybeThrowExceptionForMultiArchCopy(
10645 "Error unpackaging 32 bit native libs for multiarch app.", abi32);
10647 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
10649 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
10650 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
10651 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
10652 useIsaSpecificSubdirs);
10654 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
10655 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
10657 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10660 maybeThrowExceptionForMultiArchCopy(
10661 "Error unpackaging 64 bit native libs for multiarch app.", abi64);
10664 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
10668 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
10670 if (pkg.use32bitAbi) {
10671 pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
10672 pkg.applicationInfo.primaryCpuAbi = abi;
10674 pkg.applicationInfo.secondaryCpuAbi = abi;
10677 pkg.applicationInfo.primaryCpuAbi = abi;
10682 String[] abiList = (cpuAbiOverride != null) ?
10683 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
10685 // Enable gross and lame hacks for apps that are built with old
10686 // SDK tools. We must scan their APKs for renderscript bitcode and
10687 // not launch them if it's present. Don't bother checking on devices
10688 // that don't have 64 bit support.
10689 boolean needsRenderScriptOverride = false;
10690 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
10691 NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
10692 abiList = Build.SUPPORTED_32_BIT_ABIS;
10693 needsRenderScriptOverride = true;
10698 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
10699 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
10700 nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
10702 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
10703 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
10705 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10707 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
10708 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
10709 "Error unpackaging native libs for app, errorCode=" + copyRet);
10712 if (copyRet >= 0) {
10713 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
10714 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
10715 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
10716 } else if (needsRenderScriptOverride) {
10717 pkg.applicationInfo.primaryCpuAbi = abiList[0];
10720 } catch (IOException ioe) {
10721 Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
10723 IoUtils.closeQuietly(handle);
10726 // Now that we've calculated the ABIs and determined if it's an internal app,
10727 // we will go ahead and populate the nativeLibraryPath.
10728 setNativeLibraryPaths(pkg, appLib32InstallDir);
10732 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
10733 * i.e, so that all packages can be run inside a single process if required.
10735 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
10736 * this function will either try and make the ABI for all packages in {@code packagesForUser}
10737 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
10738 * the ABI selected for {@code packagesForUser}. This variant is used when installing or
10739 * updating a package that belongs to a shared user.
10741 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
10742 * adds unnecessary complexity.
10744 private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
10745 PackageParser.Package scannedPackage) {
10746 String requiredInstructionSet = null;
10747 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
10748 requiredInstructionSet = VMRuntime.getInstructionSet(
10749 scannedPackage.applicationInfo.primaryCpuAbi);
10752 PackageSetting requirer = null;
10753 for (PackageSetting ps : packagesForUser) {
10754 // If packagesForUser contains scannedPackage, we skip it. This will happen
10755 // when scannedPackage is an update of an existing package. Without this check,
10756 // we will never be able to change the ABI of any package belonging to a shared
10757 // user, even if it's compatible with other packages.
10758 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
10759 if (ps.primaryCpuAbiString == null) {
10763 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
10764 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
10765 // We have a mismatch between instruction sets (say arm vs arm64) warn about
10766 // this but there's not much we can do.
10767 String errorMessage = "Instruction set mismatch, "
10768 + ((requirer == null) ? "[caller]" : requirer)
10769 + " requires " + requiredInstructionSet + " whereas " + ps
10770 + " requires " + instructionSet;
10771 Slog.w(TAG, errorMessage);
10774 if (requiredInstructionSet == null) {
10775 requiredInstructionSet = instructionSet;
10781 if (requiredInstructionSet != null) {
10782 String adjustedAbi;
10783 if (requirer != null) {
10784 // requirer != null implies that either scannedPackage was null or that scannedPackage
10785 // did not require an ABI, in which case we have to adjust scannedPackage to match
10786 // the ABI of the set (which is the same as requirer's ABI)
10787 adjustedAbi = requirer.primaryCpuAbiString;
10788 if (scannedPackage != null) {
10789 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
10792 // requirer == null implies that we're updating all ABIs in the set to
10793 // match scannedPackage.
10794 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi;
10797 for (PackageSetting ps : packagesForUser) {
10798 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
10799 if (ps.primaryCpuAbiString != null) {
10803 ps.primaryCpuAbiString = adjustedAbi;
10804 if (ps.pkg != null && ps.pkg.applicationInfo != null &&
10805 !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
10806 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
10807 Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
10809 + (requirer != null ? requirer.pkg : "null")
10810 + ", scannedPackage="
10811 + (scannedPackage != null ? scannedPackage : "null")
10814 mInstaller.rmdex(ps.codePathString,
10815 getDexCodeInstructionSet(getPreferredInstructionSet()));
10816 } catch (InstallerException ignored) {
10824 private void setUpCustomResolverActivity(PackageParser.Package pkg) {
10825 synchronized (mPackages) {
10826 mResolverReplaced = true;
10827 // Set up information for custom user intent resolution activity.
10828 mResolveActivity.applicationInfo = pkg.applicationInfo;
10829 mResolveActivity.name = mCustomResolverComponentName.getClassName();
10830 mResolveActivity.packageName = pkg.applicationInfo.packageName;
10831 mResolveActivity.processName = pkg.applicationInfo.packageName;
10832 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
10833 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
10834 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
10835 mResolveActivity.theme = 0;
10836 mResolveActivity.exported = true;
10837 mResolveActivity.enabled = true;
10838 mResolveInfo.activityInfo = mResolveActivity;
10839 mResolveInfo.priority = 0;
10840 mResolveInfo.preferredOrder = 0;
10841 mResolveInfo.match = 0;
10842 mResolveComponentName = mCustomResolverComponentName;
10843 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
10844 mResolveComponentName);
10848 private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
10849 if (installerActivity == null) {
10850 if (DEBUG_EPHEMERAL) {
10851 Slog.d(TAG, "Clear ephemeral installer activity");
10853 mInstantAppInstallerActivity = null;
10857 if (DEBUG_EPHEMERAL) {
10858 Slog.d(TAG, "Set ephemeral installer activity: "
10859 + installerActivity.getComponentName());
10861 // Set up information for ephemeral installer activity
10862 mInstantAppInstallerActivity = installerActivity;
10863 mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
10864 | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
10865 mInstantAppInstallerActivity.exported = true;
10866 mInstantAppInstallerActivity.enabled = true;
10867 mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
10868 mInstantAppInstallerInfo.priority = 0;
10869 mInstantAppInstallerInfo.preferredOrder = 1;
10870 mInstantAppInstallerInfo.isDefault = true;
10871 mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
10872 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
10875 private static String calculateBundledApkRoot(final String codePathString) {
10876 final File codePath = new File(codePathString);
10877 final File codeRoot;
10878 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
10879 codeRoot = Environment.getRootDirectory();
10880 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
10881 codeRoot = Environment.getOemDirectory();
10882 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
10883 codeRoot = Environment.getVendorDirectory();
10885 // Unrecognized code path; take its top real segment as the apk root:
10886 // e.g. /something/app/blah.apk => /something
10888 File f = codePath.getCanonicalFile();
10889 File parent = f.getParentFile(); // non-null because codePath is a file
10891 while ((tmp = parent.getParentFile()) != null) {
10896 Slog.w(TAG, "Unrecognized code path "
10897 + codePath + " - using " + codeRoot);
10898 } catch (IOException e) {
10899 // Can't canonicalize the code path -- shenanigans?
10900 Slog.w(TAG, "Can't canonicalize code path " + codePath);
10901 return Environment.getRootDirectory().getPath();
10904 return codeRoot.getPath();
10908 * Derive and set the location of native libraries for the given package,
10909 * which varies depending on where and how the package was installed.
10911 private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
10912 final ApplicationInfo info = pkg.applicationInfo;
10913 final String codePath = pkg.codePath;
10914 final File codeFile = new File(codePath);
10915 final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
10916 final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
10918 info.nativeLibraryRootDir = null;
10919 info.nativeLibraryRootRequiresIsa = false;
10920 info.nativeLibraryDir = null;
10921 info.secondaryNativeLibraryDir = null;
10923 if (isApkFile(codeFile)) {
10924 // Monolithic install
10926 // If "/system/lib64/apkname" exists, assume that is the per-package
10927 // native library directory to use; otherwise use "/system/lib/apkname".
10928 final String apkRoot = calculateBundledApkRoot(info.sourceDir);
10929 final boolean is64Bit = VMRuntime.is64BitInstructionSet(
10930 getPrimaryInstructionSet(info));
10932 // This is a bundled system app so choose the path based on the ABI.
10933 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
10934 // is just the default path.
10935 final String apkName = deriveCodePathName(codePath);
10936 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
10937 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
10938 apkName).getAbsolutePath();
10940 if (info.secondaryCpuAbi != null) {
10941 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
10942 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
10943 secondaryLibDir, apkName).getAbsolutePath();
10945 } else if (asecApp) {
10946 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
10947 .getAbsolutePath();
10949 final String apkName = deriveCodePathName(codePath);
10950 info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
10951 .getAbsolutePath();
10954 info.nativeLibraryRootRequiresIsa = false;
10955 info.nativeLibraryDir = info.nativeLibraryRootDir;
10958 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
10959 info.nativeLibraryRootRequiresIsa = true;
10961 info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
10962 getPrimaryInstructionSet(info)).getAbsolutePath();
10964 if (info.secondaryCpuAbi != null) {
10965 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
10966 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
10972 * Calculate the abis and roots for a bundled app. These can uniquely
10973 * be determined from the contents of the system partition, i.e whether
10974 * it contains 64 or 32 bit shared libraries etc. We do not validate any
10975 * of this information, and instead assume that the system was built
10978 private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
10979 PackageSetting pkgSetting) {
10980 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
10982 // If "/system/lib64/apkname" exists, assume that is the per-package
10983 // native library directory to use; otherwise use "/system/lib/apkname".
10984 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
10985 setBundledAppAbi(pkg, apkRoot, apkName);
10986 // pkgSetting might be null during rescan following uninstall of updates
10987 // to a bundled app, so accommodate that possibility. The settings in
10988 // that case will be established later from the parsed package.
10990 // If the settings aren't null, sync them up with what we've just derived.
10991 // note that apkRoot isn't stored in the package settings.
10992 if (pkgSetting != null) {
10993 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
10994 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
10999 * Deduces the ABI of a bundled app and sets the relevant fields on the
11000 * parsed pkg object.
11002 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
11003 * under which system libraries are installed.
11004 * @param apkName the name of the installed package.
11006 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
11007 final File codeFile = new File(pkg.codePath);
11009 final boolean has64BitLibs;
11010 final boolean has32BitLibs;
11011 if (isApkFile(codeFile)) {
11012 // Monolithic install
11013 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
11014 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
11017 final File rootDir = new File(codeFile, LIB_DIR_NAME);
11018 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
11019 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
11020 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
11021 has64BitLibs = (new File(rootDir, isa)).exists();
11023 has64BitLibs = false;
11025 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
11026 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
11027 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
11028 has32BitLibs = (new File(rootDir, isa)).exists();
11030 has32BitLibs = false;
11034 if (has64BitLibs && !has32BitLibs) {
11035 // The package has 64 bit libs, but not 32 bit libs. Its primary
11036 // ABI should be 64 bit. We can safely assume here that the bundled
11037 // native libraries correspond to the most preferred ABI in the list.
11039 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11040 pkg.applicationInfo.secondaryCpuAbi = null;
11041 } else if (has32BitLibs && !has64BitLibs) {
11042 // The package has 32 bit libs but not 64 bit libs. Its primary
11043 // ABI should be 32 bit.
11045 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11046 pkg.applicationInfo.secondaryCpuAbi = null;
11047 } else if (has32BitLibs && has64BitLibs) {
11048 // The application has both 64 and 32 bit bundled libraries. We check
11049 // here that the app declares multiArch support, and warn if it doesn't.
11051 // We will be lenient here and record both ABIs. The primary will be the
11052 // ABI that's higher on the list, i.e, a device that's configured to prefer
11053 // 64 bit apps will see a 64 bit primary ABI,
11055 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
11056 Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
11059 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
11060 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11061 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11063 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11064 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11067 pkg.applicationInfo.primaryCpuAbi = null;
11068 pkg.applicationInfo.secondaryCpuAbi = null;
11072 private void killApplication(String pkgName, int appId, String reason) {
11073 killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
11076 private void killApplication(String pkgName, int appId, int userId, String reason) {
11077 // Request the ActivityManager to kill the process(only for existing packages)
11078 // so that we do not end up in a confused state while the user is still using the older
11079 // version of the application while the new one gets installed.
11080 final long token = Binder.clearCallingIdentity();
11082 IActivityManager am = ActivityManager.getService();
11085 am.killApplication(pkgName, appId, userId, reason);
11086 } catch (RemoteException e) {
11090 Binder.restoreCallingIdentity(token);
11094 private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
11095 // Remove the parent package setting
11096 PackageSetting ps = (PackageSetting) pkg.mExtras;
11098 removePackageLI(ps, chatty);
11100 // Remove the child package setting
11101 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11102 for (int i = 0; i < childCount; i++) {
11103 PackageParser.Package childPkg = pkg.childPackages.get(i);
11104 ps = (PackageSetting) childPkg.mExtras;
11106 removePackageLI(ps, chatty);
11111 void removePackageLI(PackageSetting ps, boolean chatty) {
11112 if (DEBUG_INSTALL) {
11114 Log.d(TAG, "Removing package " + ps.name);
11118 synchronized (mPackages) {
11119 mPackages.remove(ps.name);
11120 final PackageParser.Package pkg = ps.pkg;
11122 cleanPackageDataStructuresLILPw(pkg, chatty);
11127 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
11128 if (DEBUG_INSTALL) {
11130 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
11134 synchronized (mPackages) {
11135 // Remove the parent package
11136 mPackages.remove(pkg.applicationInfo.packageName);
11137 cleanPackageDataStructuresLILPw(pkg, chatty);
11139 // Remove the child packages
11140 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11141 for (int i = 0; i < childCount; i++) {
11142 PackageParser.Package childPkg = pkg.childPackages.get(i);
11143 mPackages.remove(childPkg.applicationInfo.packageName);
11144 cleanPackageDataStructuresLILPw(childPkg, chatty);
11149 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
11150 int N = pkg.providers.size();
11151 StringBuilder r = null;
11153 for (i=0; i<N; i++) {
11154 PackageParser.Provider p = pkg.providers.get(i);
11155 mProviders.removeProvider(p);
11156 if (p.info.authority == null) {
11158 /* There was another ContentProvider with this authority when
11159 * this app was installed so this authority is null,
11160 * Ignore it as we don't have to unregister the provider.
11164 String names[] = p.info.authority.split(";");
11165 for (int j = 0; j < names.length; j++) {
11166 if (mProvidersByAuthority.get(names[j]) == p) {
11167 mProvidersByAuthority.remove(names[j]);
11168 if (DEBUG_REMOVE) {
11170 Log.d(TAG, "Unregistered content provider: " + names[j]
11171 + ", className = " + p.info.name + ", isSyncable = "
11172 + p.info.isSyncable);
11176 if (DEBUG_REMOVE && chatty) {
11178 r = new StringBuilder(256);
11182 r.append(p.info.name);
11186 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r);
11189 N = pkg.services.size();
11191 for (i=0; i<N; i++) {
11192 PackageParser.Service s = pkg.services.get(i);
11193 mServices.removeService(s);
11196 r = new StringBuilder(256);
11200 r.append(s.info.name);
11204 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r);
11207 N = pkg.receivers.size();
11209 for (i=0; i<N; i++) {
11210 PackageParser.Activity a = pkg.receivers.get(i);
11211 mReceivers.removeActivity(a, "receiver");
11212 if (DEBUG_REMOVE && chatty) {
11214 r = new StringBuilder(256);
11218 r.append(a.info.name);
11222 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r);
11225 N = pkg.activities.size();
11227 for (i=0; i<N; i++) {
11228 PackageParser.Activity a = pkg.activities.get(i);
11229 mActivities.removeActivity(a, "activity");
11230 if (DEBUG_REMOVE && chatty) {
11232 r = new StringBuilder(256);
11236 r.append(a.info.name);
11240 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r);
11243 N = pkg.permissions.size();
11245 for (i=0; i<N; i++) {
11246 PackageParser.Permission p = pkg.permissions.get(i);
11247 BasePermission bp = mSettings.mPermissions.get(p.info.name);
11249 bp = mSettings.mPermissionTrees.get(p.info.name);
11251 if (bp != null && bp.perm == p) {
11253 if (DEBUG_REMOVE && chatty) {
11255 r = new StringBuilder(256);
11259 r.append(p.info.name);
11262 if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
11263 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name);
11264 if (appOpPkgs != null) {
11265 appOpPkgs.remove(pkg.packageName);
11270 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
11273 N = pkg.requestedPermissions.size();
11275 for (i=0; i<N; i++) {
11276 String perm = pkg.requestedPermissions.get(i);
11277 BasePermission bp = mSettings.mPermissions.get(perm);
11278 if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
11279 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm);
11280 if (appOpPkgs != null) {
11281 appOpPkgs.remove(pkg.packageName);
11282 if (appOpPkgs.isEmpty()) {
11283 mAppOpPermissionPackages.remove(perm);
11289 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
11292 N = pkg.instrumentation.size();
11294 for (i=0; i<N; i++) {
11295 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
11296 mInstrumentation.remove(a.getComponentName());
11297 if (DEBUG_REMOVE && chatty) {
11299 r = new StringBuilder(256);
11303 r.append(a.info.name);
11307 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r);
11311 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11312 // Only system apps can hold shared libraries.
11313 if (pkg.libraryNames != null) {
11314 for (i = 0; i < pkg.libraryNames.size(); i++) {
11315 String name = pkg.libraryNames.get(i);
11316 if (removeSharedLibraryLPw(name, 0)) {
11317 if (DEBUG_REMOVE && chatty) {
11319 r = new StringBuilder(256);
11332 // Any package can hold static shared libraries.
11333 if (pkg.staticSharedLibName != null) {
11334 if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
11335 if (DEBUG_REMOVE && chatty) {
11337 r = new StringBuilder(256);
11341 r.append(pkg.staticSharedLibName);
11347 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r);
11351 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
11352 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
11353 if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
11360 static final int UPDATE_PERMISSIONS_ALL = 1<<0;
11361 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
11362 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
11364 private void updatePermissionsLPw(PackageParser.Package pkg, int flags) {
11365 // Update the parent permissions
11366 updatePermissionsLPw(pkg.packageName, pkg, flags);
11367 // Update the child permissions
11368 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11369 for (int i = 0; i < childCount; i++) {
11370 PackageParser.Package childPkg = pkg.childPackages.get(i);
11371 updatePermissionsLPw(childPkg.packageName, childPkg, flags);
11375 private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
11377 final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
11378 updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
11381 private void updatePermissionsLPw(String changingPkg,
11382 PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
11383 // Make sure there are no dangling permission trees.
11384 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
11385 while (it.hasNext()) {
11386 final BasePermission bp = it.next();
11387 if (bp.packageSetting == null) {
11388 // We may not yet have parsed the package, so just see if
11389 // we still know about its settings.
11390 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
11392 if (bp.packageSetting == null) {
11393 Slog.w(TAG, "Removing dangling permission tree: " + bp.name
11394 + " from package " + bp.sourcePackage);
11396 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
11397 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
11398 Slog.i(TAG, "Removing old permission tree: " + bp.name
11399 + " from package " + bp.sourcePackage);
11400 flags |= UPDATE_PERMISSIONS_ALL;
11406 // Make sure all dynamic permissions have been assigned to a package,
11407 // and make sure there are no dangling permissions.
11408 it = mSettings.mPermissions.values().iterator();
11409 while (it.hasNext()) {
11410 final BasePermission bp = it.next();
11411 if (bp.type == BasePermission.TYPE_DYNAMIC) {
11412 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
11413 + bp.name + " pkg=" + bp.sourcePackage
11414 + " info=" + bp.pendingInfo);
11415 if (bp.packageSetting == null && bp.pendingInfo != null) {
11416 final BasePermission tree = findPermissionTreeLP(bp.name);
11417 if (tree != null && tree.perm != null) {
11418 bp.packageSetting = tree.packageSetting;
11419 bp.perm = new PackageParser.Permission(tree.perm.owner,
11420 new PermissionInfo(bp.pendingInfo));
11421 bp.perm.info.packageName = tree.perm.info.packageName;
11422 bp.perm.info.name = bp.name;
11427 if (bp.packageSetting == null) {
11428 // We may not yet have parsed the package, so just see if
11429 // we still know about its settings.
11430 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
11432 if (bp.packageSetting == null) {
11433 Slog.w(TAG, "Removing dangling permission: " + bp.name
11434 + " from package " + bp.sourcePackage);
11436 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
11437 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
11438 Slog.i(TAG, "Removing old permission: " + bp.name
11439 + " from package " + bp.sourcePackage);
11440 flags |= UPDATE_PERMISSIONS_ALL;
11446 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
11447 // Now update the permissions for all packages, in particular
11448 // replace the granted permissions of the system packages.
11449 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
11450 for (PackageParser.Package pkg : mPackages.values()) {
11451 if (pkg != pkgInfo) {
11452 // Only replace for packages on requested volume
11453 final String volumeUuid = getVolumeUuidForPackage(pkg);
11454 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
11455 && Objects.equals(replaceVolumeUuid, volumeUuid);
11456 grantPermissionsLPw(pkg, replace, changingPkg);
11461 if (pkgInfo != null) {
11462 // Only replace for packages on requested volume
11463 final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
11464 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
11465 && Objects.equals(replaceVolumeUuid, volumeUuid);
11466 grantPermissionsLPw(pkgInfo, replace, changingPkg);
11468 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11471 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
11472 String packageOfInterest) {
11473 // IMPORTANT: There are two types of permissions: install and runtime.
11474 // Install time permissions are granted when the app is installed to
11475 // all device users and users added in the future. Runtime permissions
11476 // are granted at runtime explicitly to specific users. Normal and signature
11477 // protected permissions are install time permissions. Dangerous permissions
11478 // are install permissions if the app's target SDK is Lollipop MR1 or older,
11479 // otherwise they are runtime permissions. This function does not manage
11480 // runtime permissions except for the case an app targeting Lollipop MR1
11481 // being upgraded to target a newer SDK, in which case dangerous permissions
11482 // are transformed from install time to runtime ones.
11484 final PackageSetting ps = (PackageSetting) pkg.mExtras;
11489 PermissionsState permissionsState = ps.getPermissionsState();
11490 PermissionsState origPermissions = permissionsState;
11492 final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
11494 boolean runtimePermissionsRevoked = false;
11495 int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
11497 boolean changedInstallPermission = false;
11500 ps.installPermissionsFixed = false;
11501 if (!ps.isSharedUser()) {
11502 origPermissions = new PermissionsState(permissionsState);
11503 permissionsState.reset();
11505 // We need to know only about runtime permission changes since the
11506 // calling code always writes the install permissions state but
11507 // the runtime ones are written only if changed. The only cases of
11508 // changed runtime permissions here are promotion of an install to
11509 // runtime and revocation of a runtime from a shared user.
11510 changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
11511 ps.sharedUser, UserManagerService.getInstance().getUserIds());
11512 if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
11513 runtimePermissionsRevoked = true;
11518 permissionsState.setGlobalGids(mGlobalGids);
11520 final int N = pkg.requestedPermissions.size();
11521 for (int i=0; i<N; i++) {
11522 final String name = pkg.requestedPermissions.get(i);
11523 final BasePermission bp = mSettings.mPermissions.get(name);
11524 final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
11525 >= Build.VERSION_CODES.M;
11527 if (DEBUG_INSTALL) {
11528 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
11531 if (bp == null || bp.packageSetting == null) {
11532 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
11533 Slog.w(TAG, "Unknown permission " + name
11534 + " in package " + pkg.packageName);
11540 // Limit ephemeral apps to ephemeral allowed permissions.
11541 if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
11542 Log.i(TAG, "Denying non-ephemeral permission " + bp.name + " for package "
11543 + pkg.packageName);
11547 if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
11548 Log.i(TAG, "Denying runtime-only permission " + bp.name + " for package "
11549 + pkg.packageName);
11553 final String perm = bp.name;
11554 boolean allowedSig = false;
11555 int grant = GRANT_DENIED;
11557 // Keep track of app op permissions.
11558 if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
11559 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
11560 if (pkgs == null) {
11561 pkgs = new ArraySet<>();
11562 mAppOpPermissionPackages.put(bp.name, pkgs);
11564 pkgs.add(pkg.packageName);
11567 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
11569 case PermissionInfo.PROTECTION_NORMAL: {
11570 // For all apps normal permissions are install time ones.
11571 grant = GRANT_INSTALL;
11574 case PermissionInfo.PROTECTION_DANGEROUS: {
11575 // If a permission review is required for legacy apps we represent
11576 // their permissions as always granted runtime ones since we need
11577 // to keep the review required permission flag per user while an
11578 // install permission's state is shared across all users.
11579 if (!appSupportsRuntimePermissions && !mPermissionReviewRequired) {
11580 // For legacy apps dangerous permissions are install time ones.
11581 grant = GRANT_INSTALL;
11582 } else if (origPermissions.hasInstallPermission(bp.name)) {
11583 // For legacy apps that became modern, install becomes runtime.
11584 grant = GRANT_UPGRADE;
11585 } else if (mPromoteSystemApps
11587 && mExistingSystemPackages.contains(ps.name)) {
11588 // For legacy system apps, install becomes runtime.
11589 // We cannot check hasInstallPermission() for system apps since those
11590 // permissions were granted implicitly and not persisted pre-M.
11591 grant = GRANT_UPGRADE;
11593 // For modern apps keep runtime permissions unchanged.
11594 grant = GRANT_RUNTIME;
11598 case PermissionInfo.PROTECTION_SIGNATURE: {
11599 // For all apps signature permissions are install time ones.
11600 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
11602 grant = GRANT_INSTALL;
11607 if (DEBUG_INSTALL) {
11608 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
11611 if (grant != GRANT_DENIED) {
11612 if (!isSystemApp(ps) && ps.installPermissionsFixed) {
11613 // If this is an existing, non-system package, then
11614 // we can't add any new permissions to it.
11615 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
11616 // Except... if this is a permission that was added
11617 // to the platform (note: need to only do this when
11618 // updating the platform).
11619 if (!isNewPlatformPermissionForPackage(perm, pkg)) {
11620 grant = GRANT_DENIED;
11626 case GRANT_INSTALL: {
11627 // Revoke this as runtime permission to handle the case of
11628 // a runtime permission being downgraded to an install one.
11629 // Also in permission review mode we keep dangerous permissions
11631 for (int userId : UserManagerService.getInstance().getUserIds()) {
11632 if (origPermissions.getRuntimePermissionState(
11633 bp.name, userId) != null) {
11634 // Revoke the runtime permission and clear the flags.
11635 origPermissions.revokeRuntimePermission(bp, userId);
11636 origPermissions.updatePermissionFlags(bp, userId,
11637 PackageManager.MASK_PERMISSION_FLAGS, 0);
11638 // If we revoked a permission permission, we have to write.
11639 changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11640 changedRuntimePermissionUserIds, userId);
11643 // Grant an install permission.
11644 if (permissionsState.grantInstallPermission(bp) !=
11645 PermissionsState.PERMISSION_OPERATION_FAILURE) {
11646 changedInstallPermission = true;
11650 case GRANT_RUNTIME: {
11651 // Grant previously granted runtime permissions.
11652 for (int userId : UserManagerService.getInstance().getUserIds()) {
11653 PermissionState permissionState = origPermissions
11654 .getRuntimePermissionState(bp.name, userId);
11655 int flags = permissionState != null
11656 ? permissionState.getFlags() : 0;
11657 if (origPermissions.hasRuntimePermission(bp.name, userId)) {
11658 // Don't propagate the permission in a permission review mode if
11659 // the former was revoked, i.e. marked to not propagate on upgrade.
11660 // Note that in a permission review mode install permissions are
11661 // represented as constantly granted runtime ones since we need to
11662 // keep a per user state associated with the permission. Also the
11663 // revoke on upgrade flag is no longer applicable and is reset.
11664 final boolean revokeOnUpgrade = (flags & PackageManager
11665 .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
11666 if (revokeOnUpgrade) {
11667 flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
11668 // Since we changed the flags, we have to write.
11669 changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11670 changedRuntimePermissionUserIds, userId);
11672 if (!mPermissionReviewRequired || !revokeOnUpgrade) {
11673 if (permissionsState.grantRuntimePermission(bp, userId) ==
11674 PermissionsState.PERMISSION_OPERATION_FAILURE) {
11675 // If we cannot put the permission as it was,
11676 // we have to write.
11677 changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11678 changedRuntimePermissionUserIds, userId);
11682 // If the app supports runtime permissions no need for a review.
11683 if (mPermissionReviewRequired
11684 && appSupportsRuntimePermissions
11685 && (flags & PackageManager
11686 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
11687 flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
11688 // Since we changed the flags, we have to write.
11689 changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11690 changedRuntimePermissionUserIds, userId);
11692 } else if (mPermissionReviewRequired
11693 && !appSupportsRuntimePermissions) {
11694 // For legacy apps that need a permission review, every new
11695 // runtime permission is granted but it is pending a review.
11696 // We also need to review only platform defined runtime
11697 // permissions as these are the only ones the platform knows
11698 // how to disable the API to simulate revocation as legacy
11699 // apps don't expect to run with revoked permissions.
11700 if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) {
11701 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
11702 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
11703 // We changed the flags, hence have to write.
11704 changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11705 changedRuntimePermissionUserIds, userId);
11708 if (permissionsState.grantRuntimePermission(bp, userId)
11709 != PermissionsState.PERMISSION_OPERATION_FAILURE) {
11710 // We changed the permission, hence have to write.
11711 changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11712 changedRuntimePermissionUserIds, userId);
11715 // Propagate the permission flags.
11716 permissionsState.updatePermissionFlags(bp, userId, flags, flags);
11720 case GRANT_UPGRADE: {
11721 // Grant runtime permissions for a previously held install permission.
11722 PermissionState permissionState = origPermissions
11723 .getInstallPermissionState(bp.name);
11724 final int flags = permissionState != null ? permissionState.getFlags() : 0;
11726 if (origPermissions.revokeInstallPermission(bp)
11727 != PermissionsState.PERMISSION_OPERATION_FAILURE) {
11728 // We will be transferring the permission flags, so clear them.
11729 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
11730 PackageManager.MASK_PERMISSION_FLAGS, 0);
11731 changedInstallPermission = true;
11734 // If the permission is not to be promoted to runtime we ignore it and
11735 // also its other flags as they are not applicable to install permissions.
11736 if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
11737 for (int userId : currentUserIds) {
11738 if (permissionsState.grantRuntimePermission(bp, userId) !=
11739 PermissionsState.PERMISSION_OPERATION_FAILURE) {
11740 // Transfer the permission flags.
11741 permissionsState.updatePermissionFlags(bp, userId,
11743 // If we granted the permission, we have to write.
11744 changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11745 changedRuntimePermissionUserIds, userId);
11752 if (packageOfInterest == null
11753 || packageOfInterest.equals(pkg.packageName)) {
11754 Slog.w(TAG, "Not granting permission " + perm
11755 + " to package " + pkg.packageName
11756 + " because it was previously installed without");
11761 if (permissionsState.revokeInstallPermission(bp) !=
11762 PermissionsState.PERMISSION_OPERATION_FAILURE) {
11763 // Also drop the permission flags.
11764 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
11765 PackageManager.MASK_PERMISSION_FLAGS, 0);
11766 changedInstallPermission = true;
11767 Slog.i(TAG, "Un-granting permission " + perm
11768 + " from package " + pkg.packageName
11769 + " (protectionLevel=" + bp.protectionLevel
11770 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
11772 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
11773 // Don't print warning for app op permissions, since it is fine for them
11774 // not to be granted, there is a UI for the user to decide.
11775 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
11776 Slog.w(TAG, "Not granting permission " + perm
11777 + " to package " + pkg.packageName
11778 + " (protectionLevel=" + bp.protectionLevel
11779 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
11786 if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
11787 !isSystemApp(ps) || isUpdatedSystemApp(ps)){
11788 // This is the first that we have heard about this package, so the
11789 // permissions we have now selected are fixed until explicitly
11791 ps.installPermissionsFixed = true;
11794 // Persist the runtime permissions state for users with changes. If permissions
11795 // were revoked because no app in the shared user declares them we have to
11796 // write synchronously to avoid losing runtime permissions state.
11797 for (int userId : changedRuntimePermissionUserIds) {
11798 mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
11802 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
11803 boolean allowed = false;
11804 final int NP = PackageParser.NEW_PERMISSIONS.length;
11805 for (int ip=0; ip<NP; ip++) {
11806 final PackageParser.NewPermissionInfo npi
11807 = PackageParser.NEW_PERMISSIONS[ip];
11808 if (npi.name.equals(perm)
11809 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
11811 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
11812 + pkg.packageName);
11819 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
11820 BasePermission bp, PermissionsState origPermissions) {
11821 boolean privilegedPermission = (bp.protectionLevel
11822 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0;
11823 boolean privappPermissionsDisable =
11824 RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
11825 boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage);
11826 boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
11827 if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivilegedApp()
11828 && !platformPackage && platformPermission) {
11829 ArraySet<String> wlPermissions = SystemConfig.getInstance()
11830 .getPrivAppPermissions(pkg.packageName);
11831 boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
11832 if (!whitelisted) {
11833 Slog.w(TAG, "Privileged permission " + perm + " for package "
11834 + pkg.packageName + " - not in privapp-permissions whitelist");
11835 // Only report violations for apps on system image
11836 if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
11837 if (mPrivappPermissionsViolations == null) {
11838 mPrivappPermissionsViolations = new ArraySet<>();
11840 mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
11842 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
11847 boolean allowed = (compareSignatures(
11848 bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
11849 == PackageManager.SIGNATURE_MATCH)
11850 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
11851 == PackageManager.SIGNATURE_MATCH);
11852 if (!allowed && privilegedPermission) {
11853 if (isSystemApp(pkg)) {
11854 // For updated system applications, a system permission
11855 // is granted only if it had been defined by the original application.
11856 if (pkg.isUpdatedSystemApp()) {
11857 final PackageSetting sysPs = mSettings
11858 .getDisabledSystemPkgLPr(pkg.packageName);
11859 if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) {
11860 // If the original was granted this permission, we take
11861 // that grant decision as read and propagate it to the
11863 if (sysPs.isPrivileged()) {
11867 // The system apk may have been updated with an older
11868 // version of the one on the data partition, but which
11869 // granted a new system permission that it didn't have
11870 // before. In this case we do want to allow the app to
11871 // now get the new permission if the ancestral apk is
11872 // privileged to get it.
11873 if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) {
11874 for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) {
11875 if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) {
11881 // Also if a privileged parent package on the system image or any of
11882 // its children requested a privileged permission, the updated child
11883 // packages can also get the permission.
11884 if (pkg.parentPackage != null) {
11885 final PackageSetting disabledSysParentPs = mSettings
11886 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
11887 if (disabledSysParentPs != null && disabledSysParentPs.pkg != null
11888 && disabledSysParentPs.isPrivileged()) {
11889 if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) {
11891 } else if (disabledSysParentPs.pkg.childPackages != null) {
11892 final int count = disabledSysParentPs.pkg.childPackages.size();
11893 for (int i = 0; i < count; i++) {
11894 PackageParser.Package disabledSysChildPkg =
11895 disabledSysParentPs.pkg.childPackages.get(i);
11896 if (isPackageRequestingPermission(disabledSysChildPkg,
11907 allowed = isPrivilegedApp(pkg);
11912 if (!allowed && (bp.protectionLevel
11913 & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
11914 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
11915 // If this was a previously normal/dangerous permission that got moved
11916 // to a system permission as part of the runtime permission redesign, then
11917 // we still want to blindly grant it to old apps.
11920 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
11921 && pkg.packageName.equals(mRequiredInstallerPackage)) {
11922 // If this permission is to be granted to the system installer and
11923 // this app is an installer, then it gets the permission.
11926 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
11927 && pkg.packageName.equals(mRequiredVerifierPackage)) {
11928 // If this permission is to be granted to the system verifier and
11929 // this app is a verifier, then it gets the permission.
11932 if (!allowed && (bp.protectionLevel
11933 & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
11934 && isSystemApp(pkg)) {
11935 // Any pre-installed system app is allowed to get this permission.
11938 if (!allowed && (bp.protectionLevel
11939 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
11940 // For development permissions, a development permission
11941 // is granted only if it was already granted.
11942 allowed = origPermissions.hasInstallPermission(perm);
11944 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0
11945 && pkg.packageName.equals(mSetupWizardPackage)) {
11946 // If this permission is to be granted to the system setup wizard and
11947 // this app is a setup wizard, then it gets the permission.
11954 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
11955 final int permCount = pkg.requestedPermissions.size();
11956 for (int j = 0; j < permCount; j++) {
11957 String requestedPermission = pkg.requestedPermissions.get(j);
11958 if (permission.equals(requestedPermission)) {
11965 final class ActivityIntentResolver
11966 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
11967 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
11968 boolean defaultOnly, int userId) {
11969 if (!sUserManager.exists(userId)) return null;
11970 mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
11971 return super.queryIntent(intent, resolvedType, defaultOnly, userId);
11974 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
11976 if (!sUserManager.exists(userId)) return null;
11978 return super.queryIntent(intent, resolvedType,
11979 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
11983 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
11984 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
11985 if (!sUserManager.exists(userId)) return null;
11986 if (packageActivities == null) {
11990 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
11991 final int N = packageActivities.size();
11992 ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
11993 new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
11995 ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
11996 for (int i = 0; i < N; ++i) {
11997 intentFilters = packageActivities.get(i).intents;
11998 if (intentFilters != null && intentFilters.size() > 0) {
11999 PackageParser.ActivityIntentInfo[] array =
12000 new PackageParser.ActivityIntentInfo[intentFilters.size()];
12001 intentFilters.toArray(array);
12002 listCut.add(array);
12005 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12009 * Finds a privileged activity that matches the specified activity names.
12011 private PackageParser.Activity findMatchingActivity(
12012 List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
12013 for (PackageParser.Activity sysActivity : activityList) {
12014 if (sysActivity.info.name.equals(activityInfo.name)) {
12015 return sysActivity;
12017 if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
12018 return sysActivity;
12020 if (sysActivity.info.targetActivity != null) {
12021 if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
12022 return sysActivity;
12024 if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
12025 return sysActivity;
12032 public class IterGenerator<E> {
12033 public Iterator<E> generate(ActivityIntentInfo info) {
12038 public class ActionIterGenerator extends IterGenerator<String> {
12040 public Iterator<String> generate(ActivityIntentInfo info) {
12041 return info.actionsIterator();
12045 public class CategoriesIterGenerator extends IterGenerator<String> {
12047 public Iterator<String> generate(ActivityIntentInfo info) {
12048 return info.categoriesIterator();
12052 public class SchemesIterGenerator extends IterGenerator<String> {
12054 public Iterator<String> generate(ActivityIntentInfo info) {
12055 return info.schemesIterator();
12059 public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
12061 public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
12062 return info.authoritiesIterator();
12067 * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
12068 * MODIFIED. Do not pass in a list that should not be changed.
12070 private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
12071 IterGenerator<T> generator, Iterator<T> searchIterator) {
12072 // loop through the set of actions; every one must be found in the intent filter
12073 while (searchIterator.hasNext()) {
12074 // we must have at least one filter in the list to consider a match
12075 if (intentList.size() == 0) {
12079 final T searchAction = searchIterator.next();
12081 // loop through the set of intent filters
12082 final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
12083 while (intentIter.hasNext()) {
12084 final ActivityIntentInfo intentInfo = intentIter.next();
12085 boolean selectionFound = false;
12087 // loop through the intent filter's selection criteria; at least one
12088 // of them must match the searched criteria
12089 final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
12090 while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
12091 final T intentSelection = intentSelectionIter.next();
12092 if (intentSelection != null && intentSelection.equals(searchAction)) {
12093 selectionFound = true;
12098 // the selection criteria wasn't found in this filter's set; this filter
12099 // is not a potential match
12100 if (!selectionFound) {
12101 intentIter.remove();
12107 private boolean isProtectedAction(ActivityIntentInfo filter) {
12108 final Iterator<String> actionsIter = filter.actionsIterator();
12109 while (actionsIter != null && actionsIter.hasNext()) {
12110 final String filterAction = actionsIter.next();
12111 if (PROTECTED_ACTIONS.contains(filterAction)) {
12119 * Adjusts the priority of the given intent filter according to policy.
12122 * <li>The priority for non privileged applications is capped to '0'</li>
12123 * <li>The priority for protected actions on privileged applications is capped to '0'</li>
12124 * <li>The priority for unbundled updates to privileged applications is capped to the
12125 * priority defined on the system partition</li>
12128 * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
12129 * allowed to obtain any priority on any action.
12131 private void adjustPriority(
12132 List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
12133 // nothing to do; priority is fine as-is
12134 if (intent.getPriority() <= 0) {
12138 final ActivityInfo activityInfo = intent.activity.info;
12139 final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
12141 final boolean privilegedApp =
12142 ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
12143 if (!privilegedApp) {
12144 // non-privileged applications can never define a priority >0
12145 Slog.w(TAG, "Non-privileged app; cap priority to 0;"
12146 + " package: " + applicationInfo.packageName
12147 + " activity: " + intent.activity.className
12148 + " origPrio: " + intent.getPriority());
12149 intent.setPriority(0);
12153 if (systemActivities == null) {
12154 // the system package is not disabled; we're parsing the system partition
12155 if (isProtectedAction(intent)) {
12156 if (mDeferProtectedFilters) {
12157 // We can't deal with these just yet. No component should ever obtain a
12158 // >0 priority for a protected actions, with ONE exception -- the setup
12159 // wizard. The setup wizard, however, cannot be known until we're able to
12160 // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
12161 // until all intent filters have been processed. Chicken, meet egg.
12162 // Let the filter temporarily have a high priority and rectify the
12163 // priorities after all system packages have been scanned.
12164 mProtectedFilters.add(intent);
12165 if (DEBUG_FILTERS) {
12166 Slog.i(TAG, "Protected action; save for later;"
12167 + " package: " + applicationInfo.packageName
12168 + " activity: " + intent.activity.className
12169 + " origPrio: " + intent.getPriority());
12173 if (DEBUG_FILTERS && mSetupWizardPackage == null) {
12174 Slog.i(TAG, "No setup wizard;"
12175 + " All protected intents capped to priority 0");
12177 if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
12178 if (DEBUG_FILTERS) {
12179 Slog.i(TAG, "Found setup wizard;"
12180 + " allow priority " + intent.getPriority() + ";"
12181 + " package: " + intent.activity.info.packageName
12182 + " activity: " + intent.activity.className
12183 + " priority: " + intent.getPriority());
12185 // setup wizard gets whatever it wants
12188 Slog.w(TAG, "Protected action; cap priority to 0;"
12189 + " package: " + intent.activity.info.packageName
12190 + " activity: " + intent.activity.className
12191 + " origPrio: " + intent.getPriority());
12192 intent.setPriority(0);
12196 // privileged apps on the system image get whatever priority they request
12200 // privileged app unbundled update ... try to find the same activity
12201 final PackageParser.Activity foundActivity =
12202 findMatchingActivity(systemActivities, activityInfo);
12203 if (foundActivity == null) {
12204 // this is a new activity; it cannot obtain >0 priority
12205 if (DEBUG_FILTERS) {
12206 Slog.i(TAG, "New activity; cap priority to 0;"
12207 + " package: " + applicationInfo.packageName
12208 + " activity: " + intent.activity.className
12209 + " origPrio: " + intent.getPriority());
12211 intent.setPriority(0);
12215 // found activity, now check for filter equivalence
12217 // a shallow copy is enough; we modify the list, not its contents
12218 final List<ActivityIntentInfo> intentListCopy =
12219 new ArrayList<>(foundActivity.intents);
12220 final List<ActivityIntentInfo> foundFilters = findFilters(intent);
12222 // find matching action subsets
12223 final Iterator<String> actionsIterator = intent.actionsIterator();
12224 if (actionsIterator != null) {
12225 getIntentListSubset(
12226 intentListCopy, new ActionIterGenerator(), actionsIterator);
12227 if (intentListCopy.size() == 0) {
12228 // no more intents to match; we're not equivalent
12229 if (DEBUG_FILTERS) {
12230 Slog.i(TAG, "Mismatched action; cap priority to 0;"
12231 + " package: " + applicationInfo.packageName
12232 + " activity: " + intent.activity.className
12233 + " origPrio: " + intent.getPriority());
12235 intent.setPriority(0);
12240 // find matching category subsets
12241 final Iterator<String> categoriesIterator = intent.categoriesIterator();
12242 if (categoriesIterator != null) {
12243 getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
12244 categoriesIterator);
12245 if (intentListCopy.size() == 0) {
12246 // no more intents to match; we're not equivalent
12247 if (DEBUG_FILTERS) {
12248 Slog.i(TAG, "Mismatched category; cap priority to 0;"
12249 + " package: " + applicationInfo.packageName
12250 + " activity: " + intent.activity.className
12251 + " origPrio: " + intent.getPriority());
12253 intent.setPriority(0);
12258 // find matching schemes subsets
12259 final Iterator<String> schemesIterator = intent.schemesIterator();
12260 if (schemesIterator != null) {
12261 getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
12263 if (intentListCopy.size() == 0) {
12264 // no more intents to match; we're not equivalent
12265 if (DEBUG_FILTERS) {
12266 Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
12267 + " package: " + applicationInfo.packageName
12268 + " activity: " + intent.activity.className
12269 + " origPrio: " + intent.getPriority());
12271 intent.setPriority(0);
12276 // find matching authorities subsets
12277 final Iterator<IntentFilter.AuthorityEntry>
12278 authoritiesIterator = intent.authoritiesIterator();
12279 if (authoritiesIterator != null) {
12280 getIntentListSubset(intentListCopy,
12281 new AuthoritiesIterGenerator(),
12282 authoritiesIterator);
12283 if (intentListCopy.size() == 0) {
12284 // no more intents to match; we're not equivalent
12285 if (DEBUG_FILTERS) {
12286 Slog.i(TAG, "Mismatched authority; cap priority to 0;"
12287 + " package: " + applicationInfo.packageName
12288 + " activity: " + intent.activity.className
12289 + " origPrio: " + intent.getPriority());
12291 intent.setPriority(0);
12296 // we found matching filter(s); app gets the max priority of all intents
12297 int cappedPriority = 0;
12298 for (int i = intentListCopy.size() - 1; i >= 0; --i) {
12299 cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
12301 if (intent.getPriority() > cappedPriority) {
12302 if (DEBUG_FILTERS) {
12303 Slog.i(TAG, "Found matching filter(s);"
12304 + " cap priority to " + cappedPriority + ";"
12305 + " package: " + applicationInfo.packageName
12306 + " activity: " + intent.activity.className
12307 + " origPrio: " + intent.getPriority());
12309 intent.setPriority(cappedPriority);
12312 // all this for nothing; the requested priority was <= what was on the system
12315 public final void addActivity(PackageParser.Activity a, String type) {
12316 mActivities.put(a.getComponentName(), a);
12317 if (DEBUG_SHOW_INFO)
12319 TAG, " " + type + " " +
12320 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
12321 if (DEBUG_SHOW_INFO)
12322 Log.v(TAG, " Class=" + a.info.name);
12323 final int NI = a.intents.size();
12324 for (int j=0; j<NI; j++) {
12325 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12326 if ("activity".equals(type)) {
12327 final PackageSetting ps =
12328 mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
12329 final List<PackageParser.Activity> systemActivities =
12330 ps != null && ps.pkg != null ? ps.pkg.activities : null;
12331 adjustPriority(systemActivities, intent);
12333 if (DEBUG_SHOW_INFO) {
12334 Log.v(TAG, " IntentFilter:");
12335 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
12337 if (!intent.debugCheck()) {
12338 Log.w(TAG, "==> For Activity " + a.info.name);
12344 public final void removeActivity(PackageParser.Activity a, String type) {
12345 mActivities.remove(a.getComponentName());
12346 if (DEBUG_SHOW_INFO) {
12347 Log.v(TAG, " " + type + " "
12348 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
12349 : a.info.name) + ":");
12350 Log.v(TAG, " Class=" + a.info.name);
12352 final int NI = a.intents.size();
12353 for (int j=0; j<NI; j++) {
12354 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12355 if (DEBUG_SHOW_INFO) {
12356 Log.v(TAG, " IntentFilter:");
12357 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
12359 removeFilter(intent);
12364 protected boolean allowFilterResult(
12365 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
12366 ActivityInfo filterAi = filter.activity.info;
12367 for (int i=dest.size()-1; i>=0; i--) {
12368 ActivityInfo destAi = dest.get(i).activityInfo;
12369 if (destAi.name == filterAi.name
12370 && destAi.packageName == filterAi.packageName) {
12378 protected ActivityIntentInfo[] newArray(int size) {
12379 return new ActivityIntentInfo[size];
12383 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
12384 if (!sUserManager.exists(userId)) return true;
12385 PackageParser.Package p = filter.activity.owner;
12387 PackageSetting ps = (PackageSetting)p.mExtras;
12389 // System apps are never considered stopped for purposes of
12390 // filtering, because there may be no way for the user to
12391 // actually re-launch them.
12392 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
12393 && ps.getStopped(userId);
12400 protected boolean isPackageForFilter(String packageName,
12401 PackageParser.ActivityIntentInfo info) {
12402 return packageName.equals(info.activity.owner.packageName);
12406 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
12407 int match, int userId) {
12408 if (!sUserManager.exists(userId)) return null;
12409 if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
12412 final PackageParser.Activity activity = info.activity;
12413 PackageSetting ps = (PackageSetting) activity.owner.mExtras;
12417 final PackageUserState userState = ps.readUserState(userId);
12418 ActivityInfo ai = generateActivityInfo(activity, mFlags, userState, userId);
12422 final boolean matchVisibleToInstantApp =
12423 (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12424 final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12425 // throw out filters that aren't visible to ephemeral apps
12426 if (matchVisibleToInstantApp
12427 && !(info.isVisibleToInstantApp() || userState.instantApp)) {
12430 // throw out ephemeral filters if we're not explicitly requesting them
12431 if (!isInstantApp && userState.instantApp) {
12434 // throw out instant app filters if updates are available; will trigger
12435 // instant app resolution
12436 if (userState.instantApp && ps.isUpdateAvailable()) {
12439 final ResolveInfo res = new ResolveInfo();
12440 res.activityInfo = ai;
12441 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12444 if (info != null) {
12445 res.handleAllWebDataURI = info.handleAllWebDataURI();
12447 res.priority = info.getPriority();
12448 res.preferredOrder = activity.owner.mPreferredOrder;
12449 //System.out.println("Result: " + res.activityInfo.className +
12450 // " = " + res.priority);
12452 res.isDefault = info.hasDefault;
12453 res.labelRes = info.labelRes;
12454 res.nonLocalizedLabel = info.nonLocalizedLabel;
12455 if (userNeedsBadging(userId)) {
12456 res.noResourceId = true;
12458 res.icon = info.icon;
12460 res.iconResourceId = info.icon;
12461 res.system = res.activityInfo.applicationInfo.isSystemApp();
12462 res.instantAppAvailable = userState.instantApp;
12467 protected void sortResults(List<ResolveInfo> results) {
12468 Collections.sort(results, mResolvePrioritySorter);
12472 protected void dumpFilter(PrintWriter out, String prefix,
12473 PackageParser.ActivityIntentInfo filter) {
12474 out.print(prefix); out.print(
12475 Integer.toHexString(System.identityHashCode(filter.activity)));
12477 filter.activity.printComponentShortName(out);
12478 out.print(" filter ");
12479 out.println(Integer.toHexString(System.identityHashCode(filter)));
12483 protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
12484 return filter.activity;
12487 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12488 PackageParser.Activity activity = (PackageParser.Activity)label;
12489 out.print(prefix); out.print(
12490 Integer.toHexString(System.identityHashCode(activity)));
12492 activity.printComponentShortName(out);
12494 out.print(" ("); out.print(count); out.print(" filters)");
12499 // Keys are String (activity class name), values are Activity.
12500 private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
12501 = new ArrayMap<ComponentName, PackageParser.Activity>();
12502 private int mFlags;
12505 private final class ServiceIntentResolver
12506 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
12507 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12508 boolean defaultOnly, int userId) {
12509 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
12510 return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12513 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12515 if (!sUserManager.exists(userId)) return null;
12517 return super.queryIntent(intent, resolvedType,
12518 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12522 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12523 int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
12524 if (!sUserManager.exists(userId)) return null;
12525 if (packageServices == null) {
12529 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
12530 final int N = packageServices.size();
12531 ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
12532 new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
12534 ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
12535 for (int i = 0; i < N; ++i) {
12536 intentFilters = packageServices.get(i).intents;
12537 if (intentFilters != null && intentFilters.size() > 0) {
12538 PackageParser.ServiceIntentInfo[] array =
12539 new PackageParser.ServiceIntentInfo[intentFilters.size()];
12540 intentFilters.toArray(array);
12541 listCut.add(array);
12544 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12547 public final void addService(PackageParser.Service s) {
12548 mServices.put(s.getComponentName(), s);
12549 if (DEBUG_SHOW_INFO) {
12551 + (s.info.nonLocalizedLabel != null
12552 ? s.info.nonLocalizedLabel : s.info.name) + ":");
12553 Log.v(TAG, " Class=" + s.info.name);
12555 final int NI = s.intents.size();
12557 for (j=0; j<NI; j++) {
12558 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12559 if (DEBUG_SHOW_INFO) {
12560 Log.v(TAG, " IntentFilter:");
12561 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
12563 if (!intent.debugCheck()) {
12564 Log.w(TAG, "==> For Service " + s.info.name);
12570 public final void removeService(PackageParser.Service s) {
12571 mServices.remove(s.getComponentName());
12572 if (DEBUG_SHOW_INFO) {
12573 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null
12574 ? s.info.nonLocalizedLabel : s.info.name) + ":");
12575 Log.v(TAG, " Class=" + s.info.name);
12577 final int NI = s.intents.size();
12579 for (j=0; j<NI; j++) {
12580 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12581 if (DEBUG_SHOW_INFO) {
12582 Log.v(TAG, " IntentFilter:");
12583 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
12585 removeFilter(intent);
12590 protected boolean allowFilterResult(
12591 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
12592 ServiceInfo filterSi = filter.service.info;
12593 for (int i=dest.size()-1; i>=0; i--) {
12594 ServiceInfo destAi = dest.get(i).serviceInfo;
12595 if (destAi.name == filterSi.name
12596 && destAi.packageName == filterSi.packageName) {
12604 protected PackageParser.ServiceIntentInfo[] newArray(int size) {
12605 return new PackageParser.ServiceIntentInfo[size];
12609 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
12610 if (!sUserManager.exists(userId)) return true;
12611 PackageParser.Package p = filter.service.owner;
12613 PackageSetting ps = (PackageSetting)p.mExtras;
12615 // System apps are never considered stopped for purposes of
12616 // filtering, because there may be no way for the user to
12617 // actually re-launch them.
12618 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
12619 && ps.getStopped(userId);
12626 protected boolean isPackageForFilter(String packageName,
12627 PackageParser.ServiceIntentInfo info) {
12628 return packageName.equals(info.service.owner.packageName);
12632 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
12633 int match, int userId) {
12634 if (!sUserManager.exists(userId)) return null;
12635 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
12636 if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
12639 final PackageParser.Service service = info.service;
12640 PackageSetting ps = (PackageSetting) service.owner.mExtras;
12644 final PackageUserState userState = ps.readUserState(userId);
12645 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
12646 userState, userId);
12650 final boolean matchVisibleToInstantApp =
12651 (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12652 final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12653 // throw out filters that aren't visible to ephemeral apps
12654 if (matchVisibleToInstantApp
12655 && !(info.isVisibleToInstantApp() || userState.instantApp)) {
12658 // throw out ephemeral filters if we're not explicitly requesting them
12659 if (!isInstantApp && userState.instantApp) {
12662 // throw out instant app filters if updates are available; will trigger
12663 // instant app resolution
12664 if (userState.instantApp && ps.isUpdateAvailable()) {
12667 final ResolveInfo res = new ResolveInfo();
12668 res.serviceInfo = si;
12669 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12670 res.filter = filter;
12672 res.priority = info.getPriority();
12673 res.preferredOrder = service.owner.mPreferredOrder;
12675 res.isDefault = info.hasDefault;
12676 res.labelRes = info.labelRes;
12677 res.nonLocalizedLabel = info.nonLocalizedLabel;
12678 res.icon = info.icon;
12679 res.system = res.serviceInfo.applicationInfo.isSystemApp();
12684 protected void sortResults(List<ResolveInfo> results) {
12685 Collections.sort(results, mResolvePrioritySorter);
12689 protected void dumpFilter(PrintWriter out, String prefix,
12690 PackageParser.ServiceIntentInfo filter) {
12691 out.print(prefix); out.print(
12692 Integer.toHexString(System.identityHashCode(filter.service)));
12694 filter.service.printComponentShortName(out);
12695 out.print(" filter ");
12696 out.println(Integer.toHexString(System.identityHashCode(filter)));
12700 protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
12701 return filter.service;
12704 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12705 PackageParser.Service service = (PackageParser.Service)label;
12706 out.print(prefix); out.print(
12707 Integer.toHexString(System.identityHashCode(service)));
12709 service.printComponentShortName(out);
12711 out.print(" ("); out.print(count); out.print(" filters)");
12716 // List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
12717 // final Iterator<ResolveInfo> i = resolveInfoList.iterator();
12718 // final List<ResolveInfo> retList = Lists.newArrayList();
12719 // while (i.hasNext()) {
12720 // final ResolveInfo resolveInfo = (ResolveInfo) i;
12721 // if (isEnabledLP(resolveInfo.serviceInfo)) {
12722 // retList.add(resolveInfo);
12728 // Keys are String (activity class name), values are Activity.
12729 private final ArrayMap<ComponentName, PackageParser.Service> mServices
12730 = new ArrayMap<ComponentName, PackageParser.Service>();
12731 private int mFlags;
12734 private final class ProviderIntentResolver
12735 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
12736 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12737 boolean defaultOnly, int userId) {
12738 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
12739 return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12742 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12744 if (!sUserManager.exists(userId))
12747 return super.queryIntent(intent, resolvedType,
12748 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12752 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12753 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
12754 if (!sUserManager.exists(userId))
12756 if (packageProviders == null) {
12760 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
12761 final int N = packageProviders.size();
12762 ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
12763 new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
12765 ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
12766 for (int i = 0; i < N; ++i) {
12767 intentFilters = packageProviders.get(i).intents;
12768 if (intentFilters != null && intentFilters.size() > 0) {
12769 PackageParser.ProviderIntentInfo[] array =
12770 new PackageParser.ProviderIntentInfo[intentFilters.size()];
12771 intentFilters.toArray(array);
12772 listCut.add(array);
12775 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12778 public final void addProvider(PackageParser.Provider p) {
12779 if (mProviders.containsKey(p.getComponentName())) {
12780 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
12784 mProviders.put(p.getComponentName(), p);
12785 if (DEBUG_SHOW_INFO) {
12787 + (p.info.nonLocalizedLabel != null
12788 ? p.info.nonLocalizedLabel : p.info.name) + ":");
12789 Log.v(TAG, " Class=" + p.info.name);
12791 final int NI = p.intents.size();
12793 for (j = 0; j < NI; j++) {
12794 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
12795 if (DEBUG_SHOW_INFO) {
12796 Log.v(TAG, " IntentFilter:");
12797 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
12799 if (!intent.debugCheck()) {
12800 Log.w(TAG, "==> For Provider " + p.info.name);
12806 public final void removeProvider(PackageParser.Provider p) {
12807 mProviders.remove(p.getComponentName());
12808 if (DEBUG_SHOW_INFO) {
12809 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null
12810 ? p.info.nonLocalizedLabel : p.info.name) + ":");
12811 Log.v(TAG, " Class=" + p.info.name);
12813 final int NI = p.intents.size();
12815 for (j = 0; j < NI; j++) {
12816 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
12817 if (DEBUG_SHOW_INFO) {
12818 Log.v(TAG, " IntentFilter:");
12819 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
12821 removeFilter(intent);
12826 protected boolean allowFilterResult(
12827 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
12828 ProviderInfo filterPi = filter.provider.info;
12829 for (int i = dest.size() - 1; i >= 0; i--) {
12830 ProviderInfo destPi = dest.get(i).providerInfo;
12831 if (destPi.name == filterPi.name
12832 && destPi.packageName == filterPi.packageName) {
12840 protected PackageParser.ProviderIntentInfo[] newArray(int size) {
12841 return new PackageParser.ProviderIntentInfo[size];
12845 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
12846 if (!sUserManager.exists(userId))
12848 PackageParser.Package p = filter.provider.owner;
12850 PackageSetting ps = (PackageSetting) p.mExtras;
12852 // System apps are never considered stopped for purposes of
12853 // filtering, because there may be no way for the user to
12854 // actually re-launch them.
12855 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
12856 && ps.getStopped(userId);
12863 protected boolean isPackageForFilter(String packageName,
12864 PackageParser.ProviderIntentInfo info) {
12865 return packageName.equals(info.provider.owner.packageName);
12869 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
12870 int match, int userId) {
12871 if (!sUserManager.exists(userId))
12873 final PackageParser.ProviderIntentInfo info = filter;
12874 if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
12877 final PackageParser.Provider provider = info.provider;
12878 PackageSetting ps = (PackageSetting) provider.owner.mExtras;
12882 final PackageUserState userState = ps.readUserState(userId);
12883 final boolean matchVisibleToInstantApp =
12884 (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12885 final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12886 // throw out filters that aren't visible to instant applications
12887 if (matchVisibleToInstantApp
12888 && !(info.isVisibleToInstantApp() || userState.instantApp)) {
12891 // throw out instant application filters if we're not explicitly requesting them
12892 if (!isInstantApp && userState.instantApp) {
12895 // throw out instant application filters if updates are available; will trigger
12896 // instant application resolution
12897 if (userState.instantApp && ps.isUpdateAvailable()) {
12900 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
12901 userState, userId);
12905 final ResolveInfo res = new ResolveInfo();
12906 res.providerInfo = pi;
12907 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
12908 res.filter = filter;
12910 res.priority = info.getPriority();
12911 res.preferredOrder = provider.owner.mPreferredOrder;
12913 res.isDefault = info.hasDefault;
12914 res.labelRes = info.labelRes;
12915 res.nonLocalizedLabel = info.nonLocalizedLabel;
12916 res.icon = info.icon;
12917 res.system = res.providerInfo.applicationInfo.isSystemApp();
12922 protected void sortResults(List<ResolveInfo> results) {
12923 Collections.sort(results, mResolvePrioritySorter);
12927 protected void dumpFilter(PrintWriter out, String prefix,
12928 PackageParser.ProviderIntentInfo filter) {
12931 Integer.toHexString(System.identityHashCode(filter.provider)));
12933 filter.provider.printComponentShortName(out);
12934 out.print(" filter ");
12935 out.println(Integer.toHexString(System.identityHashCode(filter)));
12939 protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
12940 return filter.provider;
12943 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12944 PackageParser.Provider provider = (PackageParser.Provider)label;
12945 out.print(prefix); out.print(
12946 Integer.toHexString(System.identityHashCode(provider)));
12948 provider.printComponentShortName(out);
12950 out.print(" ("); out.print(count); out.print(" filters)");
12955 private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
12956 = new ArrayMap<ComponentName, PackageParser.Provider>();
12957 private int mFlags;
12960 static final class EphemeralIntentResolver
12961 extends IntentResolver<AuxiliaryResolveInfo, AuxiliaryResolveInfo> {
12963 * The result that has the highest defined order. Ordering applies on a
12964 * per-package basis. Mapping is from package name to Pair of order and
12965 * EphemeralResolveInfo.
12967 * NOTE: This is implemented as a field variable for convenience and efficiency.
12968 * By having a field variable, we're able to track filter ordering as soon as
12969 * a non-zero order is defined. Otherwise, multiple loops across the result set
12970 * would be needed to apply ordering. If the intent resolver becomes re-entrant,
12971 * this needs to be contained entirely within {@link #filterResults}.
12973 final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
12976 protected AuxiliaryResolveInfo[] newArray(int size) {
12977 return new AuxiliaryResolveInfo[size];
12981 protected boolean isPackageForFilter(String packageName, AuxiliaryResolveInfo responseObj) {
12986 protected AuxiliaryResolveInfo newResult(AuxiliaryResolveInfo responseObj, int match,
12988 if (!sUserManager.exists(userId)) {
12991 final String packageName = responseObj.resolveInfo.getPackageName();
12992 final Integer order = responseObj.getOrder();
12993 final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
12994 mOrderResult.get(packageName);
12995 // ordering is enabled and this item's order isn't high enough
12996 if (lastOrderResult != null && lastOrderResult.first >= order) {
12999 final InstantAppResolveInfo res = responseObj.resolveInfo;
13001 // non-zero order, enable ordering
13002 mOrderResult.put(packageName, new Pair<>(order, res));
13004 return responseObj;
13008 protected void filterResults(List<AuxiliaryResolveInfo> results) {
13009 // only do work if ordering is enabled [most of the time it won't be]
13010 if (mOrderResult.size() == 0) {
13013 int resultSize = results.size();
13014 for (int i = 0; i < resultSize; i++) {
13015 final InstantAppResolveInfo info = results.get(i).resolveInfo;
13016 final String packageName = info.getPackageName();
13017 final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName);
13018 if (savedInfo == null) {
13019 // package doesn't having ordering
13022 if (savedInfo.second == info) {
13023 // circled back to the highest ordered item; remove from order list
13024 mOrderResult.remove(savedInfo);
13025 if (mOrderResult.size() == 0) {
13026 // no more ordered items
13031 // item has a worse order, remove it from the result list
13039 private static final Comparator<ResolveInfo> mResolvePrioritySorter =
13040 new Comparator<ResolveInfo>() {
13041 public int compare(ResolveInfo r1, ResolveInfo r2) {
13042 int v1 = r1.priority;
13043 int v2 = r2.priority;
13044 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
13046 return (v1 > v2) ? -1 : 1;
13048 v1 = r1.preferredOrder;
13049 v2 = r2.preferredOrder;
13051 return (v1 > v2) ? -1 : 1;
13053 if (r1.isDefault != r2.isDefault) {
13054 return r1.isDefault ? -1 : 1;
13058 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
13060 return (v1 > v2) ? -1 : 1;
13062 if (r1.system != r2.system) {
13063 return r1.system ? -1 : 1;
13065 if (r1.activityInfo != null) {
13066 return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
13068 if (r1.serviceInfo != null) {
13069 return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
13071 if (r1.providerInfo != null) {
13072 return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
13078 private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
13079 new Comparator<ProviderInfo>() {
13080 public int compare(ProviderInfo p1, ProviderInfo p2) {
13081 final int v1 = p1.initOrder;
13082 final int v2 = p2.initOrder;
13083 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
13087 public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
13088 final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
13089 final int[] userIds) {
13090 mHandler.post(new Runnable() {
13092 public void run() {
13094 final IActivityManager am = ActivityManager.getService();
13095 if (am == null) return;
13096 final int[] resolvedUserIds;
13097 if (userIds == null) {
13098 resolvedUserIds = am.getRunningUserIds();
13100 resolvedUserIds = userIds;
13102 for (int id : resolvedUserIds) {
13103 final Intent intent = new Intent(action,
13104 pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
13105 if (extras != null) {
13106 intent.putExtras(extras);
13108 if (targetPkg != null) {
13109 intent.setPackage(targetPkg);
13111 // Modify the UID when posting to other users
13112 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
13113 if (uid > 0 && UserHandle.getUserId(uid) != id) {
13114 uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
13115 intent.putExtra(Intent.EXTRA_UID, uid);
13117 intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
13118 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
13119 if (DEBUG_BROADCASTS) {
13120 RuntimeException here = new RuntimeException("here");
13121 here.fillInStackTrace();
13122 Slog.d(TAG, "Sending to user " + id + ": "
13123 + intent.toShortString(false, true, false, false)
13124 + " " + intent.getExtras(), here);
13126 am.broadcastIntent(null, intent, null, finishedReceiver,
13127 0, null, null, null, android.app.AppOpsManager.OP_NONE,
13128 null, finishedReceiver != null, false, id);
13130 } catch (RemoteException ex) {
13137 * Check if the external storage media is available. This is true if there
13138 * is a mounted external storage medium or if the external storage is
13141 private boolean isExternalMediaAvailable() {
13142 return mMediaMounted || Environment.isExternalStorageEmulated();
13146 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
13148 synchronized (mPackages) {
13149 if (!isExternalMediaAvailable()) {
13150 // If the external storage is no longer mounted at this point,
13151 // the caller may not have been able to delete all of this
13152 // packages files and can not delete any more. Bail.
13155 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
13156 if (lastPackage != null) {
13157 pkgs.remove(lastPackage);
13159 if (pkgs.size() > 0) {
13160 return pkgs.get(0);
13166 void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
13167 final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
13168 userId, andCode ? 1 : 0, packageName);
13169 if (mSystemReady) {
13170 msg.sendToTarget();
13172 if (mPostSystemReadyMessages == null) {
13173 mPostSystemReadyMessages = new ArrayList<>();
13175 mPostSystemReadyMessages.add(msg);
13179 void startCleaningPackages() {
13181 if (!isExternalMediaAvailable()) {
13184 synchronized (mPackages) {
13185 if (mSettings.mPackagesToBeCleaned.isEmpty()) {
13189 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
13190 intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
13191 IActivityManager am = ActivityManager.getService();
13194 synchronized (mPackages) {
13195 if (!mDefaultContainerWhitelisted) {
13196 mDefaultContainerWhitelisted = true;
13197 PackageSetting ps = mSettings.mPackages.get(DEFAULT_CONTAINER_PACKAGE);
13198 dcsUid = UserHandle.getUid(UserHandle.USER_SYSTEM, ps.appId);
13203 am.backgroundWhitelistUid(dcsUid);
13205 am.startService(null, intent, null, -1, null, false, mContext.getOpPackageName(),
13206 UserHandle.USER_SYSTEM);
13207 } catch (RemoteException e) {
13213 public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
13214 int installFlags, String installerPackageName, int userId) {
13215 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
13217 final int callingUid = Binder.getCallingUid();
13218 enforceCrossUserPermission(callingUid, userId,
13219 true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");
13221 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
13223 if (observer != null) {
13224 observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
13226 } catch (RemoteException re) {
13231 if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
13232 installFlags |= PackageManager.INSTALL_FROM_ADB;
13235 // Caller holds INSTALL_PACKAGES permission, so we're less strict
13236 // about installerPackageName.
13238 installFlags &= ~PackageManager.INSTALL_FROM_ADB;
13239 installFlags &= ~PackageManager.INSTALL_ALL_USERS;
13243 if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
13244 user = UserHandle.ALL;
13246 user = new UserHandle(userId);
13249 // Only system components can circumvent runtime permissions when installing.
13250 if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
13251 && mContext.checkCallingOrSelfPermission(Manifest.permission
13252 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
13253 throw new SecurityException("You need the "
13254 + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
13255 + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
13258 if ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0
13259 || (installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
13260 throw new IllegalArgumentException(
13261 "New installs into ASEC containers no longer supported");
13264 final File originFile = new File(originPath);
13265 final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
13267 final Message msg = mHandler.obtainMessage(INIT_COPY);
13268 final VerificationInfo verificationInfo = new VerificationInfo(
13269 null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);
13270 final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,
13271 installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,
13272 null /*packageAbiOverride*/, null /*grantedPermissions*/,
13273 null /*certificates*/, PackageManager.INSTALL_REASON_UNKNOWN);
13274 params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
13277 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
13278 System.identityHashCode(msg.obj));
13279 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
13280 System.identityHashCode(msg.obj));
13282 mHandler.sendMessage(msg);
13287 * Ensure that the install reason matches what we know about the package installer (e.g. whether
13288 * it is acting on behalf on an enterprise or the user).
13290 * Note that the ordering of the conditionals in this method is important. The checks we perform
13291 * are as follows, in this order:
13293 * 1) If the install is being performed by a system app, we can trust the app to have set the
13294 * install reason correctly. Thus, we pass through the install reason unchanged, no matter
13296 * 2) If the install is being performed by a device or profile owner app, the install reason
13297 * should be enterprise policy. However, we cannot be sure that the device or profile owner
13298 * set the install reason correctly. If the app targets an older SDK version where install
13299 * reasons did not exist yet, or if the app author simply forgot, the install reason may be
13300 * unset or wrong. Thus, we force the install reason to be enterprise policy.
13301 * 3) In all other cases, the install is being performed by a regular app that is neither part
13302 * of the system nor a device or profile owner. We have no reason to believe that this app is
13303 * acting on behalf of the enterprise admin. Thus, we check whether the install reason was
13304 * set to enterprise policy and if so, change it to unknown instead.
13306 private int fixUpInstallReason(String installerPackageName, int installerUid,
13307 int installReason) {
13308 if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
13309 == PERMISSION_GRANTED) {
13310 // If the install is being performed by a system app, we trust that app to have set the
13311 // install reason correctly.
13312 return installReason;
13315 final IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
13316 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
13318 ComponentName owner = null;
13320 owner = dpm.getDeviceOwnerComponent(true /* callingUserOnly */);
13321 if (owner == null) {
13322 owner = dpm.getProfileOwner(UserHandle.getUserId(installerUid));
13324 } catch (RemoteException e) {
13326 if (owner != null && owner.getPackageName().equals(installerPackageName)) {
13327 // If the install is being performed by a device or profile owner, the install
13328 // reason should be enterprise policy.
13329 return PackageManager.INSTALL_REASON_POLICY;
13333 if (installReason == PackageManager.INSTALL_REASON_POLICY) {
13334 // If the install is being performed by a regular app (i.e. neither system app nor
13335 // device or profile owner), we have no reason to believe that the app is acting on
13336 // behalf of an enterprise. If the app set the install reason to enterprise policy,
13337 // change it to unknown instead.
13338 return PackageManager.INSTALL_REASON_UNKNOWN;
13341 // If the install is being performed by a regular app and the install reason was set to any
13342 // value but enterprise policy, leave the install reason unchanged.
13343 return installReason;
13346 void installStage(String packageName, File stagedDir, String stagedCid,
13347 IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
13348 String installerPackageName, int installerUid, UserHandle user,
13349 Certificate[][] certificates) {
13350 if (DEBUG_EPHEMERAL) {
13351 if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
13352 Slog.d(TAG, "Ephemeral install of " + packageName);
13355 final VerificationInfo verificationInfo = new VerificationInfo(
13356 sessionParams.originatingUri, sessionParams.referrerUri,
13357 sessionParams.originatingUid, installerUid);
13359 final OriginInfo origin;
13360 if (stagedDir != null) {
13361 origin = OriginInfo.fromStagedFile(stagedDir);
13363 origin = OriginInfo.fromStagedContainer(stagedCid);
13366 final Message msg = mHandler.obtainMessage(INIT_COPY);
13367 final int installReason = fixUpInstallReason(installerPackageName, installerUid,
13368 sessionParams.installReason);
13369 final InstallParams params = new InstallParams(origin, null, observer,
13370 sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
13371 verificationInfo, user, sessionParams.abiOverride,
13372 sessionParams.grantedRuntimePermissions, certificates, installReason);
13373 params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
13376 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
13377 System.identityHashCode(msg.obj));
13378 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
13379 System.identityHashCode(msg.obj));
13381 mHandler.sendMessage(msg);
13384 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
13386 final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
13387 sendPackageAddedForNewUsers(packageName, isSystem, pkgSetting.appId, userId);
13390 public void sendPackageAddedForNewUsers(String packageName, boolean isSystem, int appId, int... userIds) {
13391 if (ArrayUtils.isEmpty(userIds)) {
13394 Bundle extras = new Bundle(1);
13395 // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
13396 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userIds[0], appId));
13398 sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_ADDED, packageName,
13399 extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, null, null, userIds);
13400 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
13401 extras, 0, null, null, userIds);
13403 mHandler.post(() -> {
13404 for (int userId : userIds) {
13405 sendBootCompletedBroadcastToSystemApp(packageName, userId);
13413 * The just-installed/enabled app is bundled on the system, so presumed to be able to run
13414 * automatically without needing an explicit launch.
13415 * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
13417 private void sendBootCompletedBroadcastToSystemApp(String packageName, int userId) {
13418 // If user is not running, the app didn't miss any broadcast
13419 if (!mUserManagerInternal.isUserRunning(userId)) {
13422 final IActivityManager am = ActivityManager.getService();
13424 // Deliver LOCKED_BOOT_COMPLETED first
13425 Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
13426 .setPackage(packageName);
13427 final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
13428 am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
13429 android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13431 // Deliver BOOT_COMPLETED only if user is unlocked
13432 if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
13433 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
13434 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
13435 android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13437 } catch (RemoteException e) {
13438 throw e.rethrowFromSystemServer();
13443 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
13445 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13446 PackageSetting pkgSetting;
13447 final int uid = Binder.getCallingUid();
13448 enforceCrossUserPermission(uid, userId,
13449 true /* requireFullPermission */, true /* checkShell */,
13450 "setApplicationHiddenSetting for user " + userId);
13452 if (hidden && isPackageDeviceAdmin(packageName, userId)) {
13453 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
13457 long callingId = Binder.clearCallingIdentity();
13459 boolean sendAdded = false;
13460 boolean sendRemoved = false;
13462 synchronized (mPackages) {
13463 pkgSetting = mSettings.mPackages.get(packageName);
13464 if (pkgSetting == null) {
13467 // Do not allow "android" is being disabled
13468 if ("android".equals(packageName)) {
13469 Slog.w(TAG, "Cannot hide package: android");
13472 // Cannot hide static shared libs as they are considered
13473 // a part of the using app (emulating static linking). Also
13474 // static libs are installed always on internal storage.
13475 PackageParser.Package pkg = mPackages.get(packageName);
13476 if (pkg != null && pkg.staticSharedLibName != null) {
13477 Slog.w(TAG, "Cannot hide package: " + packageName
13478 + " providing static shared library: "
13479 + pkg.staticSharedLibName);
13482 // Only allow protected packages to hide themselves.
13483 if (hidden && !UserHandle.isSameApp(uid, pkgSetting.appId)
13484 && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13485 Slog.w(TAG, "Not hiding protected package: " + packageName);
13489 if (pkgSetting.getHidden(userId) != hidden) {
13490 pkgSetting.setHidden(hidden, userId);
13491 mSettings.writePackageRestrictionsLPr(userId);
13493 sendRemoved = true;
13500 sendPackageAddedForUser(packageName, pkgSetting, userId);
13504 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
13506 sendApplicationHiddenForUser(packageName, pkgSetting, userId);
13510 Binder.restoreCallingIdentity(callingId);
13515 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
13517 final PackageRemovedInfo info = new PackageRemovedInfo(this);
13518 info.removedPackage = packageName;
13519 info.removedUsers = new int[] {userId};
13520 info.broadcastUsers = new int[] {userId};
13521 info.uid = UserHandle.getUid(userId, pkgSetting.appId);
13522 info.sendPackageRemovedBroadcasts(true /*killApp*/);
13525 private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
13526 if (pkgList.length > 0) {
13527 Bundle extras = new Bundle(1);
13528 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
13530 sendPackageBroadcast(
13531 suspended ? Intent.ACTION_PACKAGES_SUSPENDED
13532 : Intent.ACTION_PACKAGES_UNSUSPENDED,
13533 null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
13534 new int[] {userId});
13539 * Returns true if application is not found or there was an error. Otherwise it returns
13540 * the hidden state of the package for the given user.
13543 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
13544 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13545 enforceCrossUserPermission(Binder.getCallingUid(), userId,
13546 true /* requireFullPermission */, false /* checkShell */,
13547 "getApplicationHidden for user " + userId);
13548 PackageSetting pkgSetting;
13549 long callingId = Binder.clearCallingIdentity();
13552 synchronized (mPackages) {
13553 pkgSetting = mSettings.mPackages.get(packageName);
13554 if (pkgSetting == null) {
13557 return pkgSetting.getHidden(userId);
13560 Binder.restoreCallingIdentity(callingId);
13568 public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
13569 int installReason) {
13570 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
13572 PackageSetting pkgSetting;
13573 final int uid = Binder.getCallingUid();
13574 enforceCrossUserPermission(uid, userId,
13575 true /* requireFullPermission */, true /* checkShell */,
13576 "installExistingPackage for user " + userId);
13577 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
13578 return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
13581 long callingId = Binder.clearCallingIdentity();
13583 boolean installed = false;
13584 final boolean instantApp =
13585 (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
13586 final boolean fullApp =
13587 (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
13590 synchronized (mPackages) {
13591 pkgSetting = mSettings.mPackages.get(packageName);
13592 if (pkgSetting == null) {
13593 return PackageManager.INSTALL_FAILED_INVALID_URI;
13595 if (!pkgSetting.getInstalled(userId)) {
13596 pkgSetting.setInstalled(true, userId);
13597 pkgSetting.setHidden(false, userId);
13598 pkgSetting.setInstallReason(installReason, userId);
13599 mSettings.writePackageRestrictionsLPr(userId);
13600 mSettings.writeKernelMappingLPr(pkgSetting);
13602 } else if (fullApp && pkgSetting.getInstantApp(userId)) {
13603 // upgrade app from instant to full; we don't allow app downgrade
13606 setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
13610 if (pkgSetting.pkg != null) {
13611 synchronized (mInstallLock) {
13612 // We don't need to freeze for a brand new install
13613 prepareAppDataAfterInstallLIF(pkgSetting.pkg);
13616 sendPackageAddedForUser(packageName, pkgSetting, userId);
13617 synchronized (mPackages) {
13618 updateSequenceNumberLP(packageName, new int[]{ userId });
13622 Binder.restoreCallingIdentity(callingId);
13625 return PackageManager.INSTALL_SUCCEEDED;
13628 void setInstantAppForUser(PackageSetting pkgSetting, int userId,
13629 boolean instantApp, boolean fullApp) {
13630 // no state specified; do nothing
13631 if (!instantApp && !fullApp) {
13634 if (userId != UserHandle.USER_ALL) {
13635 if (instantApp && !pkgSetting.getInstantApp(userId)) {
13636 pkgSetting.setInstantApp(true /*instantApp*/, userId);
13637 } else if (fullApp && pkgSetting.getInstantApp(userId)) {
13638 pkgSetting.setInstantApp(false /*instantApp*/, userId);
13641 for (int currentUserId : sUserManager.getUserIds()) {
13642 if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
13643 pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
13644 } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
13645 pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
13651 boolean isUserRestricted(int userId, String restrictionKey) {
13652 Bundle restrictions = sUserManager.getUserRestrictions(userId);
13653 if (restrictions.getBoolean(restrictionKey, false)) {
13654 Log.w(TAG, "User is restricted: " + restrictionKey);
13661 public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
13663 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13664 enforceCrossUserPermission(Binder.getCallingUid(), userId,
13665 true /* requireFullPermission */, true /* checkShell */,
13666 "setPackagesSuspended for user " + userId);
13668 if (ArrayUtils.isEmpty(packageNames)) {
13669 return packageNames;
13672 // List of package names for whom the suspended state has changed.
13673 List<String> changedPackages = new ArrayList<>(packageNames.length);
13674 // List of package names for whom the suspended state is not set as requested in this
13676 List<String> unactionedPackages = new ArrayList<>(packageNames.length);
13677 long callingId = Binder.clearCallingIdentity();
13679 for (int i = 0; i < packageNames.length; i++) {
13680 String packageName = packageNames[i];
13681 boolean changed = false;
13683 synchronized (mPackages) {
13684 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
13685 if (pkgSetting == null) {
13686 Slog.w(TAG, "Could not find package setting for package \"" + packageName
13687 + "\". Skipping suspending/un-suspending.");
13688 unactionedPackages.add(packageName);
13691 appId = pkgSetting.appId;
13692 if (pkgSetting.getSuspended(userId) != suspended) {
13693 if (!canSuspendPackageForUserLocked(packageName, userId)) {
13694 unactionedPackages.add(packageName);
13697 pkgSetting.setSuspended(suspended, userId);
13698 mSettings.writePackageRestrictionsLPr(userId);
13700 changedPackages.add(packageName);
13704 if (changed && suspended) {
13705 killApplication(packageName, UserHandle.getUid(userId, appId),
13706 "suspending package");
13710 Binder.restoreCallingIdentity(callingId);
13713 if (!changedPackages.isEmpty()) {
13714 sendPackagesSuspendedForUser(changedPackages.toArray(
13715 new String[changedPackages.size()]), userId, suspended);
13718 return unactionedPackages.toArray(new String[unactionedPackages.size()]);
13722 public boolean isPackageSuspendedForUser(String packageName, int userId) {
13723 enforceCrossUserPermission(Binder.getCallingUid(), userId,
13724 true /* requireFullPermission */, false /* checkShell */,
13725 "isPackageSuspendedForUser for user " + userId);
13726 synchronized (mPackages) {
13727 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
13728 if (pkgSetting == null) {
13729 throw new IllegalArgumentException("Unknown target package: " + packageName);
13731 return pkgSetting.getSuspended(userId);
13735 private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
13736 if (isPackageDeviceAdmin(packageName, userId)) {
13737 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13738 + "\": has an active device admin");
13742 String activeLauncherPackageName = getActiveLauncherPackageName(userId);
13743 if (packageName.equals(activeLauncherPackageName)) {
13744 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13745 + "\": contains the active launcher");
13749 if (packageName.equals(mRequiredInstallerPackage)) {
13750 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13751 + "\": required for package installation");
13755 if (packageName.equals(mRequiredUninstallerPackage)) {
13756 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13757 + "\": required for package uninstallation");
13761 if (packageName.equals(mRequiredVerifierPackage)) {
13762 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13763 + "\": required for package verification");
13767 if (packageName.equals(getDefaultDialerPackageName(userId))) {
13768 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13769 + "\": is the default dialer");
13773 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13774 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13775 + "\": protected package");
13779 // Cannot suspend static shared libs as they are considered
13780 // a part of the using app (emulating static linking). Also
13781 // static libs are installed always on internal storage.
13782 PackageParser.Package pkg = mPackages.get(packageName);
13783 if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
13784 Slog.w(TAG, "Cannot suspend package: " + packageName
13785 + " providing static shared library: "
13786 + pkg.staticSharedLibName);
13793 private String getActiveLauncherPackageName(int userId) {
13794 Intent intent = new Intent(Intent.ACTION_MAIN);
13795 intent.addCategory(Intent.CATEGORY_HOME);
13796 ResolveInfo resolveInfo = resolveIntent(
13798 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
13799 PackageManager.MATCH_DEFAULT_ONLY,
13802 return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
13805 private String getDefaultDialerPackageName(int userId) {
13806 synchronized (mPackages) {
13807 return mSettings.getDefaultDialerPackageNameLPw(userId);
13812 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
13813 mContext.enforceCallingOrSelfPermission(
13814 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13815 "Only package verification agents can verify applications");
13817 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
13818 final PackageVerificationResponse response = new PackageVerificationResponse(
13819 verificationCode, Binder.getCallingUid());
13821 msg.obj = response;
13822 mHandler.sendMessage(msg);
13826 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
13827 long millisecondsToDelay) {
13828 mContext.enforceCallingOrSelfPermission(
13829 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13830 "Only package verification agents can extend verification timeouts");
13832 final PackageVerificationState state = mPendingVerification.get(id);
13833 final PackageVerificationResponse response = new PackageVerificationResponse(
13834 verificationCodeAtTimeout, Binder.getCallingUid());
13836 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
13837 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
13839 if (millisecondsToDelay < 0) {
13840 millisecondsToDelay = 0;
13842 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
13843 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
13844 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
13847 if ((state != null) && !state.timeoutExtended()) {
13848 state.extendTimeout();
13850 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
13852 msg.obj = response;
13853 mHandler.sendMessageDelayed(msg, millisecondsToDelay);
13857 private void broadcastPackageVerified(int verificationId, Uri packageUri,
13858 int verificationCode, UserHandle user) {
13859 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
13860 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
13861 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
13862 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
13863 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
13865 mContext.sendBroadcastAsUser(intent, user,
13866 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
13869 private ComponentName matchComponentForVerifier(String packageName,
13870 List<ResolveInfo> receivers) {
13871 ActivityInfo targetReceiver = null;
13873 final int NR = receivers.size();
13874 for (int i = 0; i < NR; i++) {
13875 final ResolveInfo info = receivers.get(i);
13876 if (info.activityInfo == null) {
13880 if (packageName.equals(info.activityInfo.packageName)) {
13881 targetReceiver = info.activityInfo;
13886 if (targetReceiver == null) {
13890 return new ComponentName(targetReceiver.packageName, targetReceiver.name);
13893 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
13894 List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
13895 if (pkgInfo.verifiers.length == 0) {
13899 final int N = pkgInfo.verifiers.length;
13900 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
13901 for (int i = 0; i < N; i++) {
13902 final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
13904 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
13906 if (comp == null) {
13910 final int verifierUid = getUidForVerifier(verifierInfo);
13911 if (verifierUid == -1) {
13915 if (DEBUG_VERIFY) {
13916 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
13917 + " with the correct signature");
13919 sufficientVerifiers.add(comp);
13920 verificationState.addSufficientVerifier(verifierUid);
13923 return sufficientVerifiers;
13926 private int getUidForVerifier(VerifierInfo verifierInfo) {
13927 synchronized (mPackages) {
13928 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
13931 } else if (pkg.mSignatures.length != 1) {
13932 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
13933 + " has more than one signature; ignoring");
13938 * If the public key of the package's signature does not match
13939 * our expected public key, then this is a different package and
13943 final byte[] expectedPublicKey;
13945 final Signature verifierSig = pkg.mSignatures[0];
13946 final PublicKey publicKey = verifierSig.getPublicKey();
13947 expectedPublicKey = publicKey.getEncoded();
13948 } catch (CertificateException e) {
13952 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
13954 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
13955 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
13956 + " does not have the expected public key; ignoring");
13960 return pkg.applicationInfo.uid;
13965 public void finishPackageInstall(int token, boolean didLaunch) {
13966 enforceSystemOrRoot("Only the system is allowed to finish installs");
13968 if (DEBUG_INSTALL) {
13969 Slog.v(TAG, "BM finishing package install for " + token);
13971 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
13973 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
13974 mHandler.sendMessage(msg);
13978 * Get the verification agent timeout.
13980 * @return verification timeout in milliseconds
13982 private long getVerificationTimeout() {
13983 return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
13984 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
13985 DEFAULT_VERIFICATION_TIMEOUT);
13989 * Get the default verification agent response code.
13991 * @return default verification response code
13993 private int getDefaultVerificationResponse() {
13994 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
13995 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
13996 DEFAULT_VERIFICATION_RESPONSE);
14000 * Check whether or not package verification has been enabled.
14002 * @return true if verification should be performed
14004 private boolean isVerificationEnabled(int userId, int installFlags) {
14005 if (!DEFAULT_VERIFY_ENABLE) {
14009 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
14011 // Check if installing from ADB
14012 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
14013 // Do not run verification in a test harness environment
14014 if (ActivityManager.isRunningInTestHarness()) {
14017 if (ensureVerifyAppsEnabled) {
14020 // Check if the developer does not want package verification for ADB installs
14021 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14022 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
14027 if (ensureVerifyAppsEnabled) {
14031 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14032 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
14036 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
14037 throws RemoteException {
14038 mContext.enforceCallingOrSelfPermission(
14039 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
14040 "Only intentfilter verification agents can verify applications");
14042 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
14043 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
14044 Binder.getCallingUid(), verificationCode, failedDomains);
14046 msg.obj = response;
14047 mHandler.sendMessage(msg);
14051 public int getIntentVerificationStatus(String packageName, int userId) {
14052 synchronized (mPackages) {
14053 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
14058 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
14059 mContext.enforceCallingOrSelfPermission(
14060 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14062 boolean result = false;
14063 synchronized (mPackages) {
14064 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
14067 scheduleWritePackageRestrictionsLocked(userId);
14073 public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
14074 String packageName) {
14075 synchronized (mPackages) {
14076 return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
14081 public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
14082 if (TextUtils.isEmpty(packageName)) {
14083 return ParceledListSlice.emptyList();
14085 synchronized (mPackages) {
14086 PackageParser.Package pkg = mPackages.get(packageName);
14087 if (pkg == null || pkg.activities == null) {
14088 return ParceledListSlice.emptyList();
14090 final int count = pkg.activities.size();
14091 ArrayList<IntentFilter> result = new ArrayList<>();
14092 for (int n=0; n<count; n++) {
14093 PackageParser.Activity activity = pkg.activities.get(n);
14094 if (activity.intents != null && activity.intents.size() > 0) {
14095 result.addAll(activity.intents);
14098 return new ParceledListSlice<>(result);
14103 public boolean setDefaultBrowserPackageName(String packageName, int userId) {
14104 mContext.enforceCallingOrSelfPermission(
14105 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14107 synchronized (mPackages) {
14108 boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
14109 if (packageName != null) {
14110 result |= updateIntentVerificationStatus(packageName,
14111 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS,
14113 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
14114 packageName, userId);
14121 public String getDefaultBrowserPackageName(int userId) {
14122 synchronized (mPackages) {
14123 return mSettings.getDefaultBrowserPackageNameLPw(userId);
14128 * Get the "allow unknown sources" setting.
14130 * @return the current "allow unknown sources" setting
14132 private int getUnknownSourcesSettings() {
14133 return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
14134 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
14139 public void setInstallerPackageName(String targetPackage, String installerPackageName) {
14140 final int uid = Binder.getCallingUid();
14142 synchronized (mPackages) {
14143 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
14144 if (targetPackageSetting == null) {
14145 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
14148 PackageSetting installerPackageSetting;
14149 if (installerPackageName != null) {
14150 installerPackageSetting = mSettings.mPackages.get(installerPackageName);
14151 if (installerPackageSetting == null) {
14152 throw new IllegalArgumentException("Unknown installer package: "
14153 + installerPackageName);
14156 installerPackageSetting = null;
14159 Signature[] callerSignature;
14160 Object obj = mSettings.getUserIdLPr(uid);
14162 if (obj instanceof SharedUserSetting) {
14163 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
14164 } else if (obj instanceof PackageSetting) {
14165 callerSignature = ((PackageSetting)obj).signatures.mSignatures;
14167 throw new SecurityException("Bad object " + obj + " for uid " + uid);
14170 throw new SecurityException("Unknown calling UID: " + uid);
14173 // Verify: can't set installerPackageName to a package that is
14174 // not signed with the same cert as the caller.
14175 if (installerPackageSetting != null) {
14176 if (compareSignatures(callerSignature,
14177 installerPackageSetting.signatures.mSignatures)
14178 != PackageManager.SIGNATURE_MATCH) {
14179 throw new SecurityException(
14180 "Caller does not have same cert as new installer package "
14181 + installerPackageName);
14185 // Verify: if target already has an installer package, it must
14186 // be signed with the same cert as the caller.
14187 if (targetPackageSetting.installerPackageName != null) {
14188 PackageSetting setting = mSettings.mPackages.get(
14189 targetPackageSetting.installerPackageName);
14190 // If the currently set package isn't valid, then it's always
14191 // okay to change it.
14192 if (setting != null) {
14193 if (compareSignatures(callerSignature,
14194 setting.signatures.mSignatures)
14195 != PackageManager.SIGNATURE_MATCH) {
14196 throw new SecurityException(
14197 "Caller does not have same cert as old installer package "
14198 + targetPackageSetting.installerPackageName);
14204 targetPackageSetting.installerPackageName = installerPackageName;
14205 if (installerPackageName != null) {
14206 mSettings.mInstallerPackages.add(installerPackageName);
14208 scheduleWriteSettingsLocked();
14213 public void setApplicationCategoryHint(String packageName, int categoryHint,
14214 String callerPackageName) {
14215 mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
14216 callerPackageName);
14217 synchronized (mPackages) {
14218 PackageSetting ps = mSettings.mPackages.get(packageName);
14220 throw new IllegalArgumentException("Unknown target package " + packageName);
14223 if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
14224 throw new IllegalArgumentException("Calling package " + callerPackageName
14225 + " is not installer for " + packageName);
14228 if (ps.categoryHint != categoryHint) {
14229 ps.categoryHint = categoryHint;
14230 scheduleWriteSettingsLocked();
14235 private void processPendingInstall(final InstallArgs args, final int currentStatus) {
14236 // Queue up an async operation since the package installation may take a little while.
14237 mHandler.post(new Runnable() {
14238 public void run() {
14239 mHandler.removeCallbacks(this);
14240 // Result object to be returned
14241 PackageInstalledInfo res = new PackageInstalledInfo();
14242 res.setReturnCode(currentStatus);
14245 res.removedInfo = null;
14246 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
14247 args.doPreInstall(res.returnCode);
14248 synchronized (mInstallLock) {
14249 installPackageTracedLI(args, res);
14251 args.doPostInstall(res.returnCode, res.uid);
14254 // A restore should be performed at this point if (a) the install
14255 // succeeded, (b) the operation is not an update, and (c) the new
14256 // package has not opted out of backup participation.
14257 final boolean update = res.removedInfo != null
14258 && res.removedInfo.removedPackage != null;
14259 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
14260 boolean doRestore = !update
14261 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
14263 // Set up the post-install work request bookkeeping. This will be used
14264 // and cleaned up by the post-install event handling regardless of whether
14265 // there's a restore pass performed. Token values are >= 1.
14267 if (mNextInstallToken < 0) mNextInstallToken = 1;
14268 token = mNextInstallToken++;
14270 PostInstallData data = new PostInstallData(args, res);
14271 mRunningInstalls.put(token, data);
14272 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
14274 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
14275 // Pass responsibility to the Backup Manager. It will perform a
14276 // restore if appropriate, then pass responsibility back to the
14277 // Package Manager to run the post-install observer callbacks
14279 IBackupManager bm = IBackupManager.Stub.asInterface(
14280 ServiceManager.getService(Context.BACKUP_SERVICE));
14282 if (DEBUG_INSTALL) Log.v(TAG, "token " + token
14283 + " to BM for possible restore");
14284 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
14286 // TODO: http://b/22388012
14287 if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
14288 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
14292 } catch (RemoteException e) {
14293 // can't happen; the backup manager is local
14294 } catch (Exception e) {
14295 Slog.e(TAG, "Exception trying to enqueue restore", e);
14299 Slog.e(TAG, "Backup Manager not found!");
14305 // No restore possible, or the Backup Manager was mysteriously not
14306 // available -- just fire the post-install work request directly.
14307 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
14309 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
14311 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
14312 mHandler.sendMessage(msg);
14319 * Callback from PackageSettings whenever an app is first transitioned out of the
14320 * 'stopped' state. Normally we just issue the broadcast, but we can't do that if
14321 * the app was "launched" for a restoreAtInstall operation. Therefore we check
14322 * here whether the app is the target of an ongoing install, and only send the
14323 * broadcast immediately if it is not in that state. If it *is* undergoing a restore,
14324 * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
14327 void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) {
14328 // Serialize this with the rest of the install-process message chain. In the
14329 // restore-at-install case, this Runnable will necessarily run before the
14330 // POST_INSTALL message is processed, so the contents of mRunningInstalls
14331 // are coherent. In the non-restore case, the app has already completed install
14332 // and been launched through some other means, so it is not in a problematic
14333 // state for observers to see the FIRST_LAUNCH signal.
14334 mHandler.post(new Runnable() {
14336 public void run() {
14337 for (int i = 0; i < mRunningInstalls.size(); i++) {
14338 final PostInstallData data = mRunningInstalls.valueAt(i);
14339 if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
14342 if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) {
14343 // right package; but is it for the right user?
14344 for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
14345 if (userId == data.res.newUsers[uIndex]) {
14346 if (DEBUG_BACKUP) {
14347 Slog.i(TAG, "Package " + pkgName
14348 + " being restored so deferring FIRST_LAUNCH");
14355 // didn't find it, so not being restored
14356 if (DEBUG_BACKUP) {
14357 Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH");
14359 sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId});
14364 private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) {
14365 sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
14366 installerPkg, null, userIds);
14369 private abstract class HandlerParams {
14370 private static final int MAX_RETRIES = 4;
14373 * Number of times startCopy() has been attempted and had a non-fatal
14376 private int mRetries = 0;
14378 /** User handle for the user requesting the information or installation. */
14379 private final UserHandle mUser;
14380 String traceMethod;
14383 HandlerParams(UserHandle user) {
14387 UserHandle getUser() {
14391 HandlerParams setTraceMethod(String traceMethod) {
14392 this.traceMethod = traceMethod;
14396 HandlerParams setTraceCookie(int traceCookie) {
14397 this.traceCookie = traceCookie;
14401 final boolean startCopy() {
14404 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
14406 if (++mRetries > MAX_RETRIES) {
14407 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
14408 mHandler.sendEmptyMessage(MCS_GIVE_UP);
14409 handleServiceError();
14415 } catch (RemoteException e) {
14416 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
14417 mHandler.sendEmptyMessage(MCS_RECONNECT);
14420 handleReturnCode();
14424 final void serviceError() {
14425 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
14426 handleServiceError();
14427 handleReturnCode();
14430 abstract void handleStartCopy() throws RemoteException;
14431 abstract void handleServiceError();
14432 abstract void handleReturnCode();
14435 private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
14436 for (File path : paths) {
14438 mcs.clearDirectory(path.getAbsolutePath());
14439 } catch (RemoteException e) {
14444 static class OriginInfo {
14446 * Location where install is coming from, before it has been
14447 * copied/renamed into place. This could be a single monolithic APK
14448 * file, or a cluster directory. This location may be untrusted.
14454 * Flag indicating that {@link #file} or {@link #cid} has already been
14455 * staged, meaning downstream users don't need to defensively copy the
14458 final boolean staged;
14461 * Flag indicating that {@link #file} or {@link #cid} is an already
14462 * installed app that is being moved.
14464 final boolean existing;
14466 final String resolvedPath;
14467 final File resolvedFile;
14469 static OriginInfo fromNothing() {
14470 return new OriginInfo(null, null, false, false);
14473 static OriginInfo fromUntrustedFile(File file) {
14474 return new OriginInfo(file, null, false, false);
14477 static OriginInfo fromExistingFile(File file) {
14478 return new OriginInfo(file, null, false, true);
14481 static OriginInfo fromStagedFile(File file) {
14482 return new OriginInfo(file, null, true, false);
14485 static OriginInfo fromStagedContainer(String cid) {
14486 return new OriginInfo(null, cid, true, false);
14489 private OriginInfo(File file, String cid, boolean staged, boolean existing) {
14492 this.staged = staged;
14493 this.existing = existing;
14496 resolvedPath = PackageHelper.getSdDir(cid);
14497 resolvedFile = new File(resolvedPath);
14498 } else if (file != null) {
14499 resolvedPath = file.getAbsolutePath();
14500 resolvedFile = file;
14502 resolvedPath = null;
14503 resolvedFile = null;
14508 static class MoveInfo {
14510 final String fromUuid;
14511 final String toUuid;
14512 final String packageName;
14513 final String dataAppName;
14515 final String seinfo;
14516 final int targetSdkVersion;
14518 public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
14519 String dataAppName, int appId, String seinfo, int targetSdkVersion) {
14520 this.moveId = moveId;
14521 this.fromUuid = fromUuid;
14522 this.toUuid = toUuid;
14523 this.packageName = packageName;
14524 this.dataAppName = dataAppName;
14525 this.appId = appId;
14526 this.seinfo = seinfo;
14527 this.targetSdkVersion = targetSdkVersion;
14531 static class VerificationInfo {
14532 /** A constant used to indicate that a uid value is not present. */
14533 public static final int NO_UID = -1;
14535 /** URI referencing where the package was downloaded from. */
14536 final Uri originatingUri;
14538 /** HTTP referrer URI associated with the originatingURI. */
14539 final Uri referrer;
14541 /** UID of the application that the install request originated from. */
14542 final int originatingUid;
14544 /** UID of application requesting the install */
14545 final int installerUid;
14547 VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
14548 this.originatingUri = originatingUri;
14549 this.referrer = referrer;
14550 this.originatingUid = originatingUid;
14551 this.installerUid = installerUid;
14555 class InstallParams extends HandlerParams {
14556 final OriginInfo origin;
14557 final MoveInfo move;
14558 final IPackageInstallObserver2 observer;
14560 final String installerPackageName;
14561 final String volumeUuid;
14562 private InstallArgs mArgs;
14564 final String packageAbiOverride;
14565 final String[] grantedRuntimePermissions;
14566 final VerificationInfo verificationInfo;
14567 final Certificate[][] certificates;
14568 final int installReason;
14570 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
14571 int installFlags, String installerPackageName, String volumeUuid,
14572 VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
14573 String[] grantedPermissions, Certificate[][] certificates, int installReason) {
14575 this.origin = origin;
14577 this.observer = observer;
14578 this.installFlags = installFlags;
14579 this.installerPackageName = installerPackageName;
14580 this.volumeUuid = volumeUuid;
14581 this.verificationInfo = verificationInfo;
14582 this.packageAbiOverride = packageAbiOverride;
14583 this.grantedRuntimePermissions = grantedPermissions;
14584 this.certificates = certificates;
14585 this.installReason = installReason;
14589 public String toString() {
14590 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
14591 + " file=" + origin.file + " cid=" + origin.cid + "}";
14594 private int installLocationPolicy(PackageInfoLite pkgLite) {
14595 String packageName = pkgLite.packageName;
14596 int installLocation = pkgLite.installLocation;
14597 boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
14599 synchronized (mPackages) {
14600 // Currently installed package which the new package is attempting to replace or
14601 // null if no such package is installed.
14602 PackageParser.Package installedPkg = mPackages.get(packageName);
14603 // Package which currently owns the data which the new package will own if installed.
14604 // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
14605 // will be null whereas dataOwnerPkg will contain information about the package
14606 // which was uninstalled while keeping its data.
14607 PackageParser.Package dataOwnerPkg = installedPkg;
14608 if (dataOwnerPkg == null) {
14609 PackageSetting ps = mSettings.mPackages.get(packageName);
14611 dataOwnerPkg = ps.pkg;
14615 if (dataOwnerPkg != null) {
14616 // If installed, the package will get access to data left on the device by its
14617 // predecessor. As a security measure, this is permited only if this is not a
14618 // version downgrade or if the predecessor package is marked as debuggable and
14619 // a downgrade is explicitly requested.
14621 // On debuggable platform builds, downgrades are permitted even for
14622 // non-debuggable packages to make testing easier. Debuggable platform builds do
14623 // not offer security guarantees and thus it's OK to disable some security
14624 // mechanisms to make debugging/testing easier on those builds. However, even on
14625 // debuggable builds downgrades of packages are permitted only if requested via
14626 // installFlags. This is because we aim to keep the behavior of debuggable
14627 // platform builds as close as possible to the behavior of non-debuggable
14628 // platform builds.
14629 final boolean downgradeRequested =
14630 (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
14631 final boolean packageDebuggable =
14632 (dataOwnerPkg.applicationInfo.flags
14633 & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
14634 final boolean downgradePermitted =
14635 (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
14636 if (!downgradePermitted) {
14638 checkDowngrade(dataOwnerPkg, pkgLite);
14639 } catch (PackageManagerException e) {
14640 Slog.w(TAG, "Downgrade detected: " + e.getMessage());
14641 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
14646 if (installedPkg != null) {
14647 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
14648 // Check for updated system application.
14649 if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14651 Slog.w(TAG, "Cannot install update to system app on sdcard");
14652 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
14654 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14657 // Install flag overrides everything.
14658 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14660 // If current upgrade specifies particular preference
14661 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
14662 // Application explicitly specified internal.
14663 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14664 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
14665 // App explictly prefers external. Let policy decide
14667 // Prefer previous location
14668 if (isExternal(installedPkg)) {
14669 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14671 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14675 // Invalid install. Return error code
14676 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
14680 // All the special cases have been taken care of.
14681 // Return result based on recommended install location.
14683 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14685 return pkgLite.recommendedInstallLocation;
14689 * Invoke remote method to get package information and install
14690 * location values. Override install location based on default
14691 * policy if needed and then create install arguments based
14692 * on the install location.
14694 public void handleStartCopy() throws RemoteException {
14695 int ret = PackageManager.INSTALL_SUCCEEDED;
14697 // If we're already staged, we've firmly committed to an install location
14698 if (origin.staged) {
14699 if (origin.file != null) {
14700 installFlags |= PackageManager.INSTALL_INTERNAL;
14701 installFlags &= ~PackageManager.INSTALL_EXTERNAL;
14702 } else if (origin.cid != null) {
14703 installFlags |= PackageManager.INSTALL_EXTERNAL;
14704 installFlags &= ~PackageManager.INSTALL_INTERNAL;
14706 throw new IllegalStateException("Invalid stage location");
14710 final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
14711 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
14712 final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
14713 PackageInfoLite pkgLite = null;
14715 if (onInt && onSd) {
14716 // Check if both bits are set.
14717 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
14718 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14719 } else if (onSd && ephemeral) {
14720 Slog.w(TAG, "Conflicting flags specified for installing ephemeral on external");
14721 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14723 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
14724 packageAbiOverride);
14726 if (DEBUG_EPHEMERAL && ephemeral) {
14727 Slog.v(TAG, "pkgLite for install: " + pkgLite);
14731 * If we have too little free space, try to free cache
14732 * before giving up.
14734 if (!origin.staged && pkgLite.recommendedInstallLocation
14735 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
14736 // TODO: focus freeing disk space on the target device
14737 final StorageManager storage = StorageManager.from(mContext);
14738 final long lowThreshold = storage.getStorageLowBytes(
14739 Environment.getDataDirectory());
14741 final long sizeBytes = mContainerService.calculateInstalledSize(
14742 origin.resolvedPath, isForwardLocked(), packageAbiOverride);
14745 mInstaller.freeCache(null, sizeBytes + lowThreshold, 0);
14746 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
14747 installFlags, packageAbiOverride);
14748 } catch (InstallerException e) {
14749 Slog.w(TAG, "Failed to free cache", e);
14753 * The cache free must have deleted the file we
14754 * downloaded to install.
14756 * TODO: fix the "freeCache" call to not delete
14757 * the file we care about.
14759 if (pkgLite.recommendedInstallLocation
14760 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
14761 pkgLite.recommendedInstallLocation
14762 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
14767 if (ret == PackageManager.INSTALL_SUCCEEDED) {
14768 int loc = pkgLite.recommendedInstallLocation;
14769 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
14770 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14771 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
14772 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
14773 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
14774 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
14775 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
14776 ret = PackageManager.INSTALL_FAILED_INVALID_APK;
14777 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
14778 ret = PackageManager.INSTALL_FAILED_INVALID_URI;
14779 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
14780 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
14782 // Override with defaults if needed.
14783 loc = installLocationPolicy(pkgLite);
14784 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
14785 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
14786 } else if (!onSd && !onInt) {
14787 // Override install location with flags
14788 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
14789 // Set the flag to install on external media.
14790 installFlags |= PackageManager.INSTALL_EXTERNAL;
14791 installFlags &= ~PackageManager.INSTALL_INTERNAL;
14792 } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
14793 if (DEBUG_EPHEMERAL) {
14794 Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
14796 installFlags |= PackageManager.INSTALL_INSTANT_APP;
14797 installFlags &= ~(PackageManager.INSTALL_EXTERNAL
14798 |PackageManager.INSTALL_INTERNAL);
14800 // Make sure the flag for installing on external
14802 installFlags |= PackageManager.INSTALL_INTERNAL;
14803 installFlags &= ~PackageManager.INSTALL_EXTERNAL;
14809 final InstallArgs args = createInstallArgs(this);
14812 if (ret == PackageManager.INSTALL_SUCCEEDED) {
14813 // TODO: http://b/22976637
14814 // Apps installed for "all" users use the device owner to verify the app
14815 UserHandle verifierUser = getUser();
14816 if (verifierUser == UserHandle.ALL) {
14817 verifierUser = UserHandle.SYSTEM;
14821 * Determine if we have any installed package verifiers. If we
14822 * do, then we'll defer to them to verify the packages.
14824 final int requiredUid = mRequiredVerifierPackage == null ? -1
14825 : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
14826 verifierUser.getIdentifier());
14827 if (!origin.existing && requiredUid != -1
14828 && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) {
14829 final Intent verification = new Intent(
14830 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
14831 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14832 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
14833 PACKAGE_MIME_TYPE);
14834 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
14836 // Query all live verifiers based on current user state
14837 final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
14838 PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier());
14840 if (DEBUG_VERIFY) {
14841 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
14842 + verification.toString() + " with " + pkgLite.verifiers.length
14843 + " optional verifiers");
14846 final int verificationId = mPendingVerificationToken++;
14848 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
14850 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
14851 installerPackageName);
14853 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
14856 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
14857 pkgLite.packageName);
14859 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
14860 pkgLite.versionCode);
14862 if (verificationInfo != null) {
14863 if (verificationInfo.originatingUri != null) {
14864 verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
14865 verificationInfo.originatingUri);
14867 if (verificationInfo.referrer != null) {
14868 verification.putExtra(Intent.EXTRA_REFERRER,
14869 verificationInfo.referrer);
14871 if (verificationInfo.originatingUid >= 0) {
14872 verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
14873 verificationInfo.originatingUid);
14875 if (verificationInfo.installerUid >= 0) {
14876 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
14877 verificationInfo.installerUid);
14881 final PackageVerificationState verificationState = new PackageVerificationState(
14882 requiredUid, args);
14884 mPendingVerification.append(verificationId, verificationState);
14886 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
14887 receivers, verificationState);
14889 DeviceIdleController.LocalService idleController = getDeviceIdleController();
14890 final long idleDuration = getVerificationTimeout();
14893 * If any sufficient verifiers were listed in the package
14894 * manifest, attempt to ask them.
14896 if (sufficientVerifiers != null) {
14897 final int N = sufficientVerifiers.size();
14899 Slog.i(TAG, "Additional verifiers required, but none installed.");
14900 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
14902 for (int i = 0; i < N; i++) {
14903 final ComponentName verifierComponent = sufficientVerifiers.get(i);
14904 idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
14905 verifierComponent.getPackageName(), idleDuration,
14906 verifierUser.getIdentifier(), false, "package verifier");
14908 final Intent sufficientIntent = new Intent(verification);
14909 sufficientIntent.setComponent(verifierComponent);
14910 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
14915 final ComponentName requiredVerifierComponent = matchComponentForVerifier(
14916 mRequiredVerifierPackage, receivers);
14917 if (ret == PackageManager.INSTALL_SUCCEEDED
14918 && mRequiredVerifierPackage != null) {
14919 Trace.asyncTraceBegin(
14920 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
14922 * Send the intent to the required verification agent,
14923 * but only start the verification timeout after the
14924 * target BroadcastReceivers have run.
14926 verification.setComponent(requiredVerifierComponent);
14927 idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
14928 mRequiredVerifierPackage, idleDuration,
14929 verifierUser.getIdentifier(), false, "package verifier");
14930 mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
14931 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14932 new BroadcastReceiver() {
14934 public void onReceive(Context context, Intent intent) {
14935 final Message msg = mHandler
14936 .obtainMessage(CHECK_PENDING_VERIFICATION);
14937 msg.arg1 = verificationId;
14938 mHandler.sendMessageDelayed(msg, getVerificationTimeout());
14940 }, null, 0, null, null);
14943 * We don't want the copy to proceed until verification
14944 * succeeds, so null out this field.
14950 * No package verification is enabled, so immediately start
14951 * the remote call to initiate copy using temporary file.
14953 ret = args.copyApk(mContainerService, true);
14961 void handleReturnCode() {
14962 // If mArgs is null, then MCS couldn't be reached. When it
14963 // reconnects, it will try again to install. At that point, this
14965 if (mArgs != null) {
14966 processPendingInstall(mArgs, mRet);
14971 void handleServiceError() {
14972 mArgs = createInstallArgs(this);
14973 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
14976 public boolean isForwardLocked() {
14977 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
14982 * Used during creation of InstallArgs
14984 * @param installFlags package installation flags
14985 * @return true if should be installed on external storage
14987 private static boolean installOnExternalAsec(int installFlags) {
14988 if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
14991 if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
14998 * Used during creation of InstallArgs
15000 * @param installFlags package installation flags
15001 * @return true if should be installed as forward locked
15003 private static boolean installForwardLocked(int installFlags) {
15004 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15007 private InstallArgs createInstallArgs(InstallParams params) {
15008 if (params.move != null) {
15009 return new MoveInstallArgs(params);
15010 } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
15011 return new AsecInstallArgs(params);
15013 return new FileInstallArgs(params);
15018 * Create args that describe an existing installed package. Typically used
15019 * when cleaning up old installs, or used as a move source.
15021 private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
15022 String resourcePath, String[] instructionSets) {
15023 final boolean isInAsec;
15024 if (installOnExternalAsec(installFlags)) {
15025 /* Apps on SD card are always in ASEC containers. */
15027 } else if (installForwardLocked(installFlags)
15028 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
15030 * Forward-locked apps are only in ASEC containers if they're the
15039 return new AsecInstallArgs(codePath, instructionSets,
15040 installOnExternalAsec(installFlags), installForwardLocked(installFlags));
15042 return new FileInstallArgs(codePath, resourcePath, instructionSets);
15046 static abstract class InstallArgs {
15047 /** @see InstallParams#origin */
15048 final OriginInfo origin;
15049 /** @see InstallParams#move */
15050 final MoveInfo move;
15052 final IPackageInstallObserver2 observer;
15053 // Always refers to PackageManager flags only
15054 final int installFlags;
15055 final String installerPackageName;
15056 final String volumeUuid;
15057 final UserHandle user;
15058 final String abiOverride;
15059 final String[] installGrantPermissions;
15060 /** If non-null, drop an async trace when the install completes */
15061 final String traceMethod;
15062 final int traceCookie;
15063 final Certificate[][] certificates;
15064 final int installReason;
15066 // The list of instruction sets supported by this app. This is currently
15067 // only used during the rmdex() phase to clean up resources. We can get rid of this
15068 // if we move dex files under the common app path.
15069 /* nullable */ String[] instructionSets;
15071 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
15072 int installFlags, String installerPackageName, String volumeUuid,
15073 UserHandle user, String[] instructionSets,
15074 String abiOverride, String[] installGrantPermissions,
15075 String traceMethod, int traceCookie, Certificate[][] certificates,
15076 int installReason) {
15077 this.origin = origin;
15079 this.installFlags = installFlags;
15080 this.observer = observer;
15081 this.installerPackageName = installerPackageName;
15082 this.volumeUuid = volumeUuid;
15084 this.instructionSets = instructionSets;
15085 this.abiOverride = abiOverride;
15086 this.installGrantPermissions = installGrantPermissions;
15087 this.traceMethod = traceMethod;
15088 this.traceCookie = traceCookie;
15089 this.certificates = certificates;
15090 this.installReason = installReason;
15093 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
15094 abstract int doPreInstall(int status);
15097 * Rename package into final resting place. All paths on the given
15098 * scanned package should be updated to reflect the rename.
15100 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
15101 abstract int doPostInstall(int status, int uid);
15103 /** @see PackageSettingBase#codePathString */
15104 abstract String getCodePath();
15105 /** @see PackageSettingBase#resourcePathString */
15106 abstract String getResourcePath();
15108 // Need installer lock especially for dex file removal.
15109 abstract void cleanUpResourcesLI();
15110 abstract boolean doPostDeleteLI(boolean delete);
15113 * Called before the source arguments are copied. This is used mostly
15114 * for MoveParams when it needs to read the source file to put it in the
15118 return PackageManager.INSTALL_SUCCEEDED;
15122 * Called after the source arguments are copied. This is used mostly for
15123 * MoveParams when it needs to read the source file to put it in the
15126 int doPostCopy(int uid) {
15127 return PackageManager.INSTALL_SUCCEEDED;
15130 protected boolean isFwdLocked() {
15131 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15134 protected boolean isExternalAsec() {
15135 return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15138 protected boolean isEphemeral() {
15139 return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15142 UserHandle getUser() {
15147 private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
15148 if (!allCodePaths.isEmpty()) {
15149 if (instructionSets == null) {
15150 throw new IllegalStateException("instructionSet == null");
15152 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
15153 for (String codePath : allCodePaths) {
15154 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
15156 mInstaller.rmdex(codePath, dexCodeInstructionSet);
15157 } catch (InstallerException ignored) {
15165 * Logic to handle installation of non-ASEC applications, including copying
15166 * and renaming logic.
15168 class FileInstallArgs extends InstallArgs {
15169 private File codeFile;
15170 private File resourceFile;
15172 // Example topology:
15173 // /data/app/com.example/base.apk
15174 // /data/app/com.example/split_foo.apk
15175 // /data/app/com.example/lib/arm/libfoo.so
15176 // /data/app/com.example/lib/arm64/libfoo.so
15177 // /data/app/com.example/dalvik/arm/base.apk@classes.dex
15180 FileInstallArgs(InstallParams params) {
15181 super(params.origin, params.move, params.observer, params.installFlags,
15182 params.installerPackageName, params.volumeUuid,
15183 params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
15184 params.grantedRuntimePermissions,
15185 params.traceMethod, params.traceCookie, params.certificates,
15186 params.installReason);
15187 if (isFwdLocked()) {
15188 throw new IllegalArgumentException("Forward locking only supported in ASEC");
15192 /** Existing install */
15193 FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
15194 super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
15195 null, null, null, 0, null /*certificates*/,
15196 PackageManager.INSTALL_REASON_UNKNOWN);
15197 this.codeFile = (codePath != null) ? new File(codePath) : null;
15198 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
15201 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15202 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
15204 return doCopyApk(imcs, temp);
15206 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15210 private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15211 if (origin.staged) {
15212 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
15213 codeFile = origin.file;
15214 resourceFile = origin.file;
15215 return PackageManager.INSTALL_SUCCEEDED;
15219 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15220 final File tempDir =
15221 mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
15222 codeFile = tempDir;
15223 resourceFile = tempDir;
15224 } catch (IOException e) {
15225 Slog.w(TAG, "Failed to create copy file: " + e);
15226 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15229 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
15231 public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
15232 if (!FileUtils.isValidExtFilename(name)) {
15233 throw new IllegalArgumentException("Invalid filename: " + name);
15236 final File file = new File(codeFile, name);
15237 final FileDescriptor fd = Os.open(file.getAbsolutePath(),
15238 O_RDWR | O_CREAT, 0644);
15239 Os.chmod(file.getAbsolutePath(), 0644);
15240 return new ParcelFileDescriptor(fd);
15241 } catch (ErrnoException e) {
15242 throw new RemoteException("Failed to open: " + e.getMessage());
15247 int ret = PackageManager.INSTALL_SUCCEEDED;
15248 ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
15249 if (ret != PackageManager.INSTALL_SUCCEEDED) {
15250 Slog.e(TAG, "Failed to copy package");
15254 final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
15255 NativeLibraryHelper.Handle handle = null;
15257 handle = NativeLibraryHelper.Handle.create(codeFile);
15258 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
15260 } catch (IOException e) {
15261 Slog.e(TAG, "Copying native libraries failed", e);
15262 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15264 IoUtils.closeQuietly(handle);
15270 int doPreInstall(int status) {
15271 if (status != PackageManager.INSTALL_SUCCEEDED) {
15277 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15278 if (status != PackageManager.INSTALL_SUCCEEDED) {
15283 final File targetDir = codeFile.getParentFile();
15284 final File beforeCodeFile = codeFile;
15285 final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
15287 if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
15289 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
15290 } catch (ErrnoException e) {
15291 Slog.w(TAG, "Failed to rename", e);
15295 if (!SELinux.restoreconRecursive(afterCodeFile)) {
15296 Slog.w(TAG, "Failed to restorecon");
15300 // Reflect the rename internally
15301 codeFile = afterCodeFile;
15302 resourceFile = afterCodeFile;
15304 // Reflect the rename in scanned details
15305 pkg.setCodePath(afterCodeFile.getAbsolutePath());
15306 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
15307 afterCodeFile, pkg.baseCodePath));
15308 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
15309 afterCodeFile, pkg.splitCodePaths));
15311 // Reflect the rename in app info
15312 pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15313 pkg.setApplicationInfoCodePath(pkg.codePath);
15314 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15315 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15316 pkg.setApplicationInfoResourcePath(pkg.codePath);
15317 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15318 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15323 int doPostInstall(int status, int uid) {
15324 if (status != PackageManager.INSTALL_SUCCEEDED) {
15331 String getCodePath() {
15332 return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15336 String getResourcePath() {
15337 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15340 private boolean cleanUp() {
15341 if (codeFile == null || !codeFile.exists()) {
15345 removeCodePathLI(codeFile);
15347 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
15348 resourceFile.delete();
15354 void cleanUpResourcesLI() {
15355 // Try enumerating all code paths before deleting
15356 List<String> allCodePaths = Collections.EMPTY_LIST;
15357 if (codeFile != null && codeFile.exists()) {
15359 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
15360 allCodePaths = pkg.getAllCodePaths();
15361 } catch (PackageParserException e) {
15362 // Ignored; we tried our best
15367 removeDexFiles(allCodePaths, instructionSets);
15370 boolean doPostDeleteLI(boolean delete) {
15371 // XXX err, shouldn't we respect the delete flag?
15372 cleanUpResourcesLI();
15377 private boolean isAsecExternal(String cid) {
15378 final String asecPath = PackageHelper.getSdFilesystem(cid);
15379 return !asecPath.startsWith(mAsecInternalPath);
15382 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
15383 PackageManagerException {
15385 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
15386 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
15387 throw new PackageManagerException(copyRet, message);
15393 * Extract the StorageManagerService "container ID" from the full code path of an
15396 static String cidFromCodePath(String fullCodePath) {
15397 int eidx = fullCodePath.lastIndexOf("/");
15398 String subStr1 = fullCodePath.substring(0, eidx);
15399 int sidx = subStr1.lastIndexOf("/");
15400 return subStr1.substring(sidx+1, eidx);
15404 * Logic to handle installation of ASEC applications, including copying and
15407 class AsecInstallArgs extends InstallArgs {
15408 static final String RES_FILE_NAME = "pkg.apk";
15409 static final String PUBLIC_RES_FILE_NAME = "res.zip";
15412 String packagePath;
15413 String resourcePath;
15416 AsecInstallArgs(InstallParams params) {
15417 super(params.origin, params.move, params.observer, params.installFlags,
15418 params.installerPackageName, params.volumeUuid,
15419 params.getUser(), null /* instruction sets */, params.packageAbiOverride,
15420 params.grantedRuntimePermissions,
15421 params.traceMethod, params.traceCookie, params.certificates,
15422 params.installReason);
15425 /** Existing install */
15426 AsecInstallArgs(String fullCodePath, String[] instructionSets,
15427 boolean isExternal, boolean isForwardLocked) {
15428 super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
15429 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
15430 instructionSets, null, null, null, 0, null /*certificates*/,
15431 PackageManager.INSTALL_REASON_UNKNOWN);
15432 // Hackily pretend we're still looking at a full code path
15433 if (!fullCodePath.endsWith(RES_FILE_NAME)) {
15434 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
15437 // Extract cid from fullCodePath
15438 int eidx = fullCodePath.lastIndexOf("/");
15439 String subStr1 = fullCodePath.substring(0, eidx);
15440 int sidx = subStr1.lastIndexOf("/");
15441 cid = subStr1.substring(sidx+1, eidx);
15442 setMountPath(subStr1);
15445 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
15446 super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
15447 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
15448 instructionSets, null, null, null, 0, null /*certificates*/,
15449 PackageManager.INSTALL_REASON_UNKNOWN);
15451 setMountPath(PackageHelper.getSdDir(cid));
15454 void createCopyFile() {
15455 cid = mInstallerService.allocateExternalStageCidLegacy();
15458 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15459 if (origin.staged && origin.cid != null) {
15460 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy");
15462 setMountPath(PackageHelper.getSdDir(cid));
15463 return PackageManager.INSTALL_SUCCEEDED;
15470 * Pre-emptively destroy the container since it's destroyed if
15471 * copying fails due to it existing anyway.
15473 PackageHelper.destroySdDir(cid);
15476 final String newMountPath = imcs.copyPackageToContainer(
15477 origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
15478 isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
15480 if (newMountPath != null) {
15481 setMountPath(newMountPath);
15482 return PackageManager.INSTALL_SUCCEEDED;
15484 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15489 String getCodePath() {
15490 return packagePath;
15494 String getResourcePath() {
15495 return resourcePath;
15498 int doPreInstall(int status) {
15499 if (status != PackageManager.INSTALL_SUCCEEDED) {
15500 // Destroy container
15501 PackageHelper.destroySdDir(cid);
15503 boolean mounted = PackageHelper.isContainerMounted(cid);
15505 String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
15506 Process.SYSTEM_UID);
15507 if (newMountPath != null) {
15508 setMountPath(newMountPath);
15510 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15517 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15518 String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
15519 String newMountPath = null;
15520 if (PackageHelper.isContainerMounted(cid)) {
15521 // Unmount the container
15522 if (!PackageHelper.unMountSdDir(cid)) {
15523 Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
15527 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
15528 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
15529 " which might be stale. Will try to clean up.");
15530 // Clean up the stale container and proceed to recreate.
15531 if (!PackageHelper.destroySdDir(newCacheId)) {
15532 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
15535 // Successfully cleaned up stale container. Try to rename again.
15536 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
15537 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
15538 + " inspite of cleaning it up.");
15542 if (!PackageHelper.isContainerMounted(newCacheId)) {
15543 Slog.w(TAG, "Mounting container " + newCacheId);
15544 newMountPath = PackageHelper.mountSdDir(newCacheId,
15545 getEncryptKey(), Process.SYSTEM_UID);
15547 newMountPath = PackageHelper.getSdDir(newCacheId);
15549 if (newMountPath == null) {
15550 Slog.w(TAG, "Failed to get cache path for " + newCacheId);
15553 Log.i(TAG, "Succesfully renamed " + cid +
15554 " to " + newCacheId +
15555 " at new path: " + newMountPath);
15558 final File beforeCodeFile = new File(packagePath);
15559 setMountPath(newMountPath);
15560 final File afterCodeFile = new File(packagePath);
15562 // Reflect the rename in scanned details
15563 pkg.setCodePath(afterCodeFile.getAbsolutePath());
15564 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
15565 afterCodeFile, pkg.baseCodePath));
15566 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
15567 afterCodeFile, pkg.splitCodePaths));
15569 // Reflect the rename in app info
15570 pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15571 pkg.setApplicationInfoCodePath(pkg.codePath);
15572 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15573 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15574 pkg.setApplicationInfoResourcePath(pkg.codePath);
15575 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15576 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15581 private void setMountPath(String mountPath) {
15582 final File mountFile = new File(mountPath);
15584 final File monolithicFile = new File(mountFile, RES_FILE_NAME);
15585 if (monolithicFile.exists()) {
15586 packagePath = monolithicFile.getAbsolutePath();
15587 if (isFwdLocked()) {
15588 resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
15590 resourcePath = packagePath;
15593 packagePath = mountFile.getAbsolutePath();
15594 resourcePath = packagePath;
15598 int doPostInstall(int status, int uid) {
15599 if (status != PackageManager.INSTALL_SUCCEEDED) {
15602 final int groupOwner;
15603 final String protectedFile;
15604 if (isFwdLocked()) {
15605 groupOwner = UserHandle.getSharedAppGid(uid);
15606 protectedFile = RES_FILE_NAME;
15609 protectedFile = null;
15612 if (uid < Process.FIRST_APPLICATION_UID
15613 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
15614 Slog.e(TAG, "Failed to finalize " + cid);
15615 PackageHelper.destroySdDir(cid);
15616 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15619 boolean mounted = PackageHelper.isContainerMounted(cid);
15621 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
15627 private void cleanUp() {
15628 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
15630 // Destroy secure container
15631 PackageHelper.destroySdDir(cid);
15634 private List<String> getAllCodePaths() {
15635 final File codeFile = new File(getCodePath());
15636 if (codeFile != null && codeFile.exists()) {
15638 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
15639 return pkg.getAllCodePaths();
15640 } catch (PackageParserException e) {
15641 // Ignored; we tried our best
15644 return Collections.EMPTY_LIST;
15647 void cleanUpResourcesLI() {
15648 // Enumerate all code paths before deleting
15649 cleanUpResourcesLI(getAllCodePaths());
15652 private void cleanUpResourcesLI(List<String> allCodePaths) {
15654 removeDexFiles(allCodePaths, instructionSets);
15657 String getPackageName() {
15658 return getAsecPackageName(cid);
15661 boolean doPostDeleteLI(boolean delete) {
15662 if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
15663 final List<String> allCodePaths = getAllCodePaths();
15664 boolean mounted = PackageHelper.isContainerMounted(cid);
15667 if (PackageHelper.unMountSdDir(cid)) {
15671 if (!mounted && delete) {
15672 cleanUpResourcesLI(allCodePaths);
15679 if (isFwdLocked()) {
15680 if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE,
15681 MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) {
15682 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15686 return PackageManager.INSTALL_SUCCEEDED;
15690 int doPostCopy(int uid) {
15691 if (isFwdLocked()) {
15692 if (uid < Process.FIRST_APPLICATION_UID
15693 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
15695 Slog.e(TAG, "Failed to finalize " + cid);
15696 PackageHelper.destroySdDir(cid);
15697 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15701 return PackageManager.INSTALL_SUCCEEDED;
15706 * Logic to handle movement of existing installed applications.
15708 class MoveInstallArgs extends InstallArgs {
15709 private File codeFile;
15710 private File resourceFile;
15713 MoveInstallArgs(InstallParams params) {
15714 super(params.origin, params.move, params.observer, params.installFlags,
15715 params.installerPackageName, params.volumeUuid,
15716 params.getUser(), null /* instruction sets */, params.packageAbiOverride,
15717 params.grantedRuntimePermissions,
15718 params.traceMethod, params.traceCookie, params.certificates,
15719 params.installReason);
15722 int copyApk(IMediaContainerService imcs, boolean temp) {
15723 if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
15724 + move.fromUuid + " to " + move.toUuid);
15725 synchronized (mInstaller) {
15727 mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
15728 move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
15729 } catch (InstallerException e) {
15730 Slog.w(TAG, "Failed to move app", e);
15731 return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15735 codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
15736 resourceFile = codeFile;
15737 if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
15739 return PackageManager.INSTALL_SUCCEEDED;
15742 int doPreInstall(int status) {
15743 if (status != PackageManager.INSTALL_SUCCEEDED) {
15744 cleanUp(move.toUuid);
15749 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15750 if (status != PackageManager.INSTALL_SUCCEEDED) {
15751 cleanUp(move.toUuid);
15755 // Reflect the move in app info
15756 pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15757 pkg.setApplicationInfoCodePath(pkg.codePath);
15758 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15759 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15760 pkg.setApplicationInfoResourcePath(pkg.codePath);
15761 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15762 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15767 int doPostInstall(int status, int uid) {
15768 if (status == PackageManager.INSTALL_SUCCEEDED) {
15769 cleanUp(move.fromUuid);
15771 cleanUp(move.toUuid);
15777 String getCodePath() {
15778 return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15782 String getResourcePath() {
15783 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15786 private boolean cleanUp(String volumeUuid) {
15787 final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
15789 Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
15790 final int[] userIds = sUserManager.getUserIds();
15791 synchronized (mInstallLock) {
15792 // Clean up both app data and code
15793 // All package moves are frozen until finished
15794 for (int userId : userIds) {
15796 mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
15797 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
15798 } catch (InstallerException e) {
15799 Slog.w(TAG, String.valueOf(e));
15802 removeCodePathLI(codeFile);
15807 void cleanUpResourcesLI() {
15808 throw new UnsupportedOperationException();
15811 boolean doPostDeleteLI(boolean delete) {
15812 throw new UnsupportedOperationException();
15816 static String getAsecPackageName(String packageCid) {
15817 int idx = packageCid.lastIndexOf("-");
15821 return packageCid.substring(0, idx);
15824 // Utility method used to create code paths based on package name and available index.
15825 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
15826 String idxStr = "";
15828 // Fall back to default value of idx=1 if prefix is not
15829 // part of oldCodePath
15830 if (oldCodePath != null) {
15831 String subStr = oldCodePath;
15832 // Drop the suffix right away
15833 if (suffix != null && subStr.endsWith(suffix)) {
15834 subStr = subStr.substring(0, subStr.length() - suffix.length());
15836 // If oldCodePath already contains prefix find out the
15837 // ending index to either increment or decrement.
15838 int sidx = subStr.lastIndexOf(prefix);
15840 subStr = subStr.substring(sidx + prefix.length());
15841 if (subStr != null) {
15842 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
15843 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
15846 idx = Integer.parseInt(subStr);
15852 } catch(NumberFormatException e) {
15857 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
15858 return prefix + idxStr;
15861 private File getNextCodePath(File targetDir, String packageName) {
15863 SecureRandom random = new SecureRandom();
15864 byte[] bytes = new byte[16];
15866 random.nextBytes(bytes);
15867 String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
15868 result = new File(targetDir, packageName + "-" + suffix);
15869 } while (result.exists());
15873 // Utility method that returns the relative package path with respect
15874 // to the installation directory. Like say for /data/data/com.test-1.apk
15875 // string com.test-1 is returned.
15876 static String deriveCodePathName(String codePath) {
15877 if (codePath == null) {
15880 final File codeFile = new File(codePath);
15881 final String name = codeFile.getName();
15882 if (codeFile.isDirectory()) {
15884 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
15885 final int lastDot = name.lastIndexOf('.');
15886 return name.substring(0, lastDot);
15888 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
15893 static class PackageInstalledInfo {
15896 // The set of users that originally had this package installed.
15898 // The set of users that now have this package installed.
15900 PackageParser.Package pkg;
15903 PackageRemovedInfo removedInfo;
15904 ArrayMap<String, PackageInstalledInfo> addedChildPackages;
15906 public void setError(int code, String msg) {
15907 setReturnCode(code);
15908 setReturnMessage(msg);
15912 public void setError(String msg, PackageParserException e) {
15913 setReturnCode(e.error);
15914 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15915 Slog.w(TAG, msg, e);
15918 public void setError(String msg, PackageManagerException e) {
15919 returnCode = e.error;
15920 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15921 Slog.w(TAG, msg, e);
15924 public void setReturnCode(int returnCode) {
15925 this.returnCode = returnCode;
15926 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15927 for (int i = 0; i < childCount; i++) {
15928 addedChildPackages.valueAt(i).returnCode = returnCode;
15932 private void setReturnMessage(String returnMsg) {
15933 this.returnMsg = returnMsg;
15934 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15935 for (int i = 0; i < childCount; i++) {
15936 addedChildPackages.valueAt(i).returnMsg = returnMsg;
15940 // In some error cases we want to convey more info back to the observer
15941 String origPackage;
15942 String origPermission;
15946 * Install a non-existing package.
15948 private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
15949 int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
15950 PackageInstalledInfo res, int installReason) {
15951 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
15953 // Remember this for later, in case we need to rollback this install
15954 String pkgName = pkg.packageName;
15956 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
15958 synchronized(mPackages) {
15959 final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName);
15960 if (renamedPackage != null) {
15961 // A package with the same name is already installed, though
15962 // it has been renamed to an older name. The package we
15963 // are trying to install should be installed as an update to
15964 // the existing one, but that has not been requested, so bail.
15965 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
15966 + " without first uninstalling package running as "
15970 if (mPackages.containsKey(pkgName)) {
15971 // Don't allow installation over an existing package with the same name.
15972 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
15973 + " without first uninstalling.");
15979 PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
15980 System.currentTimeMillis(), user);
15982 updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
15984 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
15985 prepareAppDataAfterInstallLIF(newPackage);
15988 // Remove package from internal structures, but keep around any
15989 // data that might have already existed
15990 deletePackageLIF(pkgName, UserHandle.ALL, false, null,
15991 PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
15993 } catch (PackageManagerException e) {
15994 res.setError("Package couldn't be installed in " + pkg.codePath, e);
15997 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16000 private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
16001 // Can't rotate keys during boot or if sharedUser.
16002 if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
16003 || !oldPs.keySetData.isUsingUpgradeKeySets()) {
16006 // app is using upgradeKeySets; make sure all are valid
16007 KeySetManagerService ksms = mSettings.mKeySetManagerService;
16008 long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
16009 for (int i = 0; i < upgradeKeySets.length; i++) {
16010 if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
16011 Slog.wtf(TAG, "Package "
16012 + (oldPs.name != null ? oldPs.name : "<null>")
16013 + " contains upgrade-key-set reference to unknown key-set: "
16014 + upgradeKeySets[i]
16015 + " reverting to signatures check.");
16022 private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
16023 // Upgrade keysets are being used. Determine if new package has a superset of the
16025 long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
16026 KeySetManagerService ksms = mSettings.mKeySetManagerService;
16027 for (int i = 0; i < upgradeKeySets.length; i++) {
16028 Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
16029 if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
16036 private static void updateDigest(MessageDigest digest, File file) throws IOException {
16037 try (DigestInputStream digestStream =
16038 new DigestInputStream(new FileInputStream(file), digest)) {
16039 while (digestStream.read() != -1) {} // nothing to do; just plow through the file
16043 private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags,
16044 UserHandle user, String installerPackageName, PackageInstalledInfo res,
16045 int installReason) {
16046 final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
16048 final PackageParser.Package oldPackage;
16049 final String pkgName = pkg.packageName;
16050 final int[] allUsers;
16051 final int[] installedUsers;
16053 synchronized(mPackages) {
16054 oldPackage = mPackages.get(pkgName);
16055 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
16057 // don't allow upgrade to target a release SDK from a pre-release SDK
16058 final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
16059 == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
16060 final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
16061 == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
16062 if (oldTargetsPreRelease
16063 && !newTargetsPreRelease
16064 && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
16065 Slog.w(TAG, "Can't install package targeting released sdk");
16066 res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
16070 final PackageSetting ps = mSettings.mPackages.get(pkgName);
16072 // verify signatures are valid
16073 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
16074 if (!checkUpgradeKeySetLP(ps, pkg)) {
16075 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16076 "New package not signed by keys specified by upgrade-keysets: "
16081 // default to original signature matching
16082 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
16083 != PackageManager.SIGNATURE_MATCH) {
16084 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16085 "New package has a different signature: " + pkgName);
16090 // don't allow a system upgrade unless the upgrade hash matches
16091 if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) {
16092 byte[] digestBytes = null;
16094 final MessageDigest digest = MessageDigest.getInstance("SHA-512");
16095 updateDigest(digest, new File(pkg.baseCodePath));
16096 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
16097 for (String path : pkg.splitCodePaths) {
16098 updateDigest(digest, new File(path));
16101 digestBytes = digest.digest();
16102 } catch (NoSuchAlgorithmException | IOException e) {
16103 res.setError(INSTALL_FAILED_INVALID_APK,
16104 "Could not compute hash: " + pkgName);
16107 if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
16108 res.setError(INSTALL_FAILED_INVALID_APK,
16109 "New package fails restrict-update check: " + pkgName);
16112 // retain upgrade restriction
16113 pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
16116 // Check for shared user id changes
16117 String invalidPackageName =
16118 getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
16119 if (invalidPackageName != null) {
16120 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
16121 "Package " + invalidPackageName + " tried to change user "
16122 + oldPackage.mSharedUserId);
16126 // In case of rollback, remember per-user/profile install state
16127 allUsers = sUserManager.getUserIds();
16128 installedUsers = ps.queryInstalledUsers(allUsers, true);
16130 // don't allow an upgrade from full to ephemeral
16131 if (isInstantApp) {
16132 if (user == null || user.getIdentifier() == UserHandle.USER_ALL) {
16133 for (int currentUser : allUsers) {
16134 if (!ps.getInstantApp(currentUser)) {
16135 // can't downgrade from full to instant
16136 Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
16137 + " for user: " + currentUser);
16138 res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16142 } else if (!ps.getInstantApp(user.getIdentifier())) {
16143 // can't downgrade from full to instant
16144 Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
16145 + " for user: " + user.getIdentifier());
16146 res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16152 // Update what is removed
16153 res.removedInfo = new PackageRemovedInfo(this);
16154 res.removedInfo.uid = oldPackage.applicationInfo.uid;
16155 res.removedInfo.removedPackage = oldPackage.packageName;
16156 res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
16157 res.removedInfo.isUpdate = true;
16158 res.removedInfo.origUsers = installedUsers;
16159 final PackageSetting ps = mSettings.getPackageLPr(pkgName);
16160 res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
16161 for (int i = 0; i < installedUsers.length; i++) {
16162 final int userId = installedUsers[i];
16163 res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
16166 final int childCount = (oldPackage.childPackages != null)
16167 ? oldPackage.childPackages.size() : 0;
16168 for (int i = 0; i < childCount; i++) {
16169 boolean childPackageUpdated = false;
16170 PackageParser.Package childPkg = oldPackage.childPackages.get(i);
16171 final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16172 if (res.addedChildPackages != null) {
16173 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
16174 if (childRes != null) {
16175 childRes.removedInfo.uid = childPkg.applicationInfo.uid;
16176 childRes.removedInfo.removedPackage = childPkg.packageName;
16177 childRes.removedInfo.isUpdate = true;
16178 childRes.removedInfo.installReasons = res.removedInfo.installReasons;
16179 childPackageUpdated = true;
16182 if (!childPackageUpdated) {
16183 PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
16184 childRemovedRes.removedPackage = childPkg.packageName;
16185 childRemovedRes.isUpdate = false;
16186 childRemovedRes.dataRemoved = true;
16187 synchronized (mPackages) {
16188 if (childPs != null) {
16189 childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
16192 if (res.removedInfo.removedChildPackages == null) {
16193 res.removedInfo.removedChildPackages = new ArrayMap<>();
16195 res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
16199 boolean sysPkg = (isSystemApp(oldPackage));
16201 // Set the system/privileged flags as needed
16202 final boolean privileged =
16203 (oldPackage.applicationInfo.privateFlags
16204 & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
16205 final int systemPolicyFlags = policyFlags
16206 | PackageParser.PARSE_IS_SYSTEM
16207 | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0);
16209 replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags,
16210 user, allUsers, installerPackageName, res, installReason);
16212 replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags,
16213 user, allUsers, installerPackageName, res, installReason);
16217 public List<String> getPreviousCodePaths(String packageName) {
16218 final PackageSetting ps = mSettings.mPackages.get(packageName);
16219 final List<String> result = new ArrayList<String>();
16220 if (ps != null && ps.oldCodePaths != null) {
16221 result.addAll(ps.oldCodePaths);
16226 private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
16227 PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
16228 int[] allUsers, String installerPackageName, PackageInstalledInfo res,
16229 int installReason) {
16230 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
16233 String pkgName = deletedPackage.packageName;
16234 boolean deletedPkg = true;
16235 boolean addedPkg = false;
16236 boolean updatedSettings = false;
16237 final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
16238 final int deleteFlags = PackageManager.DELETE_KEEP_DATA
16239 | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
16241 final long origUpdateTime = (pkg.mExtras != null)
16242 ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
16244 // First delete the existing package while retaining the data directory
16245 if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
16246 res.removedInfo, true, pkg)) {
16247 // If the existing package wasn't successfully deleted
16248 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
16249 deletedPkg = false;
16251 // Successfully deleted the old package; proceed with replace.
16253 // If deleted package lived in a container, give users a chance to
16254 // relinquish resources before killing.
16255 if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
16256 if (DEBUG_INSTALL) {
16257 Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
16259 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
16260 final ArrayList<String> pkgList = new ArrayList<String>(1);
16261 pkgList.add(deletedPackage.applicationInfo.packageName);
16262 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
16265 clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
16266 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16267 clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
16270 final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags,
16271 scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
16272 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16275 // Update the in-memory copy of the previous code paths.
16276 PackageSetting ps = mSettings.mPackages.get(pkgName);
16278 if (ps.oldCodePaths == null) {
16279 ps.oldCodePaths = new ArraySet<>();
16281 Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
16282 if (deletedPackage.splitCodePaths != null) {
16283 Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
16286 ps.oldCodePaths = null;
16288 if (ps.childPackageNames != null) {
16289 for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
16290 final String childPkgName = ps.childPackageNames.get(i);
16291 final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
16292 childPs.oldCodePaths = ps.oldCodePaths;
16295 // set instant app status, but, only if it's explicitly specified
16296 final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
16297 final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
16298 setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp);
16299 prepareAppDataAfterInstallLIF(newPackage);
16301 mDexManager.notifyPackageUpdated(newPackage.packageName,
16302 newPackage.baseCodePath, newPackage.splitCodePaths);
16303 } catch (PackageManagerException e) {
16304 res.setError("Package couldn't be installed in " + pkg.codePath, e);
16308 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16309 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
16311 // Revert all internal state mutations and added folders for the failed install
16313 deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
16314 res.removedInfo, true, null);
16317 // Restore the old package
16319 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
16320 File restoreFile = new File(deletedPackage.codePath);
16321 // Parse old package
16322 boolean oldExternal = isExternal(deletedPackage);
16323 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY |
16324 (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
16325 (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
16326 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
16328 scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
16330 } catch (PackageManagerException e) {
16331 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
16336 synchronized (mPackages) {
16337 // Ensure the installer package name up to date
16338 setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16340 // Update permissions for restored package
16341 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
16343 mSettings.writeLPr();
16346 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
16349 synchronized (mPackages) {
16350 PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);
16352 res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
16353 if (res.removedInfo.removedChildPackages != null) {
16354 final int childCount = res.removedInfo.removedChildPackages.size();
16355 // Iterate in reverse as we may modify the collection
16356 for (int i = childCount - 1; i >= 0; i--) {
16357 String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
16358 if (res.addedChildPackages.containsKey(childPackageName)) {
16359 res.removedInfo.removedChildPackages.removeAt(i);
16361 PackageRemovedInfo childInfo = res.removedInfo
16362 .removedChildPackages.valueAt(i);
16363 childInfo.removedForAllUsers = mPackages.get(
16364 childInfo.removedPackage) == null;
16373 private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
16374 PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
16375 int[] allUsers, String installerPackageName, PackageInstalledInfo res,
16376 int installReason) {
16377 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
16378 + ", old=" + deletedPackage);
16380 final boolean disabledSystem;
16382 // Remove existing system package
16383 removePackageLI(deletedPackage, true);
16385 synchronized (mPackages) {
16386 disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
16388 if (!disabledSystem) {
16389 // We didn't need to disable the .apk as a current system package,
16390 // which means we are replacing another update that is already
16391 // installed. We need to make sure to delete the older one's .apk.
16392 res.removedInfo.args = createInstallArgsForExisting(0,
16393 deletedPackage.applicationInfo.getCodePath(),
16394 deletedPackage.applicationInfo.getResourcePath(),
16395 getAppDexInstructionSets(deletedPackage.applicationInfo));
16397 res.removedInfo.args = null;
16400 // Successfully disabled the old package. Now proceed with re-installation
16401 clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
16402 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16403 clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
16405 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16406 pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
16407 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
16409 PackageParser.Package newPackage = null;
16411 // Add the package to the internal data structures
16412 newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user);
16414 // Set the update and install times
16415 PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
16416 setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
16417 System.currentTimeMillis());
16419 // Update the package dynamic state if succeeded
16420 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16421 // Now that the install succeeded make sure we remove data
16422 // directories for any child package the update removed.
16423 final int deletedChildCount = (deletedPackage.childPackages != null)
16424 ? deletedPackage.childPackages.size() : 0;
16425 final int newChildCount = (newPackage.childPackages != null)
16426 ? newPackage.childPackages.size() : 0;
16427 for (int i = 0; i < deletedChildCount; i++) {
16428 PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
16429 boolean childPackageDeleted = true;
16430 for (int j = 0; j < newChildCount; j++) {
16431 PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
16432 if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
16433 childPackageDeleted = false;
16437 if (childPackageDeleted) {
16438 PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
16439 deletedChildPkg.packageName);
16440 if (ps != null && res.removedInfo.removedChildPackages != null) {
16441 PackageRemovedInfo removedChildRes = res.removedInfo
16442 .removedChildPackages.get(deletedChildPkg.packageName);
16443 removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
16444 removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
16449 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16451 prepareAppDataAfterInstallLIF(newPackage);
16453 mDexManager.notifyPackageUpdated(newPackage.packageName,
16454 newPackage.baseCodePath, newPackage.splitCodePaths);
16456 } catch (PackageManagerException e) {
16457 res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
16458 res.setError("Package couldn't be installed in " + pkg.codePath, e);
16461 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16462 // Re installation failed. Restore old information
16463 // Remove new pkg information
16464 if (newPackage != null) {
16465 removeInstalledPackageLI(newPackage, true);
16467 // Add back the old system package
16469 scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user);
16470 } catch (PackageManagerException e) {
16471 Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
16474 synchronized (mPackages) {
16475 if (disabledSystem) {
16476 enableSystemPackageLPw(deletedPackage);
16479 // Ensure the installer package name up to date
16480 setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16482 // Update permissions for restored package
16483 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
16485 mSettings.writeLPr();
16488 Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
16489 + " after failed upgrade");
16494 * Checks whether the parent or any of the child packages have a change shared
16495 * user. For a package to be a valid update the shred users of the parent and
16496 * the children should match. We may later support changing child shared users.
16497 * @param oldPkg The updated package.
16498 * @param newPkg The update package.
16499 * @return The shared user that change between the versions.
16501 private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
16502 PackageParser.Package newPkg) {
16503 // Check parent shared user
16504 if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
16505 return newPkg.packageName;
16507 // Check child shared users
16508 final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16509 final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
16510 for (int i = 0; i < newChildCount; i++) {
16511 PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
16512 // If this child was present, did it have the same shared user?
16513 for (int j = 0; j < oldChildCount; j++) {
16514 PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
16515 if (newChildPkg.packageName.equals(oldChildPkg.packageName)
16516 && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
16517 return newChildPkg.packageName;
16524 private void removeNativeBinariesLI(PackageSetting ps) {
16525 // Remove the lib path for the parent package
16527 NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
16528 // Remove the lib path for the child packages
16529 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
16530 for (int i = 0; i < childCount; i++) {
16531 PackageSetting childPs = null;
16532 synchronized (mPackages) {
16533 childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
16535 if (childPs != null) {
16536 NativeLibraryHelper.removeNativeBinariesLI(childPs
16537 .legacyNativeLibraryPathString);
16543 private void enableSystemPackageLPw(PackageParser.Package pkg) {
16544 // Enable the parent package
16545 mSettings.enableSystemPackageLPw(pkg.packageName);
16546 // Enable the child packages
16547 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16548 for (int i = 0; i < childCount; i++) {
16549 PackageParser.Package childPkg = pkg.childPackages.get(i);
16550 mSettings.enableSystemPackageLPw(childPkg.packageName);
16554 private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
16555 PackageParser.Package newPkg) {
16556 // Disable the parent package (parent always replaced)
16557 boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
16558 // Disable the child packages
16559 final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16560 for (int i = 0; i < childCount; i++) {
16561 PackageParser.Package childPkg = oldPkg.childPackages.get(i);
16562 final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
16563 disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
16568 private void setInstallerPackageNameLPw(PackageParser.Package pkg,
16569 String installerPackageName) {
16570 // Enable the parent package
16571 mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
16572 // Enable the child packages
16573 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16574 for (int i = 0; i < childCount; i++) {
16575 PackageParser.Package childPkg = pkg.childPackages.get(i);
16576 mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
16580 private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
16581 // Collect all used permissions in the UID
16582 ArraySet<String> usedPermissions = new ArraySet<>();
16583 final int packageCount = su.packages.size();
16584 for (int i = 0; i < packageCount; i++) {
16585 PackageSetting ps = su.packages.valueAt(i);
16586 if (ps.pkg == null) {
16589 final int requestedPermCount = ps.pkg.requestedPermissions.size();
16590 for (int j = 0; j < requestedPermCount; j++) {
16591 String permission = ps.pkg.requestedPermissions.get(j);
16592 BasePermission bp = mSettings.mPermissions.get(permission);
16594 usedPermissions.add(permission);
16599 PermissionsState permissionsState = su.getPermissionsState();
16600 // Prune install permissions
16601 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
16602 final int installPermCount = installPermStates.size();
16603 for (int i = installPermCount - 1; i >= 0; i--) {
16604 PermissionState permissionState = installPermStates.get(i);
16605 if (!usedPermissions.contains(permissionState.getName())) {
16606 BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
16608 permissionsState.revokeInstallPermission(bp);
16609 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
16610 PackageManager.MASK_PERMISSION_FLAGS, 0);
16615 int[] runtimePermissionChangedUserIds = EmptyArray.INT;
16617 // Prune runtime permissions
16618 for (int userId : allUserIds) {
16619 List<PermissionState> runtimePermStates = permissionsState
16620 .getRuntimePermissionStates(userId);
16621 final int runtimePermCount = runtimePermStates.size();
16622 for (int i = runtimePermCount - 1; i >= 0; i--) {
16623 PermissionState permissionState = runtimePermStates.get(i);
16624 if (!usedPermissions.contains(permissionState.getName())) {
16625 BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
16627 permissionsState.revokeRuntimePermission(bp, userId);
16628 permissionsState.updatePermissionFlags(bp, userId,
16629 PackageManager.MASK_PERMISSION_FLAGS, 0);
16630 runtimePermissionChangedUserIds = ArrayUtils.appendInt(
16631 runtimePermissionChangedUserIds, userId);
16637 return runtimePermissionChangedUserIds;
16640 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
16641 int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
16642 // Update the parent package setting
16643 updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
16644 res, user, installReason);
16645 // Update the child packages setting
16646 final int childCount = (newPackage.childPackages != null)
16647 ? newPackage.childPackages.size() : 0;
16648 for (int i = 0; i < childCount; i++) {
16649 PackageParser.Package childPackage = newPackage.childPackages.get(i);
16650 PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
16651 updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
16652 childRes.origUsers, childRes, user, installReason);
16656 private void updateSettingsInternalLI(PackageParser.Package newPackage,
16657 String installerPackageName, int[] allUsers, int[] installedForUsers,
16658 PackageInstalledInfo res, UserHandle user, int installReason) {
16659 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
16661 String pkgName = newPackage.packageName;
16662 synchronized (mPackages) {
16663 //write settings. the installStatus will be incomplete at this stage.
16664 //note that the new package setting would have already been
16665 //added to mPackages. It hasn't been persisted yet.
16666 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
16667 // TODO: Remove this write? It's also written at the end of this method
16668 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
16669 mSettings.writeLPr();
16670 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16673 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
16674 synchronized (mPackages) {
16675 updatePermissionsLPw(newPackage.packageName, newPackage,
16676 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
16677 ? UPDATE_PERMISSIONS_ALL : 0));
16678 // For system-bundled packages, we assume that installing an upgraded version
16679 // of the package implies that the user actually wants to run that new code,
16680 // so we enable the package.
16681 PackageSetting ps = mSettings.mPackages.get(pkgName);
16682 final int userId = user.getIdentifier();
16684 if (isSystemApp(newPackage)) {
16685 if (DEBUG_INSTALL) {
16686 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
16688 // Enable system package for requested users
16689 if (res.origUsers != null) {
16690 for (int origUserId : res.origUsers) {
16691 if (userId == UserHandle.USER_ALL || userId == origUserId) {
16692 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
16693 origUserId, installerPackageName);
16697 // Also convey the prior install/uninstall state
16698 if (allUsers != null && installedForUsers != null) {
16699 for (int currentUserId : allUsers) {
16700 final boolean installed = ArrayUtils.contains(
16701 installedForUsers, currentUserId);
16702 if (DEBUG_INSTALL) {
16703 Slog.d(TAG, " user " + currentUserId + " => " + installed);
16705 ps.setInstalled(installed, currentUserId);
16707 // these install state changes will be persisted in the
16708 // upcoming call to mSettings.writeLPr().
16711 // It's implied that when a user requests installation, they want the app to be
16712 // installed and enabled.
16713 if (userId != UserHandle.USER_ALL) {
16714 ps.setInstalled(true, userId);
16715 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
16718 // When replacing an existing package, preserve the original install reason for all
16719 // users that had the package installed before.
16720 final Set<Integer> previousUserIds = new ArraySet<>();
16721 if (res.removedInfo != null && res.removedInfo.installReasons != null) {
16722 final int installReasonCount = res.removedInfo.installReasons.size();
16723 for (int i = 0; i < installReasonCount; i++) {
16724 final int previousUserId = res.removedInfo.installReasons.keyAt(i);
16725 final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
16726 ps.setInstallReason(previousInstallReason, previousUserId);
16727 previousUserIds.add(previousUserId);
16731 // Set install reason for users that are having the package newly installed.
16732 if (userId == UserHandle.USER_ALL) {
16733 for (int currentUserId : sUserManager.getUserIds()) {
16734 if (!previousUserIds.contains(currentUserId)) {
16735 ps.setInstallReason(installReason, currentUserId);
16738 } else if (!previousUserIds.contains(userId)) {
16739 ps.setInstallReason(installReason, userId);
16741 mSettings.writeKernelMappingLPr(ps);
16743 res.name = pkgName;
16744 res.uid = newPackage.applicationInfo.uid;
16745 res.pkg = newPackage;
16746 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
16747 mSettings.setInstallerPackageName(pkgName, installerPackageName);
16748 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16749 //to update install status
16750 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
16751 mSettings.writeLPr();
16752 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16755 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16758 private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
16760 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
16761 installPackageLI(args, res);
16763 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16767 private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
16768 final int installFlags = args.installFlags;
16769 final String installerPackageName = args.installerPackageName;
16770 final String volumeUuid = args.volumeUuid;
16771 final File tmpPackageFile = new File(args.getCodePath());
16772 final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
16773 final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
16774 || (args.volumeUuid != null));
16775 final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
16776 final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
16777 final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
16778 boolean replace = false;
16779 int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
16780 if (args.move != null) {
16781 // moving a complete application; perform an initial scan on the new install location
16782 scanFlags |= SCAN_INITIAL;
16784 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
16785 scanFlags |= SCAN_DONT_KILL_APP;
16788 scanFlags |= SCAN_AS_INSTANT_APP;
16791 scanFlags |= SCAN_AS_FULL_APP;
16794 // Result object to be returned
16795 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16797 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
16800 if (instantApp && (forwardLocked || onExternal)) {
16801 Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
16802 + " external=" + onExternal);
16803 res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16807 // Retrieve PackageSettings and parse package
16808 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
16809 | PackageParser.PARSE_ENFORCE_CODE
16810 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
16811 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
16812 | (instantApp ? PackageParser.PARSE_IS_EPHEMERAL : 0)
16813 | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
16814 PackageParser pp = new PackageParser();
16815 pp.setSeparateProcesses(mSeparateProcesses);
16816 pp.setDisplayMetrics(mMetrics);
16817 pp.setCallback(mPackageParserCallback);
16819 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
16820 final PackageParser.Package pkg;
16822 pkg = pp.parsePackage(tmpPackageFile, parseFlags);
16823 } catch (PackageParserException e) {
16824 res.setError("Failed parse during installPackageLI", e);
16827 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16830 // Instant apps must have target SDK >= O and have targetSanboxVersion >= 2
16831 if (instantApp && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
16832 Slog.w(TAG, "Instant app package " + pkg.packageName
16833 + " does not target O, this will be a fatal error.");
16834 // STOPSHIP: Make this a fatal error
16835 pkg.applicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
16837 if (instantApp && pkg.applicationInfo.targetSandboxVersion != 2) {
16838 Slog.w(TAG, "Instant app package " + pkg.packageName
16839 + " does not target targetSandboxVersion 2, this will be a fatal error.");
16840 // STOPSHIP: Make this a fatal error
16841 pkg.applicationInfo.targetSandboxVersion = 2;
16844 if (pkg.applicationInfo.isStaticSharedLibrary()) {
16845 // Static shared libraries have synthetic package names
16846 renameStaticSharedLibraryPackage(pkg);
16848 // No static shared libs on external storage
16850 Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
16851 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
16852 "Packages declaring static-shared libs cannot be updated");
16857 // If we are installing a clustered package add results for the children
16858 if (pkg.childPackages != null) {
16859 synchronized (mPackages) {
16860 final int childCount = pkg.childPackages.size();
16861 for (int i = 0; i < childCount; i++) {
16862 PackageParser.Package childPkg = pkg.childPackages.get(i);
16863 PackageInstalledInfo childRes = new PackageInstalledInfo();
16864 childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16865 childRes.pkg = childPkg;
16866 childRes.name = childPkg.packageName;
16867 PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16868 if (childPs != null) {
16869 childRes.origUsers = childPs.queryInstalledUsers(
16870 sUserManager.getUserIds(), true);
16872 if ((mPackages.containsKey(childPkg.packageName))) {
16873 childRes.removedInfo = new PackageRemovedInfo(this);
16874 childRes.removedInfo.removedPackage = childPkg.packageName;
16876 if (res.addedChildPackages == null) {
16877 res.addedChildPackages = new ArrayMap<>();
16879 res.addedChildPackages.put(childPkg.packageName, childRes);
16884 // If package doesn't declare API override, mark that we have an install
16885 // time CPU ABI override.
16886 if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
16887 pkg.cpuAbiOverride = args.abiOverride;
16890 String pkgName = res.name = pkg.packageName;
16891 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
16892 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
16893 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
16899 // either use what we've been given or parse directly from the APK
16900 if (args.certificates != null) {
16902 PackageParser.populateCertificates(pkg, args.certificates);
16903 } catch (PackageParserException e) {
16904 // there was something wrong with the certificates we were given;
16905 // try to pull them from the APK
16906 PackageParser.collectCertificates(pkg, parseFlags);
16909 PackageParser.collectCertificates(pkg, parseFlags);
16911 } catch (PackageParserException e) {
16912 res.setError("Failed collect during installPackageLI", e);
16916 // Get rid of all references to package scan path via parser.
16918 String oldCodePath = null;
16919 boolean systemApp = false;
16920 synchronized (mPackages) {
16921 // Check if installing already existing package
16922 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
16923 String oldName = mSettings.getRenamedPackageLPr(pkgName);
16924 if (pkg.mOriginalPackages != null
16925 && pkg.mOriginalPackages.contains(oldName)
16926 && mPackages.containsKey(oldName)) {
16927 // This package is derived from an original package,
16928 // and this device has been updating from that original
16929 // name. We must continue using the original name, so
16930 // rename the new package here.
16931 pkg.setPackageName(oldName);
16932 pkgName = pkg.packageName;
16934 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
16935 + oldName + " pkgName=" + pkgName);
16936 } else if (mPackages.containsKey(pkgName)) {
16937 // This package, under its official name, already exists
16938 // on the device; we should replace it.
16940 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
16943 // Child packages are installed through the parent package
16944 if (pkg.parentPackage != null) {
16945 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
16946 "Package " + pkg.packageName + " is child of package "
16947 + pkg.parentPackage.parentPackage + ". Child packages "
16948 + "can be updated only through the parent package.");
16953 // Prevent apps opting out from runtime permissions
16954 PackageParser.Package oldPackage = mPackages.get(pkgName);
16955 final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
16956 final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
16957 if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
16958 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
16959 res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
16960 "Package " + pkg.packageName + " new target SDK " + newTargetSdk
16961 + " doesn't support runtime permissions but the old"
16962 + " target SDK " + oldTargetSdk + " does.");
16965 // Prevent apps from downgrading their targetSandbox.
16966 final int oldTargetSandbox = oldPackage.applicationInfo.targetSandboxVersion;
16967 final int newTargetSandbox = pkg.applicationInfo.targetSandboxVersion;
16968 if (oldTargetSandbox == 2 && newTargetSandbox != 2) {
16969 res.setError(PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
16970 "Package " + pkg.packageName + " new target sandbox "
16971 + newTargetSandbox + " is incompatible with the previous value of"
16972 + oldTargetSandbox + ".");
16976 // Prevent installing of child packages
16977 if (oldPackage.parentPackage != null) {
16978 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
16979 "Package " + pkg.packageName + " is child of package "
16980 + oldPackage.parentPackage + ". Child packages "
16981 + "can be updated only through the parent package.");
16987 PackageSetting ps = mSettings.mPackages.get(pkgName);
16989 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
16991 // Static shared libs have same package with different versions where
16992 // we internally use a synthetic package name to allow multiple versions
16993 // of the same package, therefore we need to compare signatures against
16994 // the package setting for the latest library version.
16995 PackageSetting signatureCheckPs = ps;
16996 if (pkg.applicationInfo.isStaticSharedLibrary()) {
16997 SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
16998 if (libraryEntry != null) {
16999 signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
17003 // Quick sanity check that we're signed correctly if updating;
17004 // we'll check this again later when scanning, but we want to
17005 // bail early here before tripping over redefined permissions.
17006 if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
17007 if (!checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
17008 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
17009 + pkg.packageName + " upgrade keys do not match the "
17010 + "previously installed version");
17015 verifySignaturesLP(signatureCheckPs, pkg);
17016 } catch (PackageManagerException e) {
17017 res.setError(e.error, e.getMessage());
17022 oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
17023 if (ps.pkg != null && ps.pkg.applicationInfo != null) {
17024 systemApp = (ps.pkg.applicationInfo.flags &
17025 ApplicationInfo.FLAG_SYSTEM) != 0;
17027 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
17030 int N = pkg.permissions.size();
17031 for (int i = N-1; i >= 0; i--) {
17032 PackageParser.Permission perm = pkg.permissions.get(i);
17033 BasePermission bp = mSettings.mPermissions.get(perm.info.name);
17035 // Don't allow anyone but the platform to define ephemeral permissions.
17036 if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_EPHEMERAL) != 0
17037 && !PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
17038 Slog.w(TAG, "Package " + pkg.packageName
17039 + " attempting to delcare ephemeral permission "
17040 + perm.info.name + "; Removing ephemeral.");
17041 perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_EPHEMERAL;
17043 // Check whether the newly-scanned package wants to define an already-defined perm
17045 // If the defining package is signed with our cert, it's okay. This
17046 // also includes the "updating the same package" case, of course.
17047 // "updating same package" could also involve key-rotation.
17048 final boolean sigsOk;
17049 if (bp.sourcePackage.equals(pkg.packageName)
17050 && (bp.packageSetting instanceof PackageSetting)
17051 && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting,
17053 sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
17055 sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
17056 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
17059 // If the owning package is the system itself, we log but allow
17060 // install to proceed; we fail the install on all other permission
17062 if (!bp.sourcePackage.equals("android")) {
17063 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
17064 + pkg.packageName + " attempting to redeclare permission "
17065 + perm.info.name + " already owned by " + bp.sourcePackage);
17066 res.origPermission = perm.info.name;
17067 res.origPackage = bp.sourcePackage;
17070 Slog.w(TAG, "Package " + pkg.packageName
17071 + " attempting to redeclare system permission "
17072 + perm.info.name + "; ignoring new declaration");
17073 pkg.permissions.remove(i);
17075 } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
17076 // Prevent apps to change protection level to dangerous from any other
17077 // type as this would allow a privilege escalation where an app adds a
17078 // normal/signature permission in other app's group and later redefines
17079 // it as dangerous leading to the group auto-grant.
17080 if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
17081 == PermissionInfo.PROTECTION_DANGEROUS) {
17082 if (bp != null && !bp.isRuntime()) {
17083 Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
17084 + "non-runtime permission " + perm.info.name
17085 + " to runtime; keeping old protection level");
17086 perm.info.protectionLevel = bp.protectionLevel;
17096 // Abort update; system app can't be replaced with app on sdcard
17097 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
17098 "Cannot install updates to system apps on sdcard");
17100 } else if (instantApp) {
17101 // Abort update; system app can't be replaced with an instant app
17102 res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
17103 "Cannot update a system app with an instant app");
17108 if (args.move != null) {
17109 // We did an in-place move, so dex is ready to roll
17110 scanFlags |= SCAN_NO_DEX;
17111 scanFlags |= SCAN_MOVE;
17113 synchronized (mPackages) {
17114 final PackageSetting ps = mSettings.mPackages.get(pkgName);
17116 res.setError(INSTALL_FAILED_INTERNAL_ERROR,
17117 "Missing settings for moved package " + pkgName);
17120 // We moved the entire application as-is, so bring over the
17121 // previously derived ABI information.
17122 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
17123 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
17126 } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
17127 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
17128 scanFlags |= SCAN_NO_DEX;
17131 String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
17132 args.abiOverride : pkg.cpuAbiOverride);
17133 derivePackageAbi(pkg, new File(pkg.codePath), abiOverride,
17134 true /*extractLibs*/, mAppLib32InstallDir);
17135 } catch (PackageManagerException pme) {
17136 Slog.e(TAG, "Error deriving application ABI", pme);
17137 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
17141 // Shared libraries for the package need to be updated.
17142 synchronized (mPackages) {
17144 updateSharedLibrariesLPr(pkg, null);
17145 } catch (PackageManagerException e) {
17146 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
17150 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
17151 // Do not run PackageDexOptimizer through the local performDexOpt
17152 // method because `pkg` may not be in `mPackages` yet.
17154 // Also, don't fail application installs if the dexopt step fails.
17155 mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
17156 null /* instructionSets */, false /* checkProfiles */,
17157 getCompilerFilterForReason(REASON_INSTALL),
17158 getOrCreateCompilerPackageStats(pkg),
17159 mDexManager.isUsedByOtherApps(pkg.packageName));
17160 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17162 // Notify BackgroundDexOptService that the package has been changed.
17163 // If this is an update of a package which used to fail to compile,
17164 // BDOS will remove it from its blacklist.
17165 // TODO: Layering violation
17166 BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
17169 if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
17170 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
17174 startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
17176 try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
17177 "installPackageLI")) {
17179 if (pkg.applicationInfo.isStaticSharedLibrary()) {
17180 // Static libs have a synthetic package name containing the version
17181 // and cannot be updated as an update would get a new package name,
17182 // unless this is the exact same version code which is useful for
17184 PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
17185 if (existingPkg != null && existingPkg.mVersionCode != pkg.mVersionCode) {
17186 res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
17187 + "static-shared libs cannot be updated");
17191 replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
17192 installerPackageName, res, args.installReason);
17194 installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
17195 args.user, installerPackageName, volumeUuid, res, args.installReason);
17199 synchronized (mPackages) {
17200 final PackageSetting ps = mSettings.mPackages.get(pkgName);
17202 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
17203 ps.setUpdateAvailable(false /*updateAvailable*/);
17206 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17207 for (int i = 0; i < childCount; i++) {
17208 PackageParser.Package childPkg = pkg.childPackages.get(i);
17209 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
17210 PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17211 if (childPs != null) {
17212 childRes.newUsers = childPs.queryInstalledUsers(
17213 sUserManager.getUserIds(), true);
17217 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
17218 updateSequenceNumberLP(pkgName, res.newUsers);
17219 updateInstantAppInstallerLocked(pkgName);
17224 private void startIntentFilterVerifications(int userId, boolean replacing,
17225 PackageParser.Package pkg) {
17226 if (mIntentFilterVerifierComponent == null) {
17227 Slog.w(TAG, "No IntentFilter verification will not be done as "
17228 + "there is no IntentFilterVerifier available!");
17232 final int verifierUid = getPackageUid(
17233 mIntentFilterVerifierComponent.getPackageName(),
17234 MATCH_DEBUG_TRIAGED_MISSING,
17235 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
17237 Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
17238 msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
17239 mHandler.sendMessage(msg);
17241 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17242 for (int i = 0; i < childCount; i++) {
17243 PackageParser.Package childPkg = pkg.childPackages.get(i);
17244 msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
17245 msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
17246 mHandler.sendMessage(msg);
17250 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
17251 PackageParser.Package pkg) {
17252 int size = pkg.activities.size();
17254 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17255 "No activity, so no need to verify any IntentFilter!");
17259 final boolean hasDomainURLs = hasDomainURLs(pkg);
17260 if (!hasDomainURLs) {
17261 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17262 "No domain URLs, so no need to verify any IntentFilter!");
17266 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
17267 + " if any IntentFilter from the " + size
17268 + " Activities needs verification ...");
17271 final String packageName = pkg.packageName;
17273 synchronized (mPackages) {
17274 // If this is a new install and we see that we've already run verification for this
17275 // package, we have nothing to do: it means the state was restored from backup.
17277 IntentFilterVerificationInfo ivi =
17278 mSettings.getIntentFilterVerificationLPr(packageName);
17280 if (DEBUG_DOMAIN_VERIFICATION) {
17281 Slog.i(TAG, "Package " + packageName+ " already verified: status="
17282 + ivi.getStatusString());
17288 // If any filters need to be verified, then all need to be.
17289 boolean needToVerify = false;
17290 for (PackageParser.Activity a : pkg.activities) {
17291 for (ActivityIntentInfo filter : a.intents) {
17292 if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
17293 if (DEBUG_DOMAIN_VERIFICATION) {
17294 Slog.d(TAG, "Intent filter needs verification, so processing all filters");
17296 needToVerify = true;
17302 if (needToVerify) {
17303 final int verificationId = mIntentFilterVerificationToken++;
17304 for (PackageParser.Activity a : pkg.activities) {
17305 for (ActivityIntentInfo filter : a.intents) {
17306 if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
17307 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17308 "Verification needed for IntentFilter:" + filter.toString());
17309 mIntentFilterVerifier.addOneIntentFilterVerification(
17310 verifierUid, userId, verificationId, filter, packageName);
17319 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
17320 + " IntentFilter verification" + (count > 1 ? "s" : "")
17321 + " for userId:" + userId);
17322 mIntentFilterVerifier.startVerifications(userId);
17324 if (DEBUG_DOMAIN_VERIFICATION) {
17325 Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
17330 private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
17331 final ComponentName cn = filter.activity.getComponentName();
17332 final String packageName = cn.getPackageName();
17334 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
17339 int status = ivi.getStatus();
17341 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
17342 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
17351 private static boolean isMultiArch(ApplicationInfo info) {
17352 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
17355 private static boolean isExternal(PackageParser.Package pkg) {
17356 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17359 private static boolean isExternal(PackageSetting ps) {
17360 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17363 private static boolean isSystemApp(PackageParser.Package pkg) {
17364 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
17367 private static boolean isPrivilegedApp(PackageParser.Package pkg) {
17368 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
17371 private static boolean hasDomainURLs(PackageParser.Package pkg) {
17372 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
17375 private static boolean isSystemApp(PackageSetting ps) {
17376 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
17379 private static boolean isUpdatedSystemApp(PackageSetting ps) {
17380 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
17383 private int packageFlagsToInstallFlags(PackageSetting ps) {
17384 int installFlags = 0;
17385 if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
17386 // This existing package was an external ASEC install when we have
17387 // the external flag without a UUID
17388 installFlags |= PackageManager.INSTALL_EXTERNAL;
17390 if (ps.isForwardLocked()) {
17391 installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
17393 return installFlags;
17396 private String getVolumeUuidForPackage(PackageParser.Package pkg) {
17397 if (isExternal(pkg)) {
17398 if (TextUtils.isEmpty(pkg.volumeUuid)) {
17399 return StorageManager.UUID_PRIMARY_PHYSICAL;
17401 return pkg.volumeUuid;
17404 return StorageManager.UUID_PRIVATE_INTERNAL;
17408 private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
17409 if (isExternal(pkg)) {
17410 if (TextUtils.isEmpty(pkg.volumeUuid)) {
17411 return mSettings.getExternalVersion();
17413 return mSettings.findOrCreateVersion(pkg.volumeUuid);
17416 return mSettings.getInternalVersion();
17420 private void deleteTempPackageFiles() {
17421 final FilenameFilter filter = new FilenameFilter() {
17422 public boolean accept(File dir, String name) {
17423 return name.startsWith("vmdl") && name.endsWith(".tmp");
17426 for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
17432 public void deletePackageAsUser(String packageName, int versionCode,
17433 IPackageDeleteObserver observer, int userId, int flags) {
17434 deletePackageVersioned(new VersionedPackage(packageName, versionCode),
17435 new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
17439 public void deletePackageVersioned(VersionedPackage versionedPackage,
17440 final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
17441 mContext.enforceCallingOrSelfPermission(
17442 android.Manifest.permission.DELETE_PACKAGES, null);
17443 Preconditions.checkNotNull(versionedPackage);
17444 Preconditions.checkNotNull(observer);
17445 Preconditions.checkArgumentInRange(versionedPackage.getVersionCode(),
17446 PackageManager.VERSION_CODE_HIGHEST,
17447 Integer.MAX_VALUE, "versionCode must be >= -1");
17449 final String packageName = versionedPackage.getPackageName();
17450 // TODO: We will change version code to long, so in the new API it is long
17451 final int versionCode = (int) versionedPackage.getVersionCode();
17452 final String internalPackageName;
17453 synchronized (mPackages) {
17454 // Normalize package name to handle renamed packages and static libs
17455 internalPackageName = resolveInternalPackageNameLPr(versionedPackage.getPackageName(),
17456 // TODO: We will change version code to long, so in the new API it is long
17457 (int) versionedPackage.getVersionCode());
17460 final int uid = Binder.getCallingUid();
17461 if (!isOrphaned(internalPackageName)
17462 && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
17464 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
17465 intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
17466 intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
17467 observer.onUserActionRequired(intent);
17468 } catch (RemoteException re) {
17472 final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
17473 final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
17474 if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
17475 mContext.enforceCallingOrSelfPermission(
17476 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
17477 "deletePackage for user " + userId);
17480 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
17482 observer.onPackageDeleted(packageName,
17483 PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
17484 } catch (RemoteException re) {
17489 if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
17491 observer.onPackageDeleted(packageName,
17492 PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
17493 } catch (RemoteException re) {
17498 if (DEBUG_REMOVE) {
17499 Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
17500 + " deleteAllUsers: " + deleteAllUsers + " version="
17501 + (versionCode == PackageManager.VERSION_CODE_HIGHEST
17502 ? "VERSION_CODE_HIGHEST" : versionCode));
17504 // Queue up an async operation since the package deletion may take a little while.
17505 mHandler.post(new Runnable() {
17506 public void run() {
17507 mHandler.removeCallbacks(this);
17509 if (!deleteAllUsers) {
17510 returnCode = deletePackageX(internalPackageName, versionCode,
17511 userId, deleteFlags);
17513 int[] blockUninstallUserIds = getBlockUninstallForUsers(
17514 internalPackageName, users);
17515 // If nobody is blocking uninstall, proceed with delete for all users
17516 if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
17517 returnCode = deletePackageX(internalPackageName, versionCode,
17518 userId, deleteFlags);
17520 // Otherwise uninstall individually for users with blockUninstalls=false
17521 final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
17522 for (int userId : users) {
17523 if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
17524 returnCode = deletePackageX(internalPackageName, versionCode,
17525 userId, userFlags);
17526 if (returnCode != PackageManager.DELETE_SUCCEEDED) {
17527 Slog.w(TAG, "Package delete failed for user " + userId
17528 + ", returnCode " + returnCode);
17532 // The app has only been marked uninstalled for certain users.
17533 // We still need to report that delete was blocked
17534 returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
17538 observer.onPackageDeleted(packageName, returnCode, null);
17539 } catch (RemoteException e) {
17540 Log.i(TAG, "Observer no longer exists.");
17546 private String resolveExternalPackageNameLPr(PackageParser.Package pkg) {
17547 if (pkg.staticSharedLibName != null) {
17548 return pkg.manifestPackageName;
17550 return pkg.packageName;
17553 private String resolveInternalPackageNameLPr(String packageName, int versionCode) {
17554 // Handle renamed packages
17555 String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
17556 packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
17558 // Is this a static library?
17559 SparseArray<SharedLibraryEntry> versionedLib =
17560 mStaticLibsByDeclaringPackage.get(packageName);
17561 if (versionedLib == null || versionedLib.size() <= 0) {
17562 return packageName;
17565 // Figure out which lib versions the caller can see
17566 SparseIntArray versionsCallerCanSee = null;
17567 final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
17568 if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
17569 && callingAppId != Process.ROOT_UID) {
17570 versionsCallerCanSee = new SparseIntArray();
17571 String libName = versionedLib.valueAt(0).info.getName();
17572 String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
17573 if (uidPackages != null) {
17574 for (String uidPackage : uidPackages) {
17575 PackageSetting ps = mSettings.getPackageLPr(uidPackage);
17576 final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
17578 final int libVersion = ps.usesStaticLibrariesVersions[libIdx];
17579 versionsCallerCanSee.append(libVersion, libVersion);
17585 // Caller can see nothing - done
17586 if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
17587 return packageName;
17590 // Find the version the caller can see and the app version code
17591 SharedLibraryEntry highestVersion = null;
17592 final int versionCount = versionedLib.size();
17593 for (int i = 0; i < versionCount; i++) {
17594 SharedLibraryEntry libEntry = versionedLib.valueAt(i);
17595 if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
17596 libEntry.info.getVersion()) < 0) {
17599 // TODO: We will change version code to long, so in the new API it is long
17600 final int libVersionCode = (int) libEntry.info.getDeclaringPackage().getVersionCode();
17601 if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
17602 if (libVersionCode == versionCode) {
17603 return libEntry.apk;
17605 } else if (highestVersion == null) {
17606 highestVersion = libEntry;
17607 } else if (libVersionCode > highestVersion.info
17608 .getDeclaringPackage().getVersionCode()) {
17609 highestVersion = libEntry;
17613 if (highestVersion != null) {
17614 return highestVersion.apk;
17617 return packageName;
17620 private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
17621 if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
17622 || callingUid == Process.SYSTEM_UID) {
17625 final int callingUserId = UserHandle.getUserId(callingUid);
17626 // If the caller installed the pkgName, then allow it to silently uninstall.
17627 if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
17631 // Allow package verifier to silently uninstall.
17632 if (mRequiredVerifierPackage != null &&
17633 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
17637 // Allow package uninstaller to silently uninstall.
17638 if (mRequiredUninstallerPackage != null &&
17639 callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
17643 // Allow storage manager to silently uninstall.
17644 if (mStorageManagerPackage != null &&
17645 callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
17651 private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
17652 int[] result = EMPTY_INT_ARRAY;
17653 for (int userId : userIds) {
17654 if (getBlockUninstallForUser(packageName, userId)) {
17655 result = ArrayUtils.appendInt(result, userId);
17662 public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
17663 return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
17666 private boolean isPackageDeviceAdmin(String packageName, int userId) {
17667 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
17668 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
17671 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
17672 /* callingUserOnly =*/ false);
17673 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
17674 : deviceOwnerComponentName.getPackageName();
17675 // Does the package contains the device owner?
17676 // TODO Do we have to do it even if userId != UserHandle.USER_ALL? Otherwise,
17677 // this check is probably not needed, since DO should be registered as a device
17678 // admin on some user too. (Original bug for this: b/17657954)
17679 if (packageName.equals(deviceOwnerPackageName)) {
17682 // Does it contain a device admin for any user?
17684 if (userId == UserHandle.USER_ALL) {
17685 users = sUserManager.getUserIds();
17687 users = new int[]{userId};
17689 for (int i = 0; i < users.length; ++i) {
17690 if (dpm.packageHasActiveAdmins(packageName, users[i])) {
17695 } catch (RemoteException e) {
17700 private boolean shouldKeepUninstalledPackageLPr(String packageName) {
17701 return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
17705 * This method is an internal method that could be get invoked either
17706 * to delete an installed package or to clean up a failed installation.
17707 * After deleting an installed package, a broadcast is sent to notify any
17708 * listeners that the package has been removed. For cleaning up a failed
17709 * installation, the broadcast is not necessary since the package's
17710 * installation wouldn't have sent the initial broadcast either
17711 * The key steps in deleting a package are
17712 * deleting the package information in internal structures like mPackages,
17713 * deleting the packages base directories through installd
17714 * updating mSettings to reflect current status
17715 * persisting settings for later use
17716 * sending a broadcast if necessary
17718 private int deletePackageX(String packageName, int versionCode, int userId, int deleteFlags) {
17719 final PackageRemovedInfo info = new PackageRemovedInfo(this);
17722 final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
17723 ? UserHandle.USER_ALL : userId;
17725 if (isPackageDeviceAdmin(packageName, removeUser)) {
17726 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
17727 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
17730 PackageSetting uninstalledPs = null;
17731 PackageParser.Package pkg = null;
17733 // for the uninstall-updates case and restricted profiles, remember the per-
17734 // user handle installed state
17736 synchronized (mPackages) {
17737 uninstalledPs = mSettings.mPackages.get(packageName);
17738 if (uninstalledPs == null) {
17739 Slog.w(TAG, "Not removing non-existent package " + packageName);
17740 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17743 if (versionCode != PackageManager.VERSION_CODE_HIGHEST
17744 && uninstalledPs.versionCode != versionCode) {
17745 Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
17746 + uninstalledPs.versionCode + " != " + versionCode);
17747 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17750 // Static shared libs can be declared by any package, so let us not
17751 // allow removing a package if it provides a lib others depend on.
17752 pkg = mPackages.get(packageName);
17753 if (pkg != null && pkg.staticSharedLibName != null) {
17754 SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName,
17755 pkg.staticSharedLibVersion);
17756 if (libEntry != null) {
17757 List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
17758 libEntry.info, 0, userId);
17759 if (!ArrayUtils.isEmpty(libClientPackages)) {
17760 Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
17761 + " hosting lib " + libEntry.info.getName() + " version "
17762 + libEntry.info.getVersion() + " used by " + libClientPackages);
17763 return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
17768 allUsers = sUserManager.getUserIds();
17769 info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
17772 final int freezeUser;
17773 if (isUpdatedSystemApp(uninstalledPs)
17774 && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
17775 // We're downgrading a system app, which will apply to all users, so
17776 // freeze them all during the downgrade
17777 freezeUser = UserHandle.USER_ALL;
17779 freezeUser = removeUser;
17782 synchronized (mInstallLock) {
17783 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
17784 try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
17785 deleteFlags, "deletePackageX")) {
17786 res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
17787 deleteFlags | FLAGS_REMOVE_CHATTY, info, true, null);
17789 synchronized (mPackages) {
17792 mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
17794 updateSequenceNumberLP(packageName, info.removedUsers);
17795 updateInstantAppInstallerLocked(packageName);
17801 final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
17802 info.sendPackageRemovedBroadcasts(killApp);
17803 info.sendSystemPackageUpdatedBroadcasts();
17804 info.sendSystemPackageAppearedBroadcasts();
17806 // Force a gc here.
17807 Runtime.getRuntime().gc();
17808 // Delete the resources here after sending the broadcast to let
17809 // other processes clean up before deleting resources.
17810 if (info.args != null) {
17811 synchronized (mInstallLock) {
17812 info.args.doPostDeleteLI(true);
17816 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17819 static class PackageRemovedInfo {
17820 final PackageSender packageSender;
17821 String removedPackage;
17823 int removedAppId = -1;
17825 int[] removedUsers = null;
17826 int[] broadcastUsers = null;
17827 SparseArray<Integer> installReasons;
17828 boolean isRemovedPackageSystemUpdate = false;
17830 boolean dataRemoved;
17831 boolean removedForAllUsers;
17832 boolean isStaticSharedLib;
17833 // Clean up resources deleted packages.
17834 InstallArgs args = null;
17835 ArrayMap<String, PackageRemovedInfo> removedChildPackages;
17836 ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
17838 PackageRemovedInfo(PackageSender packageSender) {
17839 this.packageSender = packageSender;
17842 void sendPackageRemovedBroadcasts(boolean killApp) {
17843 sendPackageRemovedBroadcastInternal(killApp);
17844 final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
17845 for (int i = 0; i < childCount; i++) {
17846 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
17847 childInfo.sendPackageRemovedBroadcastInternal(killApp);
17851 void sendSystemPackageUpdatedBroadcasts() {
17852 if (isRemovedPackageSystemUpdate) {
17853 sendSystemPackageUpdatedBroadcastsInternal();
17854 final int childCount = (removedChildPackages != null)
17855 ? removedChildPackages.size() : 0;
17856 for (int i = 0; i < childCount; i++) {
17857 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
17858 if (childInfo.isRemovedPackageSystemUpdate) {
17859 childInfo.sendSystemPackageUpdatedBroadcastsInternal();
17865 void sendSystemPackageAppearedBroadcasts() {
17866 final int packageCount = (appearedChildPackages != null)
17867 ? appearedChildPackages.size() : 0;
17868 for (int i = 0; i < packageCount; i++) {
17869 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
17870 packageSender.sendPackageAddedForNewUsers(installedInfo.name,
17871 true, UserHandle.getAppId(installedInfo.uid),
17872 installedInfo.newUsers);
17876 private void sendSystemPackageUpdatedBroadcastsInternal() {
17877 Bundle extras = new Bundle(2);
17878 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
17879 extras.putBoolean(Intent.EXTRA_REPLACING, true);
17880 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
17881 removedPackage, extras, 0, null, null, null);
17882 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
17883 removedPackage, extras, 0, null, null, null);
17884 packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
17885 null, null, 0, removedPackage, null, null);
17888 private void sendPackageRemovedBroadcastInternal(boolean killApp) {
17889 // Don't send static shared library removal broadcasts as these
17890 // libs are visible only the the apps that depend on them an one
17891 // cannot remove the library if it has a dependency.
17892 if (isStaticSharedLib) {
17895 Bundle extras = new Bundle(2);
17896 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
17897 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
17898 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
17899 if (isUpdate || isRemovedPackageSystemUpdate) {
17900 extras.putBoolean(Intent.EXTRA_REPLACING, true);
17902 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
17903 if (removedPackage != null) {
17904 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
17905 removedPackage, extras, 0, null, null, broadcastUsers);
17906 if (dataRemoved && !isRemovedPackageSystemUpdate) {
17907 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
17908 removedPackage, extras,
17909 Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
17910 null, null, broadcastUsers);
17913 if (removedAppId >= 0) {
17914 packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras,
17915 Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, null, null, broadcastUsers);
17919 void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
17920 removedUsers = userIds;
17921 if (removedUsers == null) {
17922 broadcastUsers = null;
17926 broadcastUsers = EMPTY_INT_ARRAY;
17927 for (int i = userIds.length - 1; i >= 0; --i) {
17928 final int userId = userIds[i];
17929 if (deletedPackageSetting.getInstantApp(userId)) {
17932 broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
17938 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
17939 * flag is not set, the data directory is removed as well.
17940 * make sure this flag is set for partially installed apps. If not its meaningless to
17941 * delete a partially installed application.
17943 private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
17944 PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
17945 String packageName = ps.name;
17946 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
17947 // Retrieve object to delete permissions for shared user later on
17948 final PackageParser.Package deletedPkg;
17949 final PackageSetting deletedPs;
17951 synchronized (mPackages) {
17952 deletedPkg = mPackages.get(packageName);
17953 deletedPs = mSettings.mPackages.get(packageName);
17954 if (outInfo != null) {
17955 outInfo.removedPackage = packageName;
17956 outInfo.isStaticSharedLib = deletedPkg != null
17957 && deletedPkg.staticSharedLibName != null;
17958 outInfo.populateUsers(deletedPs == null ? null
17959 : deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true), deletedPs);
17963 removePackageLI(ps, (flags & FLAGS_REMOVE_CHATTY) != 0);
17965 if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
17966 final PackageParser.Package resolvedPkg;
17967 if (deletedPkg != null) {
17968 resolvedPkg = deletedPkg;
17970 // We don't have a parsed package when it lives on an ejected
17971 // adopted storage device, so fake something together
17972 resolvedPkg = new PackageParser.Package(ps.name);
17973 resolvedPkg.setVolumeUuid(ps.volumeUuid);
17975 destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
17976 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
17977 destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
17978 if (outInfo != null) {
17979 outInfo.dataRemoved = true;
17981 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
17984 int removedAppId = -1;
17987 synchronized (mPackages) {
17988 boolean installedStateChanged = false;
17989 if (deletedPs != null) {
17990 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
17991 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
17992 clearDefaultBrowserIfNeeded(packageName);
17993 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
17994 removedAppId = mSettings.removePackageLPw(packageName);
17995 if (outInfo != null) {
17996 outInfo.removedAppId = removedAppId;
17998 updatePermissionsLPw(deletedPs.name, null, 0);
17999 if (deletedPs.sharedUser != null) {
18000 // Remove permissions associated with package. Since runtime
18001 // permissions are per user we have to kill the removed package
18002 // or packages running under the shared user of the removed
18003 // package if revoking the permissions requested only by the removed
18004 // package is successful and this causes a change in gids.
18005 for (int userId : UserManagerService.getInstance().getUserIds()) {
18006 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
18008 if (userIdToKill == UserHandle.USER_ALL
18009 || userIdToKill >= UserHandle.USER_SYSTEM) {
18010 // If gids changed for this user, kill all affected packages.
18011 mHandler.post(new Runnable() {
18013 public void run() {
18014 // This has to happen with no lock held.
18015 killApplication(deletedPs.name, deletedPs.appId,
18016 KILL_APP_REASON_GIDS_CHANGED);
18023 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
18025 // make sure to preserve per-user disabled state if this removal was just
18026 // a downgrade of a system app to the factory package
18027 if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
18028 if (DEBUG_REMOVE) {
18029 Slog.d(TAG, "Propagating install state across downgrade");
18031 for (int userId : allUserHandles) {
18032 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
18033 if (DEBUG_REMOVE) {
18034 Slog.d(TAG, " user " + userId + " => " + installed);
18036 if (installed != ps.getInstalled(userId)) {
18037 installedStateChanged = true;
18039 ps.setInstalled(installed, userId);
18043 // can downgrade to reader
18044 if (writeSettings) {
18045 // Save settings now
18046 mSettings.writeLPr();
18048 if (installedStateChanged) {
18049 mSettings.writeKernelMappingLPr(ps);
18052 if (removedAppId != -1) {
18053 // A user ID was deleted here. Go through all users and remove it
18055 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId);
18059 static boolean locationIsPrivileged(File path) {
18061 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
18062 .getCanonicalPath();
18063 return path.getCanonicalPath().startsWith(privilegedAppDir);
18064 } catch (IOException e) {
18065 Slog.e(TAG, "Unable to access code path " + path);
18071 * Tries to delete system package.
18073 private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
18074 PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
18075 boolean writeSettings) {
18076 if (deletedPs.parentPackageName != null) {
18077 Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
18081 final boolean applyUserRestrictions
18082 = (allUserHandles != null) && (outInfo.origUsers != null);
18083 final PackageSetting disabledPs;
18084 // Confirm if the system package has been updated
18085 // An updated system app can be deleted. This will also have to restore
18086 // the system pkg from system partition
18088 synchronized (mPackages) {
18089 disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
18092 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
18093 + " disabledPs=" + disabledPs);
18095 if (disabledPs == null) {
18096 Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
18098 } else if (DEBUG_REMOVE) {
18099 Slog.d(TAG, "Deleting system pkg from data partition");
18102 if (DEBUG_REMOVE) {
18103 if (applyUserRestrictions) {
18104 Slog.d(TAG, "Remembering install states:");
18105 for (int userId : allUserHandles) {
18106 final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
18107 Slog.d(TAG, " u=" + userId + " inst=" + finstalled);
18112 // Delete the updated package
18113 outInfo.isRemovedPackageSystemUpdate = true;
18114 if (outInfo.removedChildPackages != null) {
18115 final int childCount = (deletedPs.childPackageNames != null)
18116 ? deletedPs.childPackageNames.size() : 0;
18117 for (int i = 0; i < childCount; i++) {
18118 String childPackageName = deletedPs.childPackageNames.get(i);
18119 if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
18120 .contains(childPackageName)) {
18121 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
18123 if (childInfo != null) {
18124 childInfo.isRemovedPackageSystemUpdate = true;
18130 if (disabledPs.versionCode < deletedPs.versionCode) {
18131 // Delete data for downgrades
18132 flags &= ~PackageManager.DELETE_KEEP_DATA;
18134 // Preserve data by setting flag
18135 flags |= PackageManager.DELETE_KEEP_DATA;
18138 boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
18139 outInfo, writeSettings, disabledPs.pkg);
18145 synchronized (mPackages) {
18146 // Reinstate the old system package
18147 enableSystemPackageLPw(disabledPs.pkg);
18148 // Remove any native libraries from the upgraded package.
18149 removeNativeBinariesLI(deletedPs);
18152 // Install the system package
18153 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
18154 int parseFlags = mDefParseFlags
18155 | PackageParser.PARSE_MUST_BE_APK
18156 | PackageParser.PARSE_IS_SYSTEM
18157 | PackageParser.PARSE_IS_SYSTEM_DIR;
18158 if (locationIsPrivileged(disabledPs.codePath)) {
18159 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
18162 final PackageParser.Package newPkg;
18164 newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, 0 /* scanFlags */,
18165 0 /* currentTime */, null);
18166 } catch (PackageManagerException e) {
18167 Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
18173 // update shared libraries for the newly re-installed system package
18174 updateSharedLibrariesLPr(newPkg, null);
18175 } catch (PackageManagerException e) {
18176 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
18179 prepareAppDataAfterInstallLIF(newPkg);
18182 synchronized (mPackages) {
18183 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
18185 // Propagate the permissions state as we do not want to drop on the floor
18186 // runtime permissions. The update permissions method below will take
18187 // care of removing obsolete permissions and grant install permissions.
18188 ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState());
18189 updatePermissionsLPw(newPkg.packageName, newPkg,
18190 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
18192 if (applyUserRestrictions) {
18193 boolean installedStateChanged = false;
18194 if (DEBUG_REMOVE) {
18195 Slog.d(TAG, "Propagating install state across reinstall");
18197 for (int userId : allUserHandles) {
18198 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
18199 if (DEBUG_REMOVE) {
18200 Slog.d(TAG, " user " + userId + " => " + installed);
18202 if (installed != ps.getInstalled(userId)) {
18203 installedStateChanged = true;
18205 ps.setInstalled(installed, userId);
18207 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
18209 // Regardless of writeSettings we need to ensure that this restriction
18210 // state propagation is persisted
18211 mSettings.writeAllUsersPackageRestrictionsLPr();
18212 if (installedStateChanged) {
18213 mSettings.writeKernelMappingLPr(ps);
18216 // can downgrade to reader here
18217 if (writeSettings) {
18218 mSettings.writeLPr();
18224 private boolean deleteInstalledPackageLIF(PackageSetting ps,
18225 boolean deleteCodeAndResources, int flags, int[] allUserHandles,
18226 PackageRemovedInfo outInfo, boolean writeSettings,
18227 PackageParser.Package replacingPackage) {
18228 synchronized (mPackages) {
18229 if (outInfo != null) {
18230 outInfo.uid = ps.appId;
18233 if (outInfo != null && outInfo.removedChildPackages != null) {
18234 final int childCount = (ps.childPackageNames != null)
18235 ? ps.childPackageNames.size() : 0;
18236 for (int i = 0; i < childCount; i++) {
18237 String childPackageName = ps.childPackageNames.get(i);
18238 PackageSetting childPs = mSettings.mPackages.get(childPackageName);
18239 if (childPs == null) {
18242 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
18244 if (childInfo != null) {
18245 childInfo.uid = childPs.appId;
18251 // Delete package data from internal structures and also remove data if flag is set
18252 removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
18254 // Delete the child packages data
18255 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
18256 for (int i = 0; i < childCount; i++) {
18257 PackageSetting childPs;
18258 synchronized (mPackages) {
18259 childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
18261 if (childPs != null) {
18262 PackageRemovedInfo childOutInfo = (outInfo != null
18263 && outInfo.removedChildPackages != null)
18264 ? outInfo.removedChildPackages.get(childPs.name) : null;
18265 final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
18266 && (replacingPackage != null
18267 && !replacingPackage.hasChildPackage(childPs.name))
18268 ? flags & ~DELETE_KEEP_DATA : flags;
18269 removePackageDataLIF(childPs, allUserHandles, childOutInfo,
18270 deleteFlags, writeSettings);
18274 // Delete application code and resources only for parent packages
18275 if (ps.parentPackageName == null) {
18276 if (deleteCodeAndResources && (outInfo != null)) {
18277 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
18278 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
18279 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
18287 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
18289 mContext.enforceCallingOrSelfPermission(
18290 android.Manifest.permission.DELETE_PACKAGES, null);
18291 synchronized (mPackages) {
18292 PackageSetting ps = mSettings.mPackages.get(packageName);
18294 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName);
18297 // Cannot block uninstall of static shared libs as they are
18298 // considered a part of the using app (emulating static linking).
18299 // Also static libs are installed always on internal storage.
18300 PackageParser.Package pkg = mPackages.get(packageName);
18301 if (pkg != null && pkg.staticSharedLibName != null) {
18302 Slog.w(TAG, "Cannot block uninstall of package: " + packageName
18303 + " providing static shared library: " + pkg.staticSharedLibName);
18306 if (!ps.getInstalled(userId)) {
18307 // Can't block uninstall for an app that is not installed or enabled.
18308 Log.i(TAG, "Package not installed in set block uninstall " + packageName);
18311 ps.setBlockUninstall(blockUninstall, userId);
18312 mSettings.writePackageRestrictionsLPr(userId);
18318 public boolean getBlockUninstallForUser(String packageName, int userId) {
18319 synchronized (mPackages) {
18320 PackageSetting ps = mSettings.mPackages.get(packageName);
18322 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName);
18325 return ps.getBlockUninstall(userId);
18330 public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
18331 int callingUid = Binder.getCallingUid();
18332 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
18333 throw new SecurityException(
18334 "setRequiredForSystemUser can only be run by the system or root");
18336 synchronized (mPackages) {
18337 PackageSetting ps = mSettings.mPackages.get(packageName);
18339 Log.w(TAG, "Package doesn't exist: " + packageName);
18342 if (systemUserApp) {
18343 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18345 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18347 mSettings.writeLPr();
18353 * This method handles package deletion in general
18355 private boolean deletePackageLIF(String packageName, UserHandle user,
18356 boolean deleteCodeAndResources, int[] allUserHandles, int flags,
18357 PackageRemovedInfo outInfo, boolean writeSettings,
18358 PackageParser.Package replacingPackage) {
18359 if (packageName == null) {
18360 Slog.w(TAG, "Attempt to delete null packageName.");
18364 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
18367 synchronized (mPackages) {
18368 ps = mSettings.mPackages.get(packageName);
18370 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18374 if (ps.parentPackageName != null && (!isSystemApp(ps)
18375 || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
18376 if (DEBUG_REMOVE) {
18377 Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
18378 + ((user == null) ? UserHandle.USER_ALL : user));
18380 final int removedUserId = (user != null) ? user.getIdentifier()
18381 : UserHandle.USER_ALL;
18382 if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
18385 markPackageUninstalledForUserLPw(ps, user);
18386 scheduleWritePackageRestrictionsLocked(user);
18391 if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
18392 && user.getIdentifier() != UserHandle.USER_ALL)) {
18393 // The caller is asking that the package only be deleted for a single
18394 // user. To do this, we just mark its uninstalled state and delete
18395 // its data. If this is a system app, we only allow this to happen if
18396 // they have set the special DELETE_SYSTEM_APP which requests different
18397 // semantics than normal for uninstalling system apps.
18398 markPackageUninstalledForUserLPw(ps, user);
18400 if (!isSystemApp(ps)) {
18401 // Do not uninstall the APK if an app should be cached
18402 boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
18403 if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
18404 // Other user still have this package installed, so all
18405 // we need to do is clear this user's data and save that
18406 // it is uninstalled.
18407 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
18408 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18411 scheduleWritePackageRestrictionsLocked(user);
18414 // We need to set it back to 'installed' so the uninstall
18415 // broadcasts will be sent correctly.
18416 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
18417 ps.setInstalled(true, user.getIdentifier());
18418 mSettings.writeKernelMappingLPr(ps);
18421 // This is a system app, so we assume that the
18422 // other users still have this package installed, so all
18423 // we need to do is clear this user's data and save that
18424 // it is uninstalled.
18425 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
18426 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18429 scheduleWritePackageRestrictionsLocked(user);
18434 // If we are deleting a composite package for all users, keep track
18435 // of result for each child.
18436 if (ps.childPackageNames != null && outInfo != null) {
18437 synchronized (mPackages) {
18438 final int childCount = ps.childPackageNames.size();
18439 outInfo.removedChildPackages = new ArrayMap<>(childCount);
18440 for (int i = 0; i < childCount; i++) {
18441 String childPackageName = ps.childPackageNames.get(i);
18442 PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
18443 childInfo.removedPackage = childPackageName;
18444 outInfo.removedChildPackages.put(childPackageName, childInfo);
18445 PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18446 if (childPs != null) {
18447 childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
18453 boolean ret = false;
18454 if (isSystemApp(ps)) {
18455 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
18456 // When an updated system application is deleted we delete the existing resources
18457 // as well and fall back to existing code in system partition
18458 ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
18460 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
18461 ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
18462 outInfo, writeSettings, replacingPackage);
18465 // Take a note whether we deleted the package for all users
18466 if (outInfo != null) {
18467 outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
18468 if (outInfo.removedChildPackages != null) {
18469 synchronized (mPackages) {
18470 final int childCount = outInfo.removedChildPackages.size();
18471 for (int i = 0; i < childCount; i++) {
18472 PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
18473 if (childInfo != null) {
18474 childInfo.removedForAllUsers = mPackages.get(
18475 childInfo.removedPackage) == null;
18480 // If we uninstalled an update to a system app there may be some
18481 // child packages that appeared as they are declared in the system
18482 // app but were not declared in the update.
18483 if (isSystemApp(ps)) {
18484 synchronized (mPackages) {
18485 PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
18486 final int childCount = (updatedPs.childPackageNames != null)
18487 ? updatedPs.childPackageNames.size() : 0;
18488 for (int i = 0; i < childCount; i++) {
18489 String childPackageName = updatedPs.childPackageNames.get(i);
18490 if (outInfo.removedChildPackages == null
18491 || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
18492 PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18493 if (childPs == null) {
18496 PackageInstalledInfo installRes = new PackageInstalledInfo();
18497 installRes.name = childPackageName;
18498 installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
18499 installRes.pkg = mPackages.get(childPackageName);
18500 installRes.uid = childPs.pkg.applicationInfo.uid;
18501 if (outInfo.appearedChildPackages == null) {
18502 outInfo.appearedChildPackages = new ArrayMap<>();
18504 outInfo.appearedChildPackages.put(childPackageName, installRes);
18514 private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
18515 final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
18516 ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
18517 for (int nextUserId : userIds) {
18518 if (DEBUG_REMOVE) {
18519 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
18521 ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
18522 false /*installed*/,
18524 true /*notLaunched*/,
18526 false /*suspended*/,
18527 false /*instantApp*/,
18528 null /*lastDisableAppCaller*/,
18529 null /*enabledComponents*/,
18530 null /*disabledComponents*/,
18531 false /*blockUninstall*/,
18532 ps.readUserState(nextUserId).domainVerificationStatus,
18533 0, PackageManager.INSTALL_REASON_UNKNOWN);
18535 mSettings.writeKernelMappingLPr(ps);
18538 private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
18539 PackageRemovedInfo outInfo) {
18540 final PackageParser.Package pkg;
18541 synchronized (mPackages) {
18542 pkg = mPackages.get(ps.name);
18545 final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
18546 : new int[] {userId};
18547 for (int nextUserId : userIds) {
18548 if (DEBUG_REMOVE) {
18549 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
18553 destroyAppDataLIF(pkg, userId,
18554 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18555 destroyAppProfilesLIF(pkg, userId);
18556 removeKeystoreDataIfNeeded(nextUserId, ps.appId);
18557 schedulePackageCleaning(ps.name, nextUserId, false);
18558 synchronized (mPackages) {
18559 if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
18560 scheduleWritePackageRestrictionsLocked(nextUserId);
18562 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
18566 if (outInfo != null) {
18567 outInfo.removedPackage = ps.name;
18568 outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
18569 outInfo.removedAppId = ps.appId;
18570 outInfo.removedUsers = userIds;
18571 outInfo.broadcastUsers = userIds;
18577 private final class ClearStorageConnection implements ServiceConnection {
18578 IMediaContainerService mContainerService;
18581 public void onServiceConnected(ComponentName name, IBinder service) {
18582 synchronized (this) {
18583 mContainerService = IMediaContainerService.Stub
18584 .asInterface(Binder.allowBlocking(service));
18590 public void onServiceDisconnected(ComponentName name) {
18594 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
18595 if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
18597 final boolean mounted;
18598 if (Environment.isExternalStorageEmulated()) {
18601 final String status = Environment.getExternalStorageState();
18603 mounted = status.equals(Environment.MEDIA_MOUNTED)
18604 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
18611 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
18613 if (userId == UserHandle.USER_ALL) {
18614 users = sUserManager.getUserIds();
18616 users = new int[] { userId };
18618 final ClearStorageConnection conn = new ClearStorageConnection();
18619 if (mContext.bindServiceAsUser(
18620 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
18622 for (int curUser : users) {
18623 long timeout = SystemClock.uptimeMillis() + 5000;
18624 synchronized (conn) {
18626 while (conn.mContainerService == null &&
18627 (now = SystemClock.uptimeMillis()) < timeout) {
18629 conn.wait(timeout - now);
18630 } catch (InterruptedException e) {
18634 if (conn.mContainerService == null) {
18638 final UserEnvironment userEnv = new UserEnvironment(curUser);
18639 clearDirectory(conn.mContainerService,
18640 userEnv.buildExternalStorageAppCacheDirs(packageName));
18642 clearDirectory(conn.mContainerService,
18643 userEnv.buildExternalStorageAppDataDirs(packageName));
18644 clearDirectory(conn.mContainerService,
18645 userEnv.buildExternalStorageAppMediaDirs(packageName));
18649 mContext.unbindService(conn);
18655 public void clearApplicationProfileData(String packageName) {
18656 enforceSystemOrRoot("Only the system can clear all profile data");
18658 final PackageParser.Package pkg;
18659 synchronized (mPackages) {
18660 pkg = mPackages.get(packageName);
18663 try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
18664 synchronized (mInstallLock) {
18665 clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
18671 public void clearApplicationUserData(final String packageName,
18672 final IPackageDataObserver observer, final int userId) {
18673 mContext.enforceCallingOrSelfPermission(
18674 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
18676 enforceCrossUserPermission(Binder.getCallingUid(), userId,
18677 true /* requireFullPermission */, false /* checkShell */, "clear application data");
18679 if (mProtectedPackages.isPackageDataProtected(userId, packageName)) {
18680 throw new SecurityException("Cannot clear data for a protected package: "
18683 // Queue up an async operation since the package deletion may take a little while.
18684 mHandler.post(new Runnable() {
18685 public void run() {
18686 mHandler.removeCallbacks(this);
18687 final boolean succeeded;
18688 try (PackageFreezer freezer = freezePackage(packageName,
18689 "clearApplicationUserData")) {
18690 synchronized (mInstallLock) {
18691 succeeded = clearApplicationUserDataLIF(packageName, userId);
18693 clearExternalStorageDataSync(packageName, userId, true);
18694 synchronized (mPackages) {
18695 mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
18696 packageName, userId);
18700 // invoke DeviceStorageMonitor's update method to clear any notifications
18701 DeviceStorageMonitorInternal dsm = LocalServices
18702 .getService(DeviceStorageMonitorInternal.class);
18707 if(observer != null) {
18709 observer.onRemoveCompleted(packageName, succeeded);
18710 } catch (RemoteException e) {
18711 Log.i(TAG, "Observer no longer exists.");
18713 } //end if observer
18718 private boolean clearApplicationUserDataLIF(String packageName, int userId) {
18719 if (packageName == null) {
18720 Slog.w(TAG, "Attempt to delete null packageName.");
18724 // Try finding details about the requested package
18725 PackageParser.Package pkg;
18726 synchronized (mPackages) {
18727 pkg = mPackages.get(packageName);
18729 final PackageSetting ps = mSettings.mPackages.get(packageName);
18736 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18740 PackageSetting ps = (PackageSetting) pkg.mExtras;
18741 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
18744 clearAppDataLIF(pkg, userId,
18745 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18747 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
18748 removeKeystoreDataIfNeeded(userId, appId);
18750 UserManagerInternal umInternal = getUserManagerInternal();
18752 if (umInternal.isUserUnlockingOrUnlocked(userId)) {
18753 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
18754 } else if (umInternal.isUserRunning(userId)) {
18755 flags = StorageManager.FLAG_STORAGE_DE;
18759 prepareAppDataContentsLIF(pkg, userId, flags);
18765 * Reverts user permission state changes (permissions and flags) in
18766 * all packages for a given user.
18768 * @param userId The device user for which to do a reset.
18770 private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
18771 final int packageCount = mPackages.size();
18772 for (int i = 0; i < packageCount; i++) {
18773 PackageParser.Package pkg = mPackages.valueAt(i);
18774 PackageSetting ps = (PackageSetting) pkg.mExtras;
18775 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
18779 private void resetNetworkPolicies(int userId) {
18780 LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
18784 * Reverts user permission state changes (permissions and flags).
18786 * @param ps The package for which to reset.
18787 * @param userId The device user for which to do a reset.
18789 private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
18790 final PackageSetting ps, final int userId) {
18791 if (ps.pkg == null) {
18795 // These are flags that can change base on user actions.
18796 final int userSettableMask = FLAG_PERMISSION_USER_SET
18797 | FLAG_PERMISSION_USER_FIXED
18798 | FLAG_PERMISSION_REVOKE_ON_UPGRADE
18799 | FLAG_PERMISSION_REVIEW_REQUIRED;
18801 final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
18802 | FLAG_PERMISSION_POLICY_FIXED;
18804 boolean writeInstallPermissions = false;
18805 boolean writeRuntimePermissions = false;
18807 final int permissionCount = ps.pkg.requestedPermissions.size();
18808 for (int i = 0; i < permissionCount; i++) {
18809 String permission = ps.pkg.requestedPermissions.get(i);
18811 BasePermission bp = mSettings.mPermissions.get(permission);
18816 // If shared user we just reset the state to which only this app contributed.
18817 if (ps.sharedUser != null) {
18818 boolean used = false;
18819 final int packageCount = ps.sharedUser.packages.size();
18820 for (int j = 0; j < packageCount; j++) {
18821 PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
18822 if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
18823 && pkg.pkg.requestedPermissions.contains(permission)) {
18833 PermissionsState permissionsState = ps.getPermissionsState();
18835 final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
18837 // Always clear the user settable flags.
18838 final boolean hasInstallState = permissionsState.getInstallPermissionState(
18840 // If permission review is enabled and this is a legacy app, mark the
18841 // permission as requiring a review as this is the initial state.
18843 if (mPermissionReviewRequired
18844 && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
18845 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
18847 if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
18848 if (hasInstallState) {
18849 writeInstallPermissions = true;
18851 writeRuntimePermissions = true;
18855 // Below is only runtime permission handling.
18856 if (!bp.isRuntime()) {
18860 // Never clobber system or policy.
18861 if ((oldFlags & policyOrSystemFlags) != 0) {
18865 // If this permission was granted by default, make sure it is.
18866 if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
18867 if (permissionsState.grantRuntimePermission(bp, userId)
18868 != PERMISSION_OPERATION_FAILURE) {
18869 writeRuntimePermissions = true;
18871 // If permission review is enabled the permissions for a legacy apps
18872 // are represented as constantly granted runtime ones, so don't revoke.
18873 } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
18874 // Otherwise, reset the permission.
18875 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
18876 switch (revokeResult) {
18877 case PERMISSION_OPERATION_SUCCESS:
18878 case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
18879 writeRuntimePermissions = true;
18880 final int appId = ps.appId;
18881 mHandler.post(new Runnable() {
18883 public void run() {
18884 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
18892 // Synchronously write as we are taking permissions away.
18893 if (writeRuntimePermissions) {
18894 mSettings.writeRuntimePermissionsForUserLPr(userId, true);
18897 // Synchronously write as we are taking permissions away.
18898 if (writeInstallPermissions) {
18899 mSettings.writeLPr();
18904 * Remove entries from the keystore daemon. Will only remove it if the
18905 * {@code appId} is valid.
18907 private static void removeKeystoreDataIfNeeded(int userId, int appId) {
18912 final KeyStore keyStore = KeyStore.getInstance();
18913 if (keyStore != null) {
18914 if (userId == UserHandle.USER_ALL) {
18915 for (final int individual : sUserManager.getUserIds()) {
18916 keyStore.clearUid(UserHandle.getUid(individual, appId));
18919 keyStore.clearUid(UserHandle.getUid(userId, appId));
18922 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
18927 public void deleteApplicationCacheFiles(final String packageName,
18928 final IPackageDataObserver observer) {
18929 final int userId = UserHandle.getCallingUserId();
18930 deleteApplicationCacheFilesAsUser(packageName, userId, observer);
18934 public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
18935 final IPackageDataObserver observer) {
18936 mContext.enforceCallingOrSelfPermission(
18937 android.Manifest.permission.DELETE_CACHE_FILES, null);
18938 enforceCrossUserPermission(Binder.getCallingUid(), userId,
18939 /* requireFullPermission= */ true, /* checkShell= */ false,
18940 "delete application cache files");
18942 final PackageParser.Package pkg;
18943 synchronized (mPackages) {
18944 pkg = mPackages.get(packageName);
18947 // Queue up an async operation since the package deletion may take a little while.
18948 mHandler.post(new Runnable() {
18949 public void run() {
18950 synchronized (mInstallLock) {
18951 final int flags = StorageManager.FLAG_STORAGE_DE
18952 | StorageManager.FLAG_STORAGE_CE;
18953 // We're only clearing cache files, so we don't care if the
18954 // app is unfrozen and still able to run
18955 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
18956 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
18958 clearExternalStorageDataSync(packageName, userId, false);
18959 if (observer != null) {
18961 observer.onRemoveCompleted(packageName, true);
18962 } catch (RemoteException e) {
18963 Log.i(TAG, "Observer no longer exists.");
18971 public void getPackageSizeInfo(final String packageName, int userHandle,
18972 final IPackageStatsObserver observer) {
18973 throw new UnsupportedOperationException(
18974 "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
18977 private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
18978 final PackageSetting ps;
18979 synchronized (mPackages) {
18980 ps = mSettings.mPackages.get(packageName);
18982 Slog.w(TAG, "Failed to find settings for " + packageName);
18987 final String[] packageNames = { packageName };
18988 final long[] ceDataInodes = { ps.getCeDataInode(userId) };
18989 final String[] codePaths = { ps.codePathString };
18992 mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
18993 ps.appId, ceDataInodes, codePaths, stats);
18995 // For now, ignore code size of packages on system partition
18996 if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
18997 stats.codeSize = 0;
19000 // External clients expect these to be tracked separately
19001 stats.dataSize -= stats.cacheSize;
19003 } catch (InstallerException e) {
19004 Slog.w(TAG, String.valueOf(e));
19011 private int getUidTargetSdkVersionLockedLPr(int uid) {
19012 Object obj = mSettings.getUserIdLPr(uid);
19013 if (obj instanceof SharedUserSetting) {
19014 final SharedUserSetting sus = (SharedUserSetting) obj;
19015 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
19016 final Iterator<PackageSetting> it = sus.packages.iterator();
19017 while (it.hasNext()) {
19018 final PackageSetting ps = it.next();
19019 if (ps.pkg != null) {
19020 int v = ps.pkg.applicationInfo.targetSdkVersion;
19021 if (v < vers) vers = v;
19025 } else if (obj instanceof PackageSetting) {
19026 final PackageSetting ps = (PackageSetting) obj;
19027 if (ps.pkg != null) {
19028 return ps.pkg.applicationInfo.targetSdkVersion;
19031 return Build.VERSION_CODES.CUR_DEVELOPMENT;
19035 public void addPreferredActivity(IntentFilter filter, int match,
19036 ComponentName[] set, ComponentName activity, int userId) {
19037 addPreferredActivityInternal(filter, match, set, activity, true, userId,
19038 "Adding preferred");
19041 private void addPreferredActivityInternal(IntentFilter filter, int match,
19042 ComponentName[] set, ComponentName activity, boolean always, int userId,
19045 int callingUid = Binder.getCallingUid();
19046 enforceCrossUserPermission(callingUid, userId,
19047 true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
19048 if (filter.countActions() == 0) {
19049 Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19052 synchronized (mPackages) {
19053 if (mContext.checkCallingOrSelfPermission(
19054 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19055 != PackageManager.PERMISSION_GRANTED) {
19056 if (getUidTargetSdkVersionLockedLPr(callingUid)
19057 < Build.VERSION_CODES.FROYO) {
19058 Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
19062 mContext.enforceCallingOrSelfPermission(
19063 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19066 PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
19067 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
19069 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
19070 pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
19071 scheduleWritePackageRestrictionsLocked(userId);
19072 postPreferredActivityChangedBroadcast(userId);
19076 private void postPreferredActivityChangedBroadcast(int userId) {
19077 mHandler.post(() -> {
19078 final IActivityManager am = ActivityManager.getService();
19083 final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
19084 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19086 am.broadcastIntent(null, intent, null, null,
19087 0, null, null, null, android.app.AppOpsManager.OP_NONE,
19088 null, false, false, userId);
19089 } catch (RemoteException e) {
19095 public void replacePreferredActivity(IntentFilter filter, int match,
19096 ComponentName[] set, ComponentName activity, int userId) {
19097 if (filter.countActions() != 1) {
19098 throw new IllegalArgumentException(
19099 "replacePreferredActivity expects filter to have only 1 action.");
19101 if (filter.countDataAuthorities() != 0
19102 || filter.countDataPaths() != 0
19103 || filter.countDataSchemes() > 1
19104 || filter.countDataTypes() != 0) {
19105 throw new IllegalArgumentException(
19106 "replacePreferredActivity expects filter to have no data authorities, " +
19107 "paths, or types; and at most one scheme.");
19110 final int callingUid = Binder.getCallingUid();
19111 enforceCrossUserPermission(callingUid, userId,
19112 true /* requireFullPermission */, false /* checkShell */,
19113 "replace preferred activity");
19114 synchronized (mPackages) {
19115 if (mContext.checkCallingOrSelfPermission(
19116 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19117 != PackageManager.PERMISSION_GRANTED) {
19118 if (getUidTargetSdkVersionLockedLPr(callingUid)
19119 < Build.VERSION_CODES.FROYO) {
19120 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
19121 + Binder.getCallingUid());
19124 mContext.enforceCallingOrSelfPermission(
19125 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19128 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19130 // Get all of the existing entries that exactly match this filter.
19131 ArrayList<PreferredActivity> existing = pir.findFilters(filter);
19132 if (existing != null && existing.size() == 1) {
19133 PreferredActivity cur = existing.get(0);
19134 if (DEBUG_PREFERRED) {
19135 Slog.i(TAG, "Checking replace of preferred:");
19136 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
19137 if (!cur.mPref.mAlways) {
19138 Slog.i(TAG, " -- CUR; not mAlways!");
19140 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch);
19141 Slog.i(TAG, " -- CUR: mSet="
19142 + Arrays.toString(cur.mPref.mSetComponents));
19143 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent);
19144 Slog.i(TAG, " -- NEW: mMatch="
19145 + (match&IntentFilter.MATCH_CATEGORY_MASK));
19146 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set));
19147 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString());
19150 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
19151 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
19152 && cur.mPref.sameSet(set)) {
19153 // Setting the preferred activity to what it happens to be already
19154 if (DEBUG_PREFERRED) {
19155 Slog.i(TAG, "Replacing with same preferred activity "
19156 + cur.mPref.mShortComponent + " for user "
19158 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
19164 if (existing != null) {
19165 if (DEBUG_PREFERRED) {
19166 Slog.i(TAG, existing.size() + " existing preferred matches for:");
19167 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
19169 for (int i = 0; i < existing.size(); i++) {
19170 PreferredActivity pa = existing.get(i);
19171 if (DEBUG_PREFERRED) {
19172 Slog.i(TAG, "Removing existing preferred activity "
19173 + pa.mPref.mComponent + ":");
19174 pa.dump(new LogPrinter(Log.INFO, TAG), " ");
19176 pir.removeFilter(pa);
19180 addPreferredActivityInternal(filter, match, set, activity, true, userId,
19181 "Replacing preferred");
19186 public void clearPackagePreferredActivities(String packageName) {
19187 final int uid = Binder.getCallingUid();
19189 synchronized (mPackages) {
19190 PackageParser.Package pkg = mPackages.get(packageName);
19191 if (pkg == null || pkg.applicationInfo.uid != uid) {
19192 if (mContext.checkCallingOrSelfPermission(
19193 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19194 != PackageManager.PERMISSION_GRANTED) {
19195 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
19196 < Build.VERSION_CODES.FROYO) {
19197 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
19198 + Binder.getCallingUid());
19201 mContext.enforceCallingOrSelfPermission(
19202 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19206 int user = UserHandle.getCallingUserId();
19207 if (clearPackagePreferredActivitiesLPw(packageName, user)) {
19208 scheduleWritePackageRestrictionsLocked(user);
19213 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19214 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
19215 ArrayList<PreferredActivity> removed = null;
19216 boolean changed = false;
19217 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
19218 final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
19219 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
19220 if (userId != UserHandle.USER_ALL && userId != thisUserId) {
19223 Iterator<PreferredActivity> it = pir.filterIterator();
19224 while (it.hasNext()) {
19225 PreferredActivity pa = it.next();
19226 // Mark entry for removal only if it matches the package name
19227 // and the entry is of type "always".
19228 if (packageName == null ||
19229 (pa.mPref.mComponent.getPackageName().equals(packageName)
19230 && pa.mPref.mAlways)) {
19231 if (removed == null) {
19232 removed = new ArrayList<PreferredActivity>();
19237 if (removed != null) {
19238 for (int j=0; j<removed.size(); j++) {
19239 PreferredActivity pa = removed.get(j);
19240 pir.removeFilter(pa);
19246 postPreferredActivityChangedBroadcast(userId);
19251 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19252 private void clearIntentFilterVerificationsLPw(int userId) {
19253 final int packageCount = mPackages.size();
19254 for (int i = 0; i < packageCount; i++) {
19255 PackageParser.Package pkg = mPackages.valueAt(i);
19256 clearIntentFilterVerificationsLPw(pkg.packageName, userId);
19260 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19261 void clearIntentFilterVerificationsLPw(String packageName, int userId) {
19262 if (userId == UserHandle.USER_ALL) {
19263 if (mSettings.removeIntentFilterVerificationLPw(packageName,
19264 sUserManager.getUserIds())) {
19265 for (int oneUserId : sUserManager.getUserIds()) {
19266 scheduleWritePackageRestrictionsLocked(oneUserId);
19270 if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
19271 scheduleWritePackageRestrictionsLocked(userId);
19276 void clearDefaultBrowserIfNeeded(String packageName) {
19277 for (int oneUserId : sUserManager.getUserIds()) {
19278 String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId);
19279 if (TextUtils.isEmpty(defaultBrowserPackageName)) continue;
19280 if (packageName.equals(defaultBrowserPackageName)) {
19281 setDefaultBrowserPackageName(null, oneUserId);
19287 public void resetApplicationPreferences(int userId) {
19288 mContext.enforceCallingOrSelfPermission(
19289 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19290 final long identity = Binder.clearCallingIdentity();
19293 synchronized (mPackages) {
19294 clearPackagePreferredActivitiesLPw(null, userId);
19295 mSettings.applyDefaultPreferredAppsLPw(this, userId);
19296 // TODO: We have to reset the default SMS and Phone. This requires
19297 // significant refactoring to keep all default apps in the package
19298 // manager (cleaner but more work) or have the services provide
19299 // callbacks to the package manager to request a default app reset.
19300 applyFactoryDefaultBrowserLPw(userId);
19301 clearIntentFilterVerificationsLPw(userId);
19302 primeDomainVerificationsLPw(userId);
19303 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
19304 scheduleWritePackageRestrictionsLocked(userId);
19306 resetNetworkPolicies(userId);
19308 Binder.restoreCallingIdentity(identity);
19313 public int getPreferredActivities(List<IntentFilter> outFilters,
19314 List<ComponentName> outActivities, String packageName) {
19317 final int userId = UserHandle.getCallingUserId();
19319 synchronized (mPackages) {
19320 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19322 final Iterator<PreferredActivity> it = pir.filterIterator();
19323 while (it.hasNext()) {
19324 final PreferredActivity pa = it.next();
19325 if (packageName == null
19326 || (pa.mPref.mComponent.getPackageName().equals(packageName)
19327 && pa.mPref.mAlways)) {
19328 if (outFilters != null) {
19329 outFilters.add(new IntentFilter(pa));
19331 if (outActivities != null) {
19332 outActivities.add(pa.mPref.mComponent);
19343 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
19345 int callingUid = Binder.getCallingUid();
19346 if (callingUid != Process.SYSTEM_UID) {
19347 throw new SecurityException(
19348 "addPersistentPreferredActivity can only be run by the system");
19350 if (filter.countActions() == 0) {
19351 Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19354 synchronized (mPackages) {
19355 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
19357 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
19358 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
19359 new PersistentPreferredActivity(filter, activity));
19360 scheduleWritePackageRestrictionsLocked(userId);
19361 postPreferredActivityChangedBroadcast(userId);
19366 public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
19367 int callingUid = Binder.getCallingUid();
19368 if (callingUid != Process.SYSTEM_UID) {
19369 throw new SecurityException(
19370 "clearPackagePersistentPreferredActivities can only be run by the system");
19372 ArrayList<PersistentPreferredActivity> removed = null;
19373 boolean changed = false;
19374 synchronized (mPackages) {
19375 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
19376 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
19377 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
19379 if (userId != thisUserId) {
19382 Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
19383 while (it.hasNext()) {
19384 PersistentPreferredActivity ppa = it.next();
19385 // Mark entry for removal only if it matches the package name.
19386 if (ppa.mComponent.getPackageName().equals(packageName)) {
19387 if (removed == null) {
19388 removed = new ArrayList<PersistentPreferredActivity>();
19393 if (removed != null) {
19394 for (int j=0; j<removed.size(); j++) {
19395 PersistentPreferredActivity ppa = removed.get(j);
19396 ppir.removeFilter(ppa);
19403 scheduleWritePackageRestrictionsLocked(userId);
19404 postPreferredActivityChangedBroadcast(userId);
19410 * Common machinery for picking apart a restored XML blob and passing
19411 * it to a caller-supplied functor to be applied to the running system.
19413 private void restoreFromXml(XmlPullParser parser, int userId,
19414 String expectedStartTag, BlobXmlRestorer functor)
19415 throws IOException, XmlPullParserException {
19417 while ((type = parser.next()) != XmlPullParser.START_TAG
19418 && type != XmlPullParser.END_DOCUMENT) {
19420 if (type != XmlPullParser.START_TAG) {
19421 // oops didn't find a start tag?!
19422 if (DEBUG_BACKUP) {
19423 Slog.e(TAG, "Didn't find start tag during restore");
19427 Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
19428 // this is supposed to be TAG_PREFERRED_BACKUP
19429 if (!expectedStartTag.equals(parser.getName())) {
19430 if (DEBUG_BACKUP) {
19431 Slog.e(TAG, "Found unexpected tag " + parser.getName());
19436 // skip interfering stuff, then we're aligned with the backing implementation
19437 while ((type = parser.next()) == XmlPullParser.TEXT) { }
19438 Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
19439 functor.apply(parser, userId);
19442 private interface BlobXmlRestorer {
19443 public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
19447 * Non-Binder method, support for the backup/restore mechanism: write the
19448 * full set of preferred activities in its canonical XML format. Returns the
19449 * XML output as a byte array, or null if there is none.
19452 public byte[] getPreferredActivityBackup(int userId) {
19453 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19454 throw new SecurityException("Only the system may call getPreferredActivityBackup()");
19457 ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19459 final XmlSerializer serializer = new FastXmlSerializer();
19460 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19461 serializer.startDocument(null, true);
19462 serializer.startTag(null, TAG_PREFERRED_BACKUP);
19464 synchronized (mPackages) {
19465 mSettings.writePreferredActivitiesLPr(serializer, userId, true);
19468 serializer.endTag(null, TAG_PREFERRED_BACKUP);
19469 serializer.endDocument();
19470 serializer.flush();
19471 } catch (Exception e) {
19472 if (DEBUG_BACKUP) {
19473 Slog.e(TAG, "Unable to write preferred activities for backup", e);
19478 return dataStream.toByteArray();
19482 public void restorePreferredActivities(byte[] backup, int userId) {
19483 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19484 throw new SecurityException("Only the system may call restorePreferredActivities()");
19488 final XmlPullParser parser = Xml.newPullParser();
19489 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19490 restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
19491 new BlobXmlRestorer() {
19493 public void apply(XmlPullParser parser, int userId)
19494 throws XmlPullParserException, IOException {
19495 synchronized (mPackages) {
19496 mSettings.readPreferredActivitiesLPw(parser, userId);
19500 } catch (Exception e) {
19501 if (DEBUG_BACKUP) {
19502 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19508 * Non-Binder method, support for the backup/restore mechanism: write the
19509 * default browser (etc) settings in its canonical XML format. Returns the default
19510 * browser XML representation as a byte array, or null if there is none.
19513 public byte[] getDefaultAppsBackup(int userId) {
19514 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19515 throw new SecurityException("Only the system may call getDefaultAppsBackup()");
19518 ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19520 final XmlSerializer serializer = new FastXmlSerializer();
19521 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19522 serializer.startDocument(null, true);
19523 serializer.startTag(null, TAG_DEFAULT_APPS);
19525 synchronized (mPackages) {
19526 mSettings.writeDefaultAppsLPr(serializer, userId);
19529 serializer.endTag(null, TAG_DEFAULT_APPS);
19530 serializer.endDocument();
19531 serializer.flush();
19532 } catch (Exception e) {
19533 if (DEBUG_BACKUP) {
19534 Slog.e(TAG, "Unable to write default apps for backup", e);
19539 return dataStream.toByteArray();
19543 public void restoreDefaultApps(byte[] backup, int userId) {
19544 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19545 throw new SecurityException("Only the system may call restoreDefaultApps()");
19549 final XmlPullParser parser = Xml.newPullParser();
19550 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19551 restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
19552 new BlobXmlRestorer() {
19554 public void apply(XmlPullParser parser, int userId)
19555 throws XmlPullParserException, IOException {
19556 synchronized (mPackages) {
19557 mSettings.readDefaultAppsLPw(parser, userId);
19561 } catch (Exception e) {
19562 if (DEBUG_BACKUP) {
19563 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
19569 public byte[] getIntentFilterVerificationBackup(int userId) {
19570 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19571 throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
19574 ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19576 final XmlSerializer serializer = new FastXmlSerializer();
19577 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19578 serializer.startDocument(null, true);
19579 serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
19581 synchronized (mPackages) {
19582 mSettings.writeAllDomainVerificationsLPr(serializer, userId);
19585 serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
19586 serializer.endDocument();
19587 serializer.flush();
19588 } catch (Exception e) {
19589 if (DEBUG_BACKUP) {
19590 Slog.e(TAG, "Unable to write default apps for backup", e);
19595 return dataStream.toByteArray();
19599 public void restoreIntentFilterVerification(byte[] backup, int userId) {
19600 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19601 throw new SecurityException("Only the system may call restorePreferredActivities()");
19605 final XmlPullParser parser = Xml.newPullParser();
19606 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19607 restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
19608 new BlobXmlRestorer() {
19610 public void apply(XmlPullParser parser, int userId)
19611 throws XmlPullParserException, IOException {
19612 synchronized (mPackages) {
19613 mSettings.readAllDomainVerificationsLPr(parser, userId);
19614 mSettings.writeLPr();
19618 } catch (Exception e) {
19619 if (DEBUG_BACKUP) {
19620 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19626 public byte[] getPermissionGrantBackup(int userId) {
19627 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19628 throw new SecurityException("Only the system may call getPermissionGrantBackup()");
19631 ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19633 final XmlSerializer serializer = new FastXmlSerializer();
19634 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19635 serializer.startDocument(null, true);
19636 serializer.startTag(null, TAG_PERMISSION_BACKUP);
19638 synchronized (mPackages) {
19639 serializeRuntimePermissionGrantsLPr(serializer, userId);
19642 serializer.endTag(null, TAG_PERMISSION_BACKUP);
19643 serializer.endDocument();
19644 serializer.flush();
19645 } catch (Exception e) {
19646 if (DEBUG_BACKUP) {
19647 Slog.e(TAG, "Unable to write default apps for backup", e);
19652 return dataStream.toByteArray();
19656 public void restorePermissionGrants(byte[] backup, int userId) {
19657 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19658 throw new SecurityException("Only the system may call restorePermissionGrants()");
19662 final XmlPullParser parser = Xml.newPullParser();
19663 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19664 restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
19665 new BlobXmlRestorer() {
19667 public void apply(XmlPullParser parser, int userId)
19668 throws XmlPullParserException, IOException {
19669 synchronized (mPackages) {
19670 processRestoredPermissionGrantsLPr(parser, userId);
19674 } catch (Exception e) {
19675 if (DEBUG_BACKUP) {
19676 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19681 private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
19682 throws IOException {
19683 serializer.startTag(null, TAG_ALL_GRANTS);
19685 final int N = mSettings.mPackages.size();
19686 for (int i = 0; i < N; i++) {
19687 final PackageSetting ps = mSettings.mPackages.valueAt(i);
19688 boolean pkgGrantsKnown = false;
19690 PermissionsState packagePerms = ps.getPermissionsState();
19692 for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
19693 final int grantFlags = state.getFlags();
19694 // only look at grants that are not system/policy fixed
19695 if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
19696 final boolean isGranted = state.isGranted();
19697 // And only back up the user-twiddled state bits
19698 if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
19699 final String packageName = mSettings.mPackages.keyAt(i);
19700 if (!pkgGrantsKnown) {
19701 serializer.startTag(null, TAG_GRANT);
19702 serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
19703 pkgGrantsKnown = true;
19706 final boolean userSet =
19707 (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
19708 final boolean userFixed =
19709 (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
19710 final boolean revoke =
19711 (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
19713 serializer.startTag(null, TAG_PERMISSION);
19714 serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
19716 serializer.attribute(null, ATTR_IS_GRANTED, "true");
19719 serializer.attribute(null, ATTR_USER_SET, "true");
19722 serializer.attribute(null, ATTR_USER_FIXED, "true");
19725 serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
19727 serializer.endTag(null, TAG_PERMISSION);
19732 if (pkgGrantsKnown) {
19733 serializer.endTag(null, TAG_GRANT);
19737 serializer.endTag(null, TAG_ALL_GRANTS);
19740 private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
19741 throws XmlPullParserException, IOException {
19742 String pkgName = null;
19743 int outerDepth = parser.getDepth();
19745 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
19746 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
19747 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
19751 final String tagName = parser.getName();
19752 if (tagName.equals(TAG_GRANT)) {
19753 pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
19754 if (DEBUG_BACKUP) {
19755 Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
19757 } else if (tagName.equals(TAG_PERMISSION)) {
19759 final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
19760 final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
19762 int newFlagSet = 0;
19763 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
19764 newFlagSet |= FLAG_PERMISSION_USER_SET;
19766 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
19767 newFlagSet |= FLAG_PERMISSION_USER_FIXED;
19769 if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
19770 newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
19772 if (DEBUG_BACKUP) {
19773 Slog.v(TAG, " + Restoring grant: pkg=" + pkgName + " perm=" + permName
19774 + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet));
19776 final PackageSetting ps = mSettings.mPackages.get(pkgName);
19778 // Already installed so we apply the grant immediately
19779 if (DEBUG_BACKUP) {
19780 Slog.v(TAG, " + already installed; applying");
19782 PermissionsState perms = ps.getPermissionsState();
19783 BasePermission bp = mSettings.mPermissions.get(permName);
19786 perms.grantRuntimePermission(bp, userId);
19788 if (newFlagSet != 0) {
19789 perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
19793 // Need to wait for post-restore install to apply the grant
19794 if (DEBUG_BACKUP) {
19795 Slog.v(TAG, " - not yet installed; saving for later");
19797 mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
19798 isGranted, newFlagSet, userId);
19801 PackageManagerService.reportSettingsProblem(Log.WARN,
19802 "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
19803 XmlUtils.skipCurrentTag(parser);
19807 scheduleWriteSettingsLocked();
19808 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
19812 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
19813 int sourceUserId, int targetUserId, int flags) {
19814 mContext.enforceCallingOrSelfPermission(
19815 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
19816 int callingUid = Binder.getCallingUid();
19817 enforceOwnerRights(ownerPackage, callingUid);
19818 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
19819 if (intentFilter.countActions() == 0) {
19820 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
19823 synchronized (mPackages) {
19824 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
19825 ownerPackage, targetUserId, flags);
19826 CrossProfileIntentResolver resolver =
19827 mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
19828 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
19829 // We have all those whose filter is equal. Now checking if the rest is equal as well.
19830 if (existing != null) {
19831 int size = existing.size();
19832 for (int i = 0; i < size; i++) {
19833 if (newFilter.equalsIgnoreFilter(existing.get(i))) {
19838 resolver.addFilter(newFilter);
19839 scheduleWritePackageRestrictionsLocked(sourceUserId);
19844 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
19845 mContext.enforceCallingOrSelfPermission(
19846 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
19847 int callingUid = Binder.getCallingUid();
19848 enforceOwnerRights(ownerPackage, callingUid);
19849 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
19850 synchronized (mPackages) {
19851 CrossProfileIntentResolver resolver =
19852 mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
19853 ArraySet<CrossProfileIntentFilter> set =
19854 new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
19855 for (CrossProfileIntentFilter filter : set) {
19856 if (filter.getOwnerPackage().equals(ownerPackage)) {
19857 resolver.removeFilter(filter);
19860 scheduleWritePackageRestrictionsLocked(sourceUserId);
19864 // Enforcing that callingUid is owning pkg on userId
19865 private void enforceOwnerRights(String pkg, int callingUid) {
19866 // The system owns everything.
19867 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
19870 int callingUserId = UserHandle.getUserId(callingUid);
19871 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
19873 throw new IllegalArgumentException("Unknown package " + pkg + " on user "
19876 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
19877 throw new SecurityException("Calling uid " + callingUid
19878 + " does not own package " + pkg);
19883 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
19884 return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
19888 * Report the 'Home' activity which is currently set as "always use this one". If non is set
19889 * then reports the most likely home activity or null if there are more than one.
19891 public ComponentName getDefaultHomeActivity(int userId) {
19892 List<ResolveInfo> allHomeCandidates = new ArrayList<>();
19893 ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
19898 // Find the launcher with the highest priority and return that component if there are no
19899 // other home activity with the same priority.
19900 int lastPriority = Integer.MIN_VALUE;
19901 ComponentName lastComponent = null;
19902 final int size = allHomeCandidates.size();
19903 for (int i = 0; i < size; i++) {
19904 final ResolveInfo ri = allHomeCandidates.get(i);
19905 if (ri.priority > lastPriority) {
19906 lastComponent = ri.activityInfo.getComponentName();
19907 lastPriority = ri.priority;
19908 } else if (ri.priority == lastPriority) {
19909 // Two components found with same priority.
19910 lastComponent = null;
19913 return lastComponent;
19916 private Intent getHomeIntent() {
19917 Intent intent = new Intent(Intent.ACTION_MAIN);
19918 intent.addCategory(Intent.CATEGORY_HOME);
19919 intent.addCategory(Intent.CATEGORY_DEFAULT);
19923 private IntentFilter getHomeFilter() {
19924 IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
19925 filter.addCategory(Intent.CATEGORY_HOME);
19926 filter.addCategory(Intent.CATEGORY_DEFAULT);
19930 ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
19932 Intent intent = getHomeIntent();
19933 List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
19934 PackageManager.GET_META_DATA, userId);
19935 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
19936 true, false, false, userId);
19938 allHomeCandidates.clear();
19939 if (list != null) {
19940 for (ResolveInfo ri : list) {
19941 allHomeCandidates.add(ri);
19944 return (preferred == null || preferred.activityInfo == null)
19946 : new ComponentName(preferred.activityInfo.packageName,
19947 preferred.activityInfo.name);
19951 public void setHomeActivity(ComponentName comp, int userId) {
19952 ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
19953 getHomeActivitiesAsUser(homeActivities, userId);
19955 boolean found = false;
19957 final int size = homeActivities.size();
19958 final ComponentName[] set = new ComponentName[size];
19959 for (int i = 0; i < size; i++) {
19960 final ResolveInfo candidate = homeActivities.get(i);
19961 final ActivityInfo info = candidate.activityInfo;
19962 final ComponentName activityName = new ComponentName(info.packageName, info.name);
19963 set[i] = activityName;
19964 if (!found && activityName.equals(comp)) {
19969 throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
19972 replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
19973 set, comp, userId);
19976 private @Nullable String getSetupWizardPackageName() {
19977 final Intent intent = new Intent(Intent.ACTION_MAIN);
19978 intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
19980 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
19981 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
19982 | MATCH_DISABLED_COMPONENTS,
19983 UserHandle.myUserId());
19984 if (matches.size() == 1) {
19985 return matches.get(0).getComponentInfo().packageName;
19987 Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
19988 + ": matches=" + matches);
19993 private @Nullable String getStorageManagerPackageName() {
19994 final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
19996 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
19997 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
19998 | MATCH_DISABLED_COMPONENTS,
19999 UserHandle.myUserId());
20000 if (matches.size() == 1) {
20001 return matches.get(0).getComponentInfo().packageName;
20003 Slog.e(TAG, "There should probably be exactly one storage manager; found "
20004 + matches.size() + ": matches=" + matches);
20010 public void setApplicationEnabledSetting(String appPackageName,
20011 int newState, int flags, int userId, String callingPackage) {
20012 if (!sUserManager.exists(userId)) return;
20013 if (callingPackage == null) {
20014 callingPackage = Integer.toString(Binder.getCallingUid());
20016 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
20020 public void setUpdateAvailable(String packageName, boolean updateAvailable) {
20021 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
20022 synchronized (mPackages) {
20023 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
20024 if (pkgSetting != null) {
20025 pkgSetting.setUpdateAvailable(updateAvailable);
20031 public void setComponentEnabledSetting(ComponentName componentName,
20032 int newState, int flags, int userId) {
20033 if (!sUserManager.exists(userId)) return;
20034 setEnabledSetting(componentName.getPackageName(),
20035 componentName.getClassName(), newState, flags, userId, null);
20038 private void setEnabledSetting(final String packageName, String className, int newState,
20039 final int flags, int userId, String callingPackage) {
20040 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
20041 || newState == COMPONENT_ENABLED_STATE_ENABLED
20042 || newState == COMPONENT_ENABLED_STATE_DISABLED
20043 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20044 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
20045 throw new IllegalArgumentException("Invalid new component state: "
20048 PackageSetting pkgSetting;
20049 final int uid = Binder.getCallingUid();
20050 final int permission;
20051 if (uid == Process.SYSTEM_UID) {
20052 permission = PackageManager.PERMISSION_GRANTED;
20054 permission = mContext.checkCallingOrSelfPermission(
20055 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20057 enforceCrossUserPermission(uid, userId,
20058 false /* requireFullPermission */, true /* checkShell */, "set enabled");
20059 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20060 boolean sendNow = false;
20061 boolean isApp = (className == null);
20062 String componentName = isApp ? packageName : className;
20063 int packageUid = -1;
20064 ArrayList<String> components;
20067 synchronized (mPackages) {
20068 pkgSetting = mSettings.mPackages.get(packageName);
20069 if (pkgSetting == null) {
20070 if (className == null) {
20071 throw new IllegalArgumentException("Unknown package: " + packageName);
20073 throw new IllegalArgumentException(
20074 "Unknown component: " + packageName + "/" + className);
20078 // Limit who can change which apps
20079 if (!UserHandle.isSameApp(uid, pkgSetting.appId)) {
20080 // Don't allow apps that don't have permission to modify other apps
20081 if (!allowedByPermission) {
20082 throw new SecurityException(
20083 "Permission Denial: attempt to change component state from pid="
20084 + Binder.getCallingPid()
20085 + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
20087 // Don't allow changing protected packages.
20088 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
20089 throw new SecurityException("Cannot disable a protected package: " + packageName);
20093 synchronized (mPackages) {
20094 if (uid == Process.SHELL_UID
20095 && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
20096 // Shell can only change whole packages between ENABLED and DISABLED_USER states
20097 // unless it is a test package.
20098 int oldState = pkgSetting.getEnabled(userId);
20099 if (className == null
20101 (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
20102 || oldState == COMPONENT_ENABLED_STATE_DEFAULT
20103 || oldState == COMPONENT_ENABLED_STATE_ENABLED)
20105 (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20106 || newState == COMPONENT_ENABLED_STATE_DEFAULT
20107 || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
20110 throw new SecurityException(
20111 "Shell cannot change component state for " + packageName + "/"
20112 + className + " to " + newState);
20115 if (className == null) {
20116 // We're dealing with an application/package level state change
20117 if (pkgSetting.getEnabled(userId) == newState) {
20121 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
20122 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
20123 // Don't care about who enables an app.
20124 callingPackage = null;
20126 pkgSetting.setEnabled(newState, userId, callingPackage);
20127 // pkgSetting.pkg.mSetEnabled = newState;
20129 // We're dealing with a component level state change
20130 // First, verify that this is a valid class name.
20131 PackageParser.Package pkg = pkgSetting.pkg;
20132 if (pkg == null || !pkg.hasComponentClassName(className)) {
20134 pkg.applicationInfo.targetSdkVersion >=
20135 Build.VERSION_CODES.JELLY_BEAN) {
20136 throw new IllegalArgumentException("Component class " + className
20137 + " does not exist in " + packageName);
20139 Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
20140 + className + " does not exist in " + packageName);
20143 switch (newState) {
20144 case COMPONENT_ENABLED_STATE_ENABLED:
20145 if (!pkgSetting.enableComponentLPw(className, userId)) {
20149 case COMPONENT_ENABLED_STATE_DISABLED:
20150 if (!pkgSetting.disableComponentLPw(className, userId)) {
20154 case COMPONENT_ENABLED_STATE_DEFAULT:
20155 if (!pkgSetting.restoreComponentLPw(className, userId)) {
20160 Slog.e(TAG, "Invalid new component state: " + newState);
20164 scheduleWritePackageRestrictionsLocked(userId);
20165 updateSequenceNumberLP(packageName, new int[] { userId });
20166 final long callingId = Binder.clearCallingIdentity();
20168 updateInstantAppInstallerLocked(packageName);
20170 Binder.restoreCallingIdentity(callingId);
20172 components = mPendingBroadcasts.get(userId, packageName);
20173 final boolean newPackage = components == null;
20175 components = new ArrayList<String>();
20177 if (!components.contains(componentName)) {
20178 components.add(componentName);
20180 if ((flags&PackageManager.DONT_KILL_APP) == 0) {
20182 // Purge entry from pending broadcast list if another one exists already
20183 // since we are sending one right away.
20184 mPendingBroadcasts.remove(userId, packageName);
20187 mPendingBroadcasts.put(userId, packageName, components);
20189 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
20190 // Schedule a message
20191 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
20196 long callingId = Binder.clearCallingIdentity();
20199 packageUid = UserHandle.getUid(userId, pkgSetting.appId);
20200 sendPackageChangedBroadcast(packageName,
20201 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
20204 Binder.restoreCallingIdentity(callingId);
20209 public void flushPackageRestrictionsAsUser(int userId) {
20210 if (!sUserManager.exists(userId)) {
20213 enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
20214 false /* checkShell */, "flushPackageRestrictions");
20215 synchronized (mPackages) {
20216 mSettings.writePackageRestrictionsLPr(userId);
20217 mDirtyUsers.remove(userId);
20218 if (mDirtyUsers.isEmpty()) {
20219 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
20224 private void sendPackageChangedBroadcast(String packageName,
20225 boolean killFlag, ArrayList<String> componentNames, int packageUid) {
20227 Log.v(TAG, "Sending package changed: package=" + packageName + " components="
20229 Bundle extras = new Bundle(4);
20230 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
20231 String nameList[] = new String[componentNames.size()];
20232 componentNames.toArray(nameList);
20233 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
20234 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
20235 extras.putInt(Intent.EXTRA_UID, packageUid);
20236 // If this is not reporting a change of the overall package, then only send it
20237 // to registered receivers. We don't want to launch a swath of apps for every
20238 // little component state change.
20239 final int flags = !componentNames.contains(packageName)
20240 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
20241 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, flags, null, null,
20242 new int[] {UserHandle.getUserId(packageUid)});
20246 public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
20247 if (!sUserManager.exists(userId)) return;
20248 final int uid = Binder.getCallingUid();
20249 final int permission = mContext.checkCallingOrSelfPermission(
20250 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20251 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20252 enforceCrossUserPermission(uid, userId,
20253 true /* requireFullPermission */, true /* checkShell */, "stop package");
20255 synchronized (mPackages) {
20256 if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
20257 allowedByPermission, uid, userId)) {
20258 scheduleWritePackageRestrictionsLocked(userId);
20264 public String getInstallerPackageName(String packageName) {
20266 synchronized (mPackages) {
20267 return mSettings.getInstallerPackageNameLPr(packageName);
20271 public boolean isOrphaned(String packageName) {
20273 synchronized (mPackages) {
20274 return mSettings.isOrphaned(packageName);
20279 public int getApplicationEnabledSetting(String packageName, int userId) {
20280 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20281 int uid = Binder.getCallingUid();
20282 enforceCrossUserPermission(uid, userId,
20283 false /* requireFullPermission */, false /* checkShell */, "get enabled");
20285 synchronized (mPackages) {
20286 return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
20291 public int getComponentEnabledSetting(ComponentName componentName, int userId) {
20292 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20293 int uid = Binder.getCallingUid();
20294 enforceCrossUserPermission(uid, userId,
20295 false /* requireFullPermission */, false /* checkShell */, "get component enabled");
20297 synchronized (mPackages) {
20298 return mSettings.getComponentEnabledSettingLPr(componentName, userId);
20303 public void enterSafeMode() {
20304 enforceSystemOrRoot("Only the system can request entering safe mode");
20306 if (!mSystemReady) {
20312 public void systemReady() {
20313 mSystemReady = true;
20314 final ContentResolver resolver = mContext.getContentResolver();
20315 ContentObserver co = new ContentObserver(mHandler) {
20317 public void onChange(boolean selfChange) {
20318 mEphemeralAppsDisabled =
20319 (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) ||
20320 (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0);
20323 mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
20324 .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
20325 false, co, UserHandle.USER_SYSTEM);
20326 mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
20327 .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM);
20330 // Disable any carrier apps. We do this very early in boot to prevent the apps from being
20331 // disabled after already being started.
20332 CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
20333 mContext.getContentResolver(), UserHandle.USER_SYSTEM);
20335 // Read the compatibilty setting when the system is ready.
20336 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
20337 mContext.getContentResolver(),
20338 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
20339 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
20340 if (DEBUG_SETTINGS) {
20341 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
20344 int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
20346 synchronized (mPackages) {
20347 // Verify that all of the preferred activity components actually
20348 // exist. It is possible for applications to be updated and at
20349 // that point remove a previously declared activity component that
20350 // had been set as a preferred activity. We try to clean this up
20351 // the next time we encounter that preferred activity, but it is
20352 // possible for the user flow to never be able to return to that
20353 // situation so here we do a sanity check to make sure we haven't
20354 // left any junk around.
20355 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
20356 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20357 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20359 for (PreferredActivity pa : pir.filterSet()) {
20360 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
20364 if (removed.size() > 0) {
20365 for (int r=0; r<removed.size(); r++) {
20366 PreferredActivity pa = removed.get(r);
20367 Slog.w(TAG, "Removing dangling preferred activity: "
20368 + pa.mPref.mComponent);
20369 pir.removeFilter(pa);
20371 mSettings.writePackageRestrictionsLPr(
20372 mSettings.mPreferredActivities.keyAt(i));
20376 for (int userId : UserManagerService.getInstance().getUserIds()) {
20377 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
20378 grantPermissionsUserIds = ArrayUtils.appendInt(
20379 grantPermissionsUserIds, userId);
20383 sUserManager.systemReady();
20385 // If we upgraded grant all default permissions before kicking off.
20386 for (int userId : grantPermissionsUserIds) {
20387 mDefaultPermissionPolicy.grantDefaultPermissions(userId);
20390 // If we did not grant default permissions, we preload from this the
20391 // default permission exceptions lazily to ensure we don't hit the
20392 // disk on a new user creation.
20393 if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
20394 mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
20397 // Kick off any messages waiting for system ready
20398 if (mPostSystemReadyMessages != null) {
20399 for (Message msg : mPostSystemReadyMessages) {
20400 msg.sendToTarget();
20402 mPostSystemReadyMessages = null;
20405 // Watch for external volumes that come and go over time
20406 final StorageManager storage = mContext.getSystemService(StorageManager.class);
20407 storage.registerListener(mStorageListener);
20409 mInstallerService.systemReady();
20410 mPackageDexOptimizer.systemReady();
20412 StorageManagerInternal StorageManagerInternal = LocalServices.getService(
20413 StorageManagerInternal.class);
20414 StorageManagerInternal.addExternalStoragePolicy(
20415 new StorageManagerInternal.ExternalStorageMountPolicy() {
20417 public int getMountMode(int uid, String packageName) {
20418 if (Process.isIsolated(uid)) {
20419 return Zygote.MOUNT_EXTERNAL_NONE;
20421 if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
20422 return Zygote.MOUNT_EXTERNAL_DEFAULT;
20424 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20425 return Zygote.MOUNT_EXTERNAL_DEFAULT;
20427 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20428 return Zygote.MOUNT_EXTERNAL_READ;
20430 return Zygote.MOUNT_EXTERNAL_WRITE;
20434 public boolean hasExternalStorage(int uid, String packageName) {
20439 // Now that we're mostly running, clean up stale users and apps
20440 sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
20441 reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
20443 if (mPrivappPermissionsViolations != null) {
20444 Slog.wtf(TAG,"Signature|privileged permissions not in "
20445 + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
20446 mPrivappPermissionsViolations = null;
20450 public void waitForAppDataPrepared() {
20451 if (mPrepareAppDataFuture == null) {
20454 ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
20455 mPrepareAppDataFuture = null;
20459 public boolean isSafeMode() {
20464 public boolean hasSystemUidErrors() {
20465 return mHasSystemUidErrors;
20468 static String arrayToString(int[] array) {
20469 StringBuffer buf = new StringBuffer(128);
20471 if (array != null) {
20472 for (int i=0; i<array.length; i++) {
20473 if (i > 0) buf.append(", ");
20474 buf.append(array[i]);
20478 return buf.toString();
20481 static class DumpState {
20482 public static final int DUMP_LIBS = 1 << 0;
20483 public static final int DUMP_FEATURES = 1 << 1;
20484 public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2;
20485 public static final int DUMP_SERVICE_RESOLVERS = 1 << 3;
20486 public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4;
20487 public static final int DUMP_CONTENT_RESOLVERS = 1 << 5;
20488 public static final int DUMP_PERMISSIONS = 1 << 6;
20489 public static final int DUMP_PACKAGES = 1 << 7;
20490 public static final int DUMP_SHARED_USERS = 1 << 8;
20491 public static final int DUMP_MESSAGES = 1 << 9;
20492 public static final int DUMP_PROVIDERS = 1 << 10;
20493 public static final int DUMP_VERIFIERS = 1 << 11;
20494 public static final int DUMP_PREFERRED = 1 << 12;
20495 public static final int DUMP_PREFERRED_XML = 1 << 13;
20496 public static final int DUMP_KEYSETS = 1 << 14;
20497 public static final int DUMP_VERSION = 1 << 15;
20498 public static final int DUMP_INSTALLS = 1 << 16;
20499 public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17;
20500 public static final int DUMP_DOMAIN_PREFERRED = 1 << 18;
20501 public static final int DUMP_FROZEN = 1 << 19;
20502 public static final int DUMP_DEXOPT = 1 << 20;
20503 public static final int DUMP_COMPILER_STATS = 1 << 21;
20504 public static final int DUMP_ENABLED_OVERLAYS = 1 << 22;
20506 public static final int OPTION_SHOW_FILTERS = 1 << 0;
20508 private int mTypes;
20510 private int mOptions;
20512 private boolean mTitlePrinted;
20514 private SharedUserSetting mSharedUser;
20516 public boolean isDumping(int type) {
20517 if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
20521 return (mTypes & type) != 0;
20524 public void setDump(int type) {
20528 public boolean isOptionEnabled(int option) {
20529 return (mOptions & option) != 0;
20532 public void setOptionEnabled(int option) {
20533 mOptions |= option;
20536 public boolean onTitlePrinted() {
20537 final boolean printed = mTitlePrinted;
20538 mTitlePrinted = true;
20542 public boolean getTitlePrinted() {
20543 return mTitlePrinted;
20546 public void setTitlePrinted(boolean enabled) {
20547 mTitlePrinted = enabled;
20550 public SharedUserSetting getSharedUser() {
20551 return mSharedUser;
20554 public void setSharedUser(SharedUserSetting user) {
20555 mSharedUser = user;
20560 public void onShellCommand(FileDescriptor in, FileDescriptor out,
20561 FileDescriptor err, String[] args, ShellCallback callback,
20562 ResultReceiver resultReceiver) {
20563 (new PackageManagerShellCommand(this)).exec(
20564 this, in, out, err, args, callback, resultReceiver);
20568 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
20569 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
20571 DumpState dumpState = new DumpState();
20572 boolean fullPreferred = false;
20573 boolean checkin = false;
20575 String packageName = null;
20576 ArraySet<String> permissionNames = null;
20579 while (opti < args.length) {
20580 String opt = args[opti];
20581 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
20586 if ("-a".equals(opt)) {
20587 // Right now we only know how to print all.
20588 } else if ("-h".equals(opt)) {
20589 pw.println("Package manager dump options:");
20590 pw.println(" [-h] [-f] [--checkin] [cmd] ...");
20591 pw.println(" --checkin: dump for a checkin");
20592 pw.println(" -f: print details of intent filters");
20593 pw.println(" -h: print this help");
20594 pw.println(" cmd may be one of:");
20595 pw.println(" l[ibraries]: list known shared libraries");
20596 pw.println(" f[eatures]: list device features");
20597 pw.println(" k[eysets]: print known keysets");
20598 pw.println(" r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
20599 pw.println(" perm[issions]: dump permissions");
20600 pw.println(" permission [name ...]: dump declaration and use of given permission");
20601 pw.println(" pref[erred]: print preferred package settings");
20602 pw.println(" preferred-xml [--full]: print preferred package settings as xml");
20603 pw.println(" prov[iders]: dump content providers");
20604 pw.println(" p[ackages]: dump installed packages");
20605 pw.println(" s[hared-users]: dump shared user IDs");
20606 pw.println(" m[essages]: print collected runtime messages");
20607 pw.println(" v[erifiers]: print package verifier info");
20608 pw.println(" d[omain-preferred-apps]: print domains preferred apps");
20609 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
20610 pw.println(" version: print database version info");
20611 pw.println(" write: write current settings now");
20612 pw.println(" installs: details about install sessions");
20613 pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?");
20614 pw.println(" dexopt: dump dexopt state");
20615 pw.println(" compiler-stats: dump compiler statistics");
20616 pw.println(" enabled-overlays: dump list of enabled overlay packages");
20617 pw.println(" <package.name>: info about given package");
20619 } else if ("--checkin".equals(opt)) {
20621 } else if ("-f".equals(opt)) {
20622 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
20623 } else if ("--proto".equals(opt)) {
20627 pw.println("Unknown argument: " + opt + "; use -h for help");
20631 // Is the caller requesting to dump a particular piece of data?
20632 if (opti < args.length) {
20633 String cmd = args[opti];
20635 // Is this a package name?
20636 if ("android".equals(cmd) || cmd.contains(".")) {
20638 // When dumping a single package, we always dump all of its
20639 // filter information since the amount of data will be reasonable.
20640 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
20641 } else if ("check-permission".equals(cmd)) {
20642 if (opti >= args.length) {
20643 pw.println("Error: check-permission missing permission argument");
20646 String perm = args[opti];
20648 if (opti >= args.length) {
20649 pw.println("Error: check-permission missing package argument");
20653 String pkg = args[opti];
20655 int user = UserHandle.getUserId(Binder.getCallingUid());
20656 if (opti < args.length) {
20658 user = Integer.parseInt(args[opti]);
20659 } catch (NumberFormatException e) {
20660 pw.println("Error: check-permission user argument is not a number: "
20666 // Normalize package name to handle renamed packages and static libs
20667 pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
20669 pw.println(checkPermission(perm, pkg, user));
20671 } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
20672 dumpState.setDump(DumpState.DUMP_LIBS);
20673 } else if ("f".equals(cmd) || "features".equals(cmd)) {
20674 dumpState.setDump(DumpState.DUMP_FEATURES);
20675 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
20676 if (opti >= args.length) {
20677 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
20678 | DumpState.DUMP_SERVICE_RESOLVERS
20679 | DumpState.DUMP_RECEIVER_RESOLVERS
20680 | DumpState.DUMP_CONTENT_RESOLVERS);
20682 while (opti < args.length) {
20683 String name = args[opti];
20684 if ("a".equals(name) || "activity".equals(name)) {
20685 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
20686 } else if ("s".equals(name) || "service".equals(name)) {
20687 dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
20688 } else if ("r".equals(name) || "receiver".equals(name)) {
20689 dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
20690 } else if ("c".equals(name) || "content".equals(name)) {
20691 dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
20693 pw.println("Error: unknown resolver table type: " + name);
20699 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
20700 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
20701 } else if ("permission".equals(cmd)) {
20702 if (opti >= args.length) {
20703 pw.println("Error: permission requires permission name");
20706 permissionNames = new ArraySet<>();
20707 while (opti < args.length) {
20708 permissionNames.add(args[opti]);
20711 dumpState.setDump(DumpState.DUMP_PERMISSIONS
20712 | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
20713 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
20714 dumpState.setDump(DumpState.DUMP_PREFERRED);
20715 } else if ("preferred-xml".equals(cmd)) {
20716 dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
20717 if (opti < args.length && "--full".equals(args[opti])) {
20718 fullPreferred = true;
20721 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
20722 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
20723 } else if ("p".equals(cmd) || "packages".equals(cmd)) {
20724 dumpState.setDump(DumpState.DUMP_PACKAGES);
20725 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
20726 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
20727 } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
20728 dumpState.setDump(DumpState.DUMP_PROVIDERS);
20729 } else if ("m".equals(cmd) || "messages".equals(cmd)) {
20730 dumpState.setDump(DumpState.DUMP_MESSAGES);
20731 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
20732 dumpState.setDump(DumpState.DUMP_VERIFIERS);
20733 } else if ("i".equals(cmd) || "ifv".equals(cmd)
20734 || "intent-filter-verifiers".equals(cmd)) {
20735 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
20736 } else if ("version".equals(cmd)) {
20737 dumpState.setDump(DumpState.DUMP_VERSION);
20738 } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
20739 dumpState.setDump(DumpState.DUMP_KEYSETS);
20740 } else if ("installs".equals(cmd)) {
20741 dumpState.setDump(DumpState.DUMP_INSTALLS);
20742 } else if ("frozen".equals(cmd)) {
20743 dumpState.setDump(DumpState.DUMP_FROZEN);
20744 } else if ("dexopt".equals(cmd)) {
20745 dumpState.setDump(DumpState.DUMP_DEXOPT);
20746 } else if ("compiler-stats".equals(cmd)) {
20747 dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
20748 } else if ("enabled-overlays".equals(cmd)) {
20749 dumpState.setDump(DumpState.DUMP_ENABLED_OVERLAYS);
20750 } else if ("write".equals(cmd)) {
20751 synchronized (mPackages) {
20752 mSettings.writeLPr();
20753 pw.println("Settings written.");
20760 pw.println("vers,1");
20764 synchronized (mPackages) {
20765 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
20767 if (dumpState.onTitlePrinted())
20769 pw.println("Database versions:");
20770 mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, " "));
20774 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
20776 if (dumpState.onTitlePrinted())
20778 pw.println("Verifiers:");
20779 pw.print(" Required: ");
20780 pw.print(mRequiredVerifierPackage);
20781 pw.print(" (uid=");
20782 pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
20783 UserHandle.USER_SYSTEM));
20785 } else if (mRequiredVerifierPackage != null) {
20786 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
20788 pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
20789 UserHandle.USER_SYSTEM));
20793 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
20794 packageName == null) {
20795 if (mIntentFilterVerifierComponent != null) {
20796 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
20798 if (dumpState.onTitlePrinted())
20800 pw.println("Intent Filter Verifier:");
20801 pw.print(" Using: ");
20802 pw.print(verifierPackageName);
20803 pw.print(" (uid=");
20804 pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
20805 UserHandle.USER_SYSTEM));
20807 } else if (verifierPackageName != null) {
20808 pw.print("ifv,"); pw.print(verifierPackageName);
20810 pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
20811 UserHandle.USER_SYSTEM));
20815 pw.println("No Intent Filter Verifier available!");
20819 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
20820 boolean printedHeader = false;
20821 final Iterator<String> it = mSharedLibraries.keySet().iterator();
20822 while (it.hasNext()) {
20823 String libName = it.next();
20824 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
20825 if (versionedLib == null) {
20828 final int versionCount = versionedLib.size();
20829 for (int i = 0; i < versionCount; i++) {
20830 SharedLibraryEntry libEntry = versionedLib.valueAt(i);
20832 if (!printedHeader) {
20833 if (dumpState.onTitlePrinted())
20835 pw.println("Libraries:");
20836 printedHeader = true;
20842 pw.print(libEntry.info.getName());
20843 if (libEntry.info.isStatic()) {
20844 pw.print(" version=" + libEntry.info.getVersion());
20849 if (libEntry.path != null) {
20850 pw.print(" (jar) ");
20851 pw.print(libEntry.path);
20853 pw.print(" (apk) ");
20854 pw.print(libEntry.apk);
20861 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
20862 if (dumpState.onTitlePrinted())
20865 pw.println("Features:");
20868 synchronized (mAvailableFeatures) {
20869 for (FeatureInfo feat : mAvailableFeatures.values()) {
20872 pw.print(feat.name);
20874 pw.println(feat.version);
20877 pw.print(feat.name);
20878 if (feat.version > 0) {
20879 pw.print(" version=");
20880 pw.print(feat.version);
20888 if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
20889 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
20890 : "Activity Resolver Table:", " ", packageName,
20891 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20892 dumpState.setTitlePrinted(true);
20895 if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
20896 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
20897 : "Receiver Resolver Table:", " ", packageName,
20898 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20899 dumpState.setTitlePrinted(true);
20902 if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
20903 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
20904 : "Service Resolver Table:", " ", packageName,
20905 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20906 dumpState.setTitlePrinted(true);
20909 if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
20910 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
20911 : "Provider Resolver Table:", " ", packageName,
20912 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20913 dumpState.setTitlePrinted(true);
20917 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
20918 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20919 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20920 int user = mSettings.mPreferredActivities.keyAt(i);
20922 dumpState.getTitlePrinted()
20923 ? "\nPreferred Activities User " + user + ":"
20924 : "Preferred Activities User " + user + ":", " ",
20925 packageName, true, false)) {
20926 dumpState.setTitlePrinted(true);
20931 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
20933 FileOutputStream fout = new FileOutputStream(fd);
20934 BufferedOutputStream str = new BufferedOutputStream(fout);
20935 XmlSerializer serializer = new FastXmlSerializer();
20937 serializer.setOutput(str, StandardCharsets.UTF_8.name());
20938 serializer.startDocument(null, true);
20939 serializer.setFeature(
20940 "http://xmlpull.org/v1/doc/features.html#indent-output", true);
20941 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
20942 serializer.endDocument();
20943 serializer.flush();
20944 } catch (IllegalArgumentException e) {
20945 pw.println("Failed writing: " + e);
20946 } catch (IllegalStateException e) {
20947 pw.println("Failed writing: " + e);
20948 } catch (IOException e) {
20949 pw.println("Failed writing: " + e);
20954 && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
20955 && packageName == null) {
20957 int count = mSettings.mPackages.size();
20959 pw.println("No applications!");
20962 final String prefix = " ";
20963 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
20964 if (allPackageSettings.size() == 0) {
20965 pw.println("No domain preferred apps!");
20968 pw.println("App verification status:");
20971 for (PackageSetting ps : allPackageSettings) {
20972 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
20973 if (ivi == null || ivi.getPackageName() == null) continue;
20974 pw.println(prefix + "Package: " + ivi.getPackageName());
20975 pw.println(prefix + "Domains: " + ivi.getDomainsString());
20976 pw.println(prefix + "Status: " + ivi.getStatusString());
20981 pw.println(prefix + "No app verification established.");
20984 for (int userId : sUserManager.getUserIds()) {
20985 pw.println("App linkages for user " + userId + ":");
20988 for (PackageSetting ps : allPackageSettings) {
20989 final long status = ps.getDomainVerificationStatusForUser(userId);
20990 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
20991 && !DEBUG_DOMAIN_VERIFICATION) {
20994 pw.println(prefix + "Package: " + ps.name);
20995 pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
20996 String statusStr = IntentFilterVerificationInfo.
20997 getStatusStringFromValue(status);
20998 pw.println(prefix + "Status: " + statusStr);
21003 pw.println(prefix + "No configured app linkages.");
21011 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
21012 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
21013 if (packageName == null && permissionNames == null) {
21014 for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
21016 if (dumpState.onTitlePrinted())
21018 pw.println("AppOp Permissions:");
21020 pw.print(" AppOp Permission ");
21021 pw.print(mAppOpPermissionPackages.keyAt(iperm));
21023 ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
21024 for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
21025 pw.print(" "); pw.println(pkgs.valueAt(ipkg));
21031 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
21032 boolean printedSomething = false;
21033 for (PackageParser.Provider p : mProviders.mProviders.values()) {
21034 if (packageName != null && !packageName.equals(p.info.packageName)) {
21037 if (!printedSomething) {
21038 if (dumpState.onTitlePrinted())
21040 pw.println("Registered ContentProviders:");
21041 printedSomething = true;
21043 pw.print(" "); p.printComponentShortName(pw); pw.println(":");
21044 pw.print(" "); pw.println(p.toString());
21046 printedSomething = false;
21047 for (Map.Entry<String, PackageParser.Provider> entry :
21048 mProvidersByAuthority.entrySet()) {
21049 PackageParser.Provider p = entry.getValue();
21050 if (packageName != null && !packageName.equals(p.info.packageName)) {
21053 if (!printedSomething) {
21054 if (dumpState.onTitlePrinted())
21056 pw.println("ContentProvider Authorities:");
21057 printedSomething = true;
21059 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:");
21060 pw.print(" "); pw.println(p.toString());
21061 if (p.info != null && p.info.applicationInfo != null) {
21062 final String appInfo = p.info.applicationInfo.toString();
21063 pw.print(" applicationInfo="); pw.println(appInfo);
21068 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
21069 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
21072 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
21073 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
21076 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
21077 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
21080 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
21081 mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
21084 if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
21085 // XXX should handle packageName != null by dumping only install data that
21086 // the given package is involved with.
21087 if (dumpState.onTitlePrinted()) pw.println();
21089 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120);
21091 ipw.println("Frozen packages:");
21092 ipw.increaseIndent();
21093 if (mFrozenPackages.size() == 0) {
21094 ipw.println("(none)");
21096 for (int i = 0; i < mFrozenPackages.size(); i++) {
21097 ipw.println(mFrozenPackages.valueAt(i));
21100 ipw.decreaseIndent();
21103 if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
21104 if (dumpState.onTitlePrinted()) pw.println();
21105 dumpDexoptStateLPr(pw, packageName);
21108 if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
21109 if (dumpState.onTitlePrinted()) pw.println();
21110 dumpCompilerStatsLPr(pw, packageName);
21113 if (!checkin && dumpState.isDumping(DumpState.DUMP_ENABLED_OVERLAYS)) {
21114 if (dumpState.onTitlePrinted()) pw.println();
21115 dumpEnabledOverlaysLPr(pw);
21118 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
21119 if (dumpState.onTitlePrinted()) pw.println();
21120 mSettings.dumpReadMessagesLPr(pw, dumpState);
21123 pw.println("Package warning messages:");
21124 BufferedReader in = null;
21125 String line = null;
21127 in = new BufferedReader(new FileReader(getSettingsProblemFile()));
21128 while ((line = in.readLine()) != null) {
21129 if (line.contains("ignored: updated version")) continue;
21132 } catch (IOException ignored) {
21134 IoUtils.closeQuietly(in);
21138 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
21139 BufferedReader in = null;
21140 String line = null;
21142 in = new BufferedReader(new FileReader(getSettingsProblemFile()));
21143 while ((line = in.readLine()) != null) {
21144 if (line.contains("ignored: updated version")) continue;
21148 } catch (IOException ignored) {
21150 IoUtils.closeQuietly(in);
21155 // PackageInstaller should be called outside of mPackages lock
21156 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
21157 // XXX should handle packageName != null by dumping only install data that
21158 // the given package is involved with.
21159 if (dumpState.onTitlePrinted()) pw.println();
21160 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120));
21164 private void dumpProto(FileDescriptor fd) {
21165 final ProtoOutputStream proto = new ProtoOutputStream(fd);
21167 synchronized (mPackages) {
21168 final long requiredVerifierPackageToken =
21169 proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
21170 proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
21172 PackageServiceDumpProto.PackageShortProto.UID,
21174 mRequiredVerifierPackage,
21175 MATCH_DEBUG_TRIAGED_MISSING,
21176 UserHandle.USER_SYSTEM));
21177 proto.end(requiredVerifierPackageToken);
21179 if (mIntentFilterVerifierComponent != null) {
21180 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
21181 final long verifierPackageToken =
21182 proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
21183 proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
21185 PackageServiceDumpProto.PackageShortProto.UID,
21187 verifierPackageName,
21188 MATCH_DEBUG_TRIAGED_MISSING,
21189 UserHandle.USER_SYSTEM));
21190 proto.end(verifierPackageToken);
21193 dumpSharedLibrariesProto(proto);
21194 dumpFeaturesProto(proto);
21195 mSettings.dumpPackagesProto(proto);
21196 mSettings.dumpSharedUsersProto(proto);
21197 dumpMessagesProto(proto);
21202 private void dumpMessagesProto(ProtoOutputStream proto) {
21203 BufferedReader in = null;
21204 String line = null;
21206 in = new BufferedReader(new FileReader(getSettingsProblemFile()));
21207 while ((line = in.readLine()) != null) {
21208 if (line.contains("ignored: updated version")) continue;
21209 proto.write(PackageServiceDumpProto.MESSAGES, line);
21211 } catch (IOException ignored) {
21213 IoUtils.closeQuietly(in);
21217 private void dumpFeaturesProto(ProtoOutputStream proto) {
21218 synchronized (mAvailableFeatures) {
21219 final int count = mAvailableFeatures.size();
21220 for (int i = 0; i < count; i++) {
21221 final FeatureInfo feat = mAvailableFeatures.valueAt(i);
21222 final long featureToken = proto.start(PackageServiceDumpProto.FEATURES);
21223 proto.write(PackageServiceDumpProto.FeatureProto.NAME, feat.name);
21224 proto.write(PackageServiceDumpProto.FeatureProto.VERSION, feat.version);
21225 proto.end(featureToken);
21230 private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
21231 final int count = mSharedLibraries.size();
21232 for (int i = 0; i < count; i++) {
21233 final String libName = mSharedLibraries.keyAt(i);
21234 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
21235 if (versionedLib == null) {
21238 final int versionCount = versionedLib.size();
21239 for (int j = 0; j < versionCount; j++) {
21240 final SharedLibraryEntry libEntry = versionedLib.valueAt(j);
21241 final long sharedLibraryToken =
21242 proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
21243 proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libEntry.info.getName());
21244 final boolean isJar = (libEntry.path != null);
21245 proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
21247 proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH, libEntry.path);
21249 proto.write(PackageServiceDumpProto.SharedLibraryProto.APK, libEntry.apk);
21251 proto.end(sharedLibraryToken);
21256 private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
21257 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120);
21259 ipw.println("Dexopt state:");
21260 ipw.increaseIndent();
21261 Collection<PackageParser.Package> packages = null;
21262 if (packageName != null) {
21263 PackageParser.Package targetPackage = mPackages.get(packageName);
21264 if (targetPackage != null) {
21265 packages = Collections.singletonList(targetPackage);
21267 ipw.println("Unable to find package: " + packageName);
21271 packages = mPackages.values();
21274 for (PackageParser.Package pkg : packages) {
21275 ipw.println("[" + pkg.packageName + "]");
21276 ipw.increaseIndent();
21277 mPackageDexOptimizer.dumpDexoptState(ipw, pkg);
21278 ipw.decreaseIndent();
21282 private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
21283 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120);
21285 ipw.println("Compiler stats:");
21286 ipw.increaseIndent();
21287 Collection<PackageParser.Package> packages = null;
21288 if (packageName != null) {
21289 PackageParser.Package targetPackage = mPackages.get(packageName);
21290 if (targetPackage != null) {
21291 packages = Collections.singletonList(targetPackage);
21293 ipw.println("Unable to find package: " + packageName);
21297 packages = mPackages.values();
21300 for (PackageParser.Package pkg : packages) {
21301 ipw.println("[" + pkg.packageName + "]");
21302 ipw.increaseIndent();
21304 CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
21305 if (stats == null) {
21306 ipw.println("(No recorded stats)");
21310 ipw.decreaseIndent();
21314 private void dumpEnabledOverlaysLPr(PrintWriter pw) {
21315 pw.println("Enabled overlay paths:");
21316 final int N = mEnabledOverlayPaths.size();
21317 for (int i = 0; i < N; i++) {
21318 final int userId = mEnabledOverlayPaths.keyAt(i);
21319 pw.println(String.format(" User %d:", userId));
21320 final ArrayMap<String, ArrayList<String>> userSpecificOverlays =
21321 mEnabledOverlayPaths.valueAt(i);
21322 final int M = userSpecificOverlays.size();
21323 for (int j = 0; j < M; j++) {
21324 final String targetPackageName = userSpecificOverlays.keyAt(j);
21325 final ArrayList<String> overlayPackagePaths = userSpecificOverlays.valueAt(j);
21326 pw.println(String.format(" %s: %s", targetPackageName, overlayPackagePaths));
21331 private String dumpDomainString(String packageName) {
21332 List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
21334 List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
21336 ArraySet<String> result = new ArraySet<>();
21337 if (iviList.size() > 0) {
21338 for (IntentFilterVerificationInfo ivi : iviList) {
21339 for (String host : ivi.getDomains()) {
21344 if (filters != null && filters.size() > 0) {
21345 for (IntentFilter filter : filters) {
21346 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
21347 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
21348 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
21349 result.addAll(filter.getHostsList());
21354 StringBuilder sb = new StringBuilder(result.size() * 16);
21355 for (String domain : result) {
21356 if (sb.length() > 0) sb.append(" ");
21359 return sb.toString();
21362 // ------- apps on sdcard specific code -------
21363 static final boolean DEBUG_SD_INSTALL = false;
21365 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
21367 private static final String SD_ENCRYPTION_ALGORITHM = "AES";
21369 private boolean mMediaMounted = false;
21371 static String getEncryptKey() {
21373 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
21374 SD_ENCRYPTION_KEYSTORE_NAME);
21375 if (sdEncKey == null) {
21376 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
21377 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
21378 if (sdEncKey == null) {
21379 Slog.e(TAG, "Failed to create encryption keys");
21384 } catch (NoSuchAlgorithmException nsae) {
21385 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
21387 } catch (IOException ioe) {
21388 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
21394 * Update media status on PackageManager.
21397 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
21398 int callingUid = Binder.getCallingUid();
21399 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
21400 throw new SecurityException("Media status can only be updated by the system");
21402 // reader; this apparently protects mMediaMounted, but should probably
21403 // be a different lock in that case.
21404 synchronized (mPackages) {
21405 Log.i(TAG, "Updating external media status from "
21406 + (mMediaMounted ? "mounted" : "unmounted") + " to "
21407 + (mediaStatus ? "mounted" : "unmounted"));
21408 if (DEBUG_SD_INSTALL)
21409 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
21410 + ", mMediaMounted=" + mMediaMounted);
21411 if (mediaStatus == mMediaMounted) {
21412 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
21414 mHandler.sendMessage(msg);
21417 mMediaMounted = mediaStatus;
21419 // Queue up an async operation since the package installation may take a
21421 mHandler.post(new Runnable() {
21422 public void run() {
21423 updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
21429 * Called by StorageManagerService when the initial ASECs to scan are available.
21430 * Should block until all the ASEC containers are finished being scanned.
21432 public void scanAvailableAsecs() {
21433 updateExternalMediaStatusInner(true, false, false);
21437 * Collect information of applications on external media, map them against
21438 * existing containers and update information based on current mount status.
21439 * Please note that we always have to report status if reportStatus has been
21440 * set to true especially when unloading packages.
21442 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
21443 boolean externalStorage) {
21444 ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
21445 int[] uidArr = EmptyArray.INT;
21447 final String[] list = PackageHelper.getSecureContainerList();
21448 if (ArrayUtils.isEmpty(list)) {
21449 Log.i(TAG, "No secure containers found");
21451 // Process list of secure containers and categorize them
21452 // as active or stale based on their package internal state.
21455 synchronized (mPackages) {
21456 for (String cid : list) {
21457 // Leave stages untouched for now; installer service owns them
21458 if (PackageInstallerService.isStageName(cid)) continue;
21460 if (DEBUG_SD_INSTALL)
21461 Log.i(TAG, "Processing container " + cid);
21462 String pkgName = getAsecPackageName(cid);
21463 if (pkgName == null) {
21464 Slog.i(TAG, "Found stale container " + cid + " with no package name");
21467 if (DEBUG_SD_INSTALL)
21468 Log.i(TAG, "Looking for pkg : " + pkgName);
21470 final PackageSetting ps = mSettings.mPackages.get(pkgName);
21472 Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
21477 * Skip packages that are not external if we're unmounting
21478 * external storage.
21480 if (externalStorage && !isMounted && !isExternal(ps)) {
21484 final AsecInstallArgs args = new AsecInstallArgs(cid,
21485 getAppDexInstructionSets(ps), ps.isForwardLocked());
21486 // The package status is changed only if the code path
21487 // matches between settings and the container id.
21488 if (ps.codePathString != null
21489 && ps.codePathString.startsWith(args.getCodePath())) {
21490 if (DEBUG_SD_INSTALL) {
21491 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
21492 + " at code path: " + ps.codePathString);
21495 // We do have a valid package installed on sdcard
21496 processCids.put(args, ps.codePathString);
21497 final int uid = ps.appId;
21499 uidArr = ArrayUtils.appendInt(uidArr, uid);
21502 Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
21503 + ps.codePathString);
21508 Arrays.sort(uidArr);
21511 // Process packages with valid entries.
21513 if (DEBUG_SD_INSTALL)
21514 Log.i(TAG, "Loading packages");
21515 loadMediaPackages(processCids, uidArr, externalStorage);
21516 startCleaningPackages();
21517 mInstallerService.onSecureContainersAvailable();
21519 if (DEBUG_SD_INSTALL)
21520 Log.i(TAG, "Unloading packages");
21521 unloadMediaPackages(processCids, uidArr, reportStatus);
21525 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21526 ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
21527 final int size = infos.size();
21528 final String[] packageNames = new String[size];
21529 final int[] packageUids = new int[size];
21530 for (int i = 0; i < size; i++) {
21531 final ApplicationInfo info = infos.get(i);
21532 packageNames[i] = info.packageName;
21533 packageUids[i] = info.uid;
21535 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
21539 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21540 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21541 sendResourcesChangedBroadcast(mediaStatus, replacing,
21542 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
21545 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21546 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21547 int size = pkgList.length;
21549 // Send broadcasts here
21550 Bundle extras = new Bundle();
21551 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
21552 if (uidArr != null) {
21553 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
21556 extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
21558 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
21559 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
21560 sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null);
21565 * Look at potentially valid container ids from processCids If package
21566 * information doesn't match the one on record or package scanning fails,
21567 * the cid is added to list of removeCids. We currently don't delete stale
21570 private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr,
21571 boolean externalStorage) {
21572 ArrayList<String> pkgList = new ArrayList<String>();
21573 Set<AsecInstallArgs> keys = processCids.keySet();
21575 for (AsecInstallArgs args : keys) {
21576 String codePath = processCids.get(args);
21577 if (DEBUG_SD_INSTALL)
21578 Log.i(TAG, "Loading container : " + args.cid);
21579 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
21581 // Make sure there are no container errors first.
21582 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
21583 Slog.e(TAG, "Failed to mount cid : " + args.cid
21584 + " when installing from sdcard");
21587 // Check code path here.
21588 if (codePath == null || !codePath.startsWith(args.getCodePath())) {
21589 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
21590 + " does not match one in settings " + codePath);
21594 int parseFlags = mDefParseFlags;
21595 if (args.isExternalAsec()) {
21596 parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
21598 if (args.isFwdLocked()) {
21599 parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
21602 synchronized (mInstallLock) {
21603 PackageParser.Package pkg = null;
21605 // Sadly we don't know the package name yet to freeze it
21606 pkg = scanPackageTracedLI(new File(codePath), parseFlags,
21607 SCAN_IGNORE_FROZEN, 0, null);
21608 } catch (PackageManagerException e) {
21609 Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
21611 // Scan the package
21614 * TODO why is the lock being held? doPostInstall is
21615 * called in other places without the lock. This needs
21616 * to be straightened out.
21619 synchronized (mPackages) {
21620 retCode = PackageManager.INSTALL_SUCCEEDED;
21621 pkgList.add(pkg.packageName);
21622 // Post process args
21623 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
21624 pkg.applicationInfo.uid);
21627 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard");
21632 if (retCode != PackageManager.INSTALL_SUCCEEDED) {
21633 Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
21638 synchronized (mPackages) {
21639 // If the platform SDK has changed since the last time we booted,
21640 // we need to re-grant app permission to catch any new ones that
21641 // appear. This is really a hack, and means that apps can in some
21642 // cases get permissions that the user didn't initially explicitly
21643 // allow... it would be nice to have some better way to handle
21645 final VersionInfo ver = externalStorage ? mSettings.getExternalVersion()
21646 : mSettings.getInternalVersion();
21647 final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL
21648 : StorageManager.UUID_PRIVATE_INTERNAL;
21650 int updateFlags = UPDATE_PERMISSIONS_ALL;
21651 if (ver.sdkVersion != mSdkVersion) {
21652 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
21653 + mSdkVersion + "; regranting permissions for external");
21654 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
21656 updatePermissionsLPw(null, null, volumeUuid, updateFlags);
21658 // Yay, everything is now upgraded
21659 ver.forceCurrent();
21661 // can downgrade to reader
21662 // Persist settings
21663 mSettings.writeLPr();
21665 // Send a broadcast to let everyone know we are done processing
21666 if (pkgList.size() > 0) {
21667 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
21672 * Utility method to unload a list of specified containers
21674 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
21675 // Just unmount all valid containers.
21676 for (AsecInstallArgs arg : cidArgs) {
21677 synchronized (mInstallLock) {
21678 arg.doPostDeleteLI(false);
21684 * Unload packages mounted on external media. This involves deleting package
21685 * data from internal structures, sending broadcasts about disabled packages,
21686 * gc'ing to free up references, unmounting all secure containers
21687 * corresponding to packages on external media, and posting a
21688 * UPDATED_MEDIA_STATUS message if status has been requested. Please note
21689 * that we always have to post this message if status has been requested no
21692 private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
21693 final boolean reportStatus) {
21694 if (DEBUG_SD_INSTALL)
21695 Log.i(TAG, "unloading media packages");
21696 ArrayList<String> pkgList = new ArrayList<String>();
21697 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
21698 final Set<AsecInstallArgs> keys = processCids.keySet();
21699 for (AsecInstallArgs args : keys) {
21700 String pkgName = args.getPackageName();
21701 if (DEBUG_SD_INSTALL)
21702 Log.i(TAG, "Trying to unload pkg : " + pkgName);
21703 // Delete package internally
21704 PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
21705 synchronized (mInstallLock) {
21706 final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
21708 try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags,
21709 "unloadMediaPackages")) {
21710 res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false,
21714 pkgList.add(pkgName);
21716 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
21717 failedList.add(args);
21723 synchronized (mPackages) {
21724 // We didn't update the settings after removing each package;
21725 // write them now for all packages.
21726 mSettings.writeLPr();
21729 // We have to absolutely send UPDATED_MEDIA_STATUS only
21730 // after confirming that all the receivers processed the ordered
21731 // broadcast when packages get disabled, force a gc to clean things up.
21732 // and unload all the containers.
21733 if (pkgList.size() > 0) {
21734 sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
21735 new IIntentReceiver.Stub() {
21736 public void performReceive(Intent intent, int resultCode, String data,
21737 Bundle extras, boolean ordered, boolean sticky,
21738 int sendingUser) throws RemoteException {
21739 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
21740 reportStatus ? 1 : 0, 1, keys);
21741 mHandler.sendMessage(msg);
21745 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
21747 mHandler.sendMessage(msg);
21751 private void loadPrivatePackages(final VolumeInfo vol) {
21752 mHandler.post(new Runnable() {
21754 public void run() {
21755 loadPrivatePackagesInner(vol);
21760 private void loadPrivatePackagesInner(VolumeInfo vol) {
21761 final String volumeUuid = vol.fsUuid;
21762 if (TextUtils.isEmpty(volumeUuid)) {
21763 Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
21767 final ArrayList<PackageFreezer> freezers = new ArrayList<>();
21768 final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
21769 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
21771 final VersionInfo ver;
21772 final List<PackageSetting> packages;
21773 synchronized (mPackages) {
21774 ver = mSettings.findOrCreateVersion(volumeUuid);
21775 packages = mSettings.getVolumePackagesLPr(volumeUuid);
21778 for (PackageSetting ps : packages) {
21779 freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
21780 synchronized (mInstallLock) {
21781 final PackageParser.Package pkg;
21783 pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
21784 loaded.add(pkg.applicationInfo);
21786 } catch (PackageManagerException e) {
21787 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
21790 if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
21791 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
21792 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
21793 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
21798 // Reconcile app data for all started/unlocked users
21799 final StorageManager sm = mContext.getSystemService(StorageManager.class);
21800 final UserManager um = mContext.getSystemService(UserManager.class);
21801 UserManagerInternal umInternal = getUserManagerInternal();
21802 for (UserInfo user : um.getUsers()) {
21804 if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
21805 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
21806 } else if (umInternal.isUserRunning(user.id)) {
21807 flags = StorageManager.FLAG_STORAGE_DE;
21813 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
21814 synchronized (mInstallLock) {
21815 reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
21817 } catch (IllegalStateException e) {
21818 // Device was probably ejected, and we'll process that event momentarily
21819 Slog.w(TAG, "Failed to prepare storage: " + e);
21823 synchronized (mPackages) {
21824 int updateFlags = UPDATE_PERMISSIONS_ALL;
21825 if (ver.sdkVersion != mSdkVersion) {
21826 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
21827 + mSdkVersion + "; regranting permissions for " + volumeUuid);
21828 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
21830 updatePermissionsLPw(null, null, volumeUuid, updateFlags);
21832 // Yay, everything is now upgraded
21833 ver.forceCurrent();
21835 mSettings.writeLPr();
21838 for (PackageFreezer freezer : freezers) {
21842 if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
21843 sendResourcesChangedBroadcast(true, false, loaded, null);
21846 private void unloadPrivatePackages(final VolumeInfo vol) {
21847 mHandler.post(new Runnable() {
21849 public void run() {
21850 unloadPrivatePackagesInner(vol);
21855 private void unloadPrivatePackagesInner(VolumeInfo vol) {
21856 final String volumeUuid = vol.fsUuid;
21857 if (TextUtils.isEmpty(volumeUuid)) {
21858 Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
21862 final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
21863 synchronized (mInstallLock) {
21864 synchronized (mPackages) {
21865 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
21866 for (PackageSetting ps : packages) {
21867 if (ps.pkg == null) continue;
21869 final ApplicationInfo info = ps.pkg.applicationInfo;
21870 final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
21871 final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
21873 try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
21874 "unloadPrivatePackagesInner")) {
21875 if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
21877 unloaded.add(info);
21879 Slog.w(TAG, "Failed to unload " + ps.codePath);
21883 // Try very hard to release any references to this package
21884 // so we don't risk the system server being killed due to
21886 AttributeCache.instance().removePackage(ps.name);
21889 mSettings.writeLPr();
21893 if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
21894 sendResourcesChangedBroadcast(false, false, unloaded, null);
21896 // Try very hard to release any references to this path so we don't risk
21897 // the system server being killed due to open FDs
21898 ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
21900 for (int i = 0; i < 3; i++) {
21902 System.runFinalization();
21906 private void assertPackageKnown(String volumeUuid, String packageName)
21907 throws PackageManagerException {
21908 synchronized (mPackages) {
21909 // Normalize package name to handle renamed packages
21910 packageName = normalizePackageNameLPr(packageName);
21912 final PackageSetting ps = mSettings.mPackages.get(packageName);
21914 throw new PackageManagerException("Package " + packageName + " is unknown");
21915 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
21916 throw new PackageManagerException(
21917 "Package " + packageName + " found on unknown volume " + volumeUuid
21918 + "; expected volume " + ps.volumeUuid);
21923 private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
21924 throws PackageManagerException {
21925 synchronized (mPackages) {
21926 // Normalize package name to handle renamed packages
21927 packageName = normalizePackageNameLPr(packageName);
21929 final PackageSetting ps = mSettings.mPackages.get(packageName);
21931 throw new PackageManagerException("Package " + packageName + " is unknown");
21932 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
21933 throw new PackageManagerException(
21934 "Package " + packageName + " found on unknown volume " + volumeUuid
21935 + "; expected volume " + ps.volumeUuid);
21936 } else if (!ps.getInstalled(userId)) {
21937 throw new PackageManagerException(
21938 "Package " + packageName + " not installed for user " + userId);
21943 private List<String> collectAbsoluteCodePaths() {
21944 synchronized (mPackages) {
21945 List<String> codePaths = new ArrayList<>();
21946 final int packageCount = mSettings.mPackages.size();
21947 for (int i = 0; i < packageCount; i++) {
21948 final PackageSetting ps = mSettings.mPackages.valueAt(i);
21949 codePaths.add(ps.codePath.getAbsolutePath());
21956 * Examine all apps present on given mounted volume, and destroy apps that
21957 * aren't expected, either due to uninstallation or reinstallation on
21960 private void reconcileApps(String volumeUuid) {
21961 List<String> absoluteCodePaths = collectAbsoluteCodePaths();
21962 List<File> filesToDelete = null;
21964 final File[] files = FileUtils.listFilesOrEmpty(
21965 Environment.getDataAppDirectory(volumeUuid));
21966 for (File file : files) {
21967 final boolean isPackage = (isApkFile(file) || file.isDirectory())
21968 && !PackageInstallerService.isStageName(file.getName());
21970 // Ignore entries which are not packages
21974 String absolutePath = file.getAbsolutePath();
21976 boolean pathValid = false;
21977 final int absoluteCodePathCount = absoluteCodePaths.size();
21978 for (int i = 0; i < absoluteCodePathCount; i++) {
21979 String absoluteCodePath = absoluteCodePaths.get(i);
21980 if (absolutePath.startsWith(absoluteCodePath)) {
21987 if (filesToDelete == null) {
21988 filesToDelete = new ArrayList<>();
21990 filesToDelete.add(file);
21994 if (filesToDelete != null) {
21995 final int fileToDeleteCount = filesToDelete.size();
21996 for (int i = 0; i < fileToDeleteCount; i++) {
21997 File fileToDelete = filesToDelete.get(i);
21998 logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
21999 synchronized (mInstallLock) {
22000 removeCodePathLI(fileToDelete);
22007 * Reconcile all app data for the given user.
22009 * Verifies that directories exist and that ownership and labeling is
22010 * correct for all installed apps on all mounted volumes.
22012 void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
22013 final StorageManager storage = mContext.getSystemService(StorageManager.class);
22014 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
22015 final String volumeUuid = vol.getFsUuid();
22016 synchronized (mInstallLock) {
22017 reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
22022 private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
22023 boolean migrateAppData) {
22024 reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
22028 * Reconcile all app data on given mounted volume.
22030 * Destroys app data that isn't expected, either due to uninstallation or
22031 * reinstallation on another volume.
22033 * Verifies that directories exist and that ownership and labeling is
22034 * correct for all installed apps.
22035 * @returns list of skipped non-core packages (if {@code onlyCoreApps} is true)
22037 private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
22038 boolean migrateAppData, boolean onlyCoreApps) {
22039 Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
22040 + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
22041 List<String> result = onlyCoreApps ? new ArrayList<>() : null;
22043 final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
22044 final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
22046 // First look for stale data that doesn't belong, and check if things
22047 // have changed since we did our last restorecon
22048 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
22049 if (StorageManager.isFileEncryptedNativeOrEmulated()
22050 && !StorageManager.isUserKeyUnlocked(userId)) {
22051 throw new RuntimeException(
22052 "Yikes, someone asked us to reconcile CE storage while " + userId
22053 + " was still locked; this would have caused massive data loss!");
22056 final File[] files = FileUtils.listFilesOrEmpty(ceDir);
22057 for (File file : files) {
22058 final String packageName = file.getName();
22060 assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
22061 } catch (PackageManagerException e) {
22062 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
22064 mInstaller.destroyAppData(volumeUuid, packageName, userId,
22065 StorageManager.FLAG_STORAGE_CE, 0);
22066 } catch (InstallerException e2) {
22067 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
22072 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
22073 final File[] files = FileUtils.listFilesOrEmpty(deDir);
22074 for (File file : files) {
22075 final String packageName = file.getName();
22077 assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
22078 } catch (PackageManagerException e) {
22079 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
22081 mInstaller.destroyAppData(volumeUuid, packageName, userId,
22082 StorageManager.FLAG_STORAGE_DE, 0);
22083 } catch (InstallerException e2) {
22084 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
22090 // Ensure that data directories are ready to roll for all packages
22091 // installed for this volume and user
22092 final List<PackageSetting> packages;
22093 synchronized (mPackages) {
22094 packages = mSettings.getVolumePackagesLPr(volumeUuid);
22096 int preparedCount = 0;
22097 for (PackageSetting ps : packages) {
22098 final String packageName = ps.name;
22099 if (ps.pkg == null) {
22100 Slog.w(TAG, "Odd, missing scanned package " + packageName);
22101 // TODO: might be due to legacy ASEC apps; we should circle back
22102 // and reconcile again once they're scanned
22105 // Skip non-core apps if requested
22106 if (onlyCoreApps && !ps.pkg.coreApp) {
22107 result.add(packageName);
22111 if (ps.getInstalled(userId)) {
22112 prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
22117 Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
22122 * Prepare app data for the given app just after it was installed or
22123 * upgraded. This method carefully only touches users that it's installed
22124 * for, and it forces a restorecon to handle any seinfo changes.
22126 * Verifies that directories exist and that ownership and labeling is
22127 * correct for all installed apps. If there is an ownership mismatch, it
22128 * will try recovering system apps by wiping data; third-party app data is
22131 * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
22133 private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
22134 final PackageSetting ps;
22135 synchronized (mPackages) {
22136 ps = mSettings.mPackages.get(pkg.packageName);
22137 mSettings.writeKernelMappingLPr(ps);
22140 final UserManager um = mContext.getSystemService(UserManager.class);
22141 UserManagerInternal umInternal = getUserManagerInternal();
22142 for (UserInfo user : um.getUsers()) {
22144 if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
22145 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
22146 } else if (umInternal.isUserRunning(user.id)) {
22147 flags = StorageManager.FLAG_STORAGE_DE;
22152 if (ps.getInstalled(user.id)) {
22153 // TODO: when user data is locked, mark that we're still dirty
22154 prepareAppDataLIF(pkg, user.id, flags);
22160 * Prepare app data for the given app.
22162 * Verifies that directories exist and that ownership and labeling is
22163 * correct for all installed apps. If there is an ownership mismatch, this
22164 * will try recovering system apps by wiping data; third-party app data is
22167 private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
22169 Slog.wtf(TAG, "Package was null!", new Throwable());
22172 prepareAppDataLeafLIF(pkg, userId, flags);
22173 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
22174 for (int i = 0; i < childCount; i++) {
22175 prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
22179 private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags,
22180 boolean maybeMigrateAppData) {
22181 prepareAppDataLIF(pkg, userId, flags);
22183 if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
22184 // We may have just shuffled around app data directories, so
22185 // prepare them one more time
22186 prepareAppDataLIF(pkg, userId, flags);
22190 private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
22191 if (DEBUG_APP_DATA) {
22192 Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
22193 + Integer.toHexString(flags));
22196 final String volumeUuid = pkg.volumeUuid;
22197 final String packageName = pkg.packageName;
22198 final ApplicationInfo app = pkg.applicationInfo;
22199 final int appId = UserHandle.getAppId(app.uid);
22201 Preconditions.checkNotNull(app.seInfo);
22203 long ceDataInode = -1;
22205 ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
22206 appId, app.seInfo, app.targetSdkVersion);
22207 } catch (InstallerException e) {
22208 if (app.isSystemApp()) {
22209 logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
22210 + ", but trying to recover: " + e);
22211 destroyAppDataLeafLIF(pkg, userId, flags);
22213 ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
22214 appId, app.seInfo, app.targetSdkVersion);
22215 logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
22216 } catch (InstallerException e2) {
22217 logCriticalInfo(Log.DEBUG, "Recovery failed!");
22220 Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
22224 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
22225 // TODO: mark this structure as dirty so we persist it!
22226 synchronized (mPackages) {
22227 final PackageSetting ps = mSettings.mPackages.get(packageName);
22229 ps.setCeDataInode(ceDataInode, userId);
22234 prepareAppDataContentsLeafLIF(pkg, userId, flags);
22237 private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
22239 Slog.wtf(TAG, "Package was null!", new Throwable());
22242 prepareAppDataContentsLeafLIF(pkg, userId, flags);
22243 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
22244 for (int i = 0; i < childCount; i++) {
22245 prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
22249 private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
22250 final String volumeUuid = pkg.volumeUuid;
22251 final String packageName = pkg.packageName;
22252 final ApplicationInfo app = pkg.applicationInfo;
22254 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
22255 // Create a native library symlink only if we have native libraries
22256 // and if the native libraries are 32 bit libraries. We do not provide
22257 // this symlink for 64 bit libraries.
22258 if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
22259 final String nativeLibPath = app.nativeLibraryDir;
22261 mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
22262 nativeLibPath, userId);
22263 } catch (InstallerException e) {
22264 Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
22271 * For system apps on non-FBE devices, this method migrates any existing
22272 * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
22273 * requested by the app.
22275 private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
22276 if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated()
22277 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
22278 final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
22279 ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
22281 mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
22283 } catch (InstallerException e) {
22284 logCriticalInfo(Log.WARN,
22285 "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
22293 public PackageFreezer freezePackage(String packageName, String killReason) {
22294 return freezePackage(packageName, UserHandle.USER_ALL, killReason);
22297 public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
22298 return new PackageFreezer(packageName, userId, killReason);
22301 public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
22302 String killReason) {
22303 return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
22306 public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
22307 String killReason) {
22308 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
22309 return new PackageFreezer();
22311 return freezePackage(packageName, userId, killReason);
22315 public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
22316 String killReason) {
22317 return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
22320 public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
22321 String killReason) {
22322 if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
22323 return new PackageFreezer();
22325 return freezePackage(packageName, userId, killReason);
22330 * Class that freezes and kills the given package upon creation, and
22331 * unfreezes it upon closing. This is typically used when doing surgery on
22332 * app code/data to prevent the app from running while you're working.
22334 private class PackageFreezer implements AutoCloseable {
22335 private final String mPackageName;
22336 private final PackageFreezer[] mChildren;
22338 private final boolean mWeFroze;
22340 private final AtomicBoolean mClosed = new AtomicBoolean();
22341 private final CloseGuard mCloseGuard = CloseGuard.get();
22344 * Create and return a stub freezer that doesn't actually do anything,
22345 * typically used when someone requested
22346 * {@link PackageManager#INSTALL_DONT_KILL_APP} or
22347 * {@link PackageManager#DELETE_DONT_KILL_APP}.
22349 public PackageFreezer() {
22350 mPackageName = null;
22353 mCloseGuard.open("close");
22356 public PackageFreezer(String packageName, int userId, String killReason) {
22357 synchronized (mPackages) {
22358 mPackageName = packageName;
22359 mWeFroze = mFrozenPackages.add(mPackageName);
22361 final PackageSetting ps = mSettings.mPackages.get(mPackageName);
22363 killApplication(ps.name, ps.appId, userId, killReason);
22366 final PackageParser.Package p = mPackages.get(packageName);
22367 if (p != null && p.childPackages != null) {
22368 final int N = p.childPackages.size();
22369 mChildren = new PackageFreezer[N];
22370 for (int i = 0; i < N; i++) {
22371 mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
22372 userId, killReason);
22378 mCloseGuard.open("close");
22382 protected void finalize() throws Throwable {
22384 mCloseGuard.warnIfOpen();
22392 public void close() {
22393 mCloseGuard.close();
22394 if (mClosed.compareAndSet(false, true)) {
22395 synchronized (mPackages) {
22397 mFrozenPackages.remove(mPackageName);
22400 if (mChildren != null) {
22401 for (PackageFreezer freezer : mChildren) {
22411 * Verify that given package is currently frozen.
22413 private void checkPackageFrozen(String packageName) {
22414 synchronized (mPackages) {
22415 if (!mFrozenPackages.contains(packageName)) {
22416 Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
22422 public int movePackage(final String packageName, final String volumeUuid) {
22423 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22425 final UserHandle user = new UserHandle(UserHandle.getCallingUserId());
22426 final int moveId = mNextMoveId.getAndIncrement();
22427 mHandler.post(new Runnable() {
22429 public void run() {
22431 movePackageInternal(packageName, volumeUuid, moveId, user);
22432 } catch (PackageManagerException e) {
22433 Slog.w(TAG, "Failed to move " + packageName, e);
22434 mMoveCallbacks.notifyStatusChanged(moveId,
22435 PackageManager.MOVE_FAILED_INTERNAL_ERROR);
22442 private void movePackageInternal(final String packageName, final String volumeUuid,
22443 final int moveId, UserHandle user) throws PackageManagerException {
22444 final StorageManager storage = mContext.getSystemService(StorageManager.class);
22445 final PackageManager pm = mContext.getPackageManager();
22447 final boolean currentAsec;
22448 final String currentVolumeUuid;
22449 final File codeFile;
22450 final String installerPackageName;
22451 final String packageAbiOverride;
22453 final String seinfo;
22454 final String label;
22455 final int targetSdkVersion;
22456 final PackageFreezer freezer;
22457 final int[] installedUserIds;
22460 synchronized (mPackages) {
22461 final PackageParser.Package pkg = mPackages.get(packageName);
22462 final PackageSetting ps = mSettings.mPackages.get(packageName);
22463 if (pkg == null || ps == null) {
22464 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
22467 if (pkg.applicationInfo.isSystemApp()) {
22468 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
22469 "Cannot move system application");
22472 final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
22473 final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
22474 com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
22475 if (isInternalStorage && !allow3rdPartyOnInternal) {
22476 throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
22477 "3rd party apps are not allowed on internal storage");
22480 if (pkg.applicationInfo.isExternalAsec()) {
22481 currentAsec = true;
22482 currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
22483 } else if (pkg.applicationInfo.isForwardLocked()) {
22484 currentAsec = true;
22485 currentVolumeUuid = "forward_locked";
22487 currentAsec = false;
22488 currentVolumeUuid = ps.volumeUuid;
22490 final File probe = new File(pkg.codePath);
22491 final File probeOat = new File(probe, "oat");
22492 if (!probe.isDirectory() || !probeOat.isDirectory()) {
22493 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22494 "Move only supported for modern cluster style installs");
22498 if (Objects.equals(currentVolumeUuid, volumeUuid)) {
22499 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22500 "Package already moved to " + volumeUuid);
22502 if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
22503 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
22504 "Device admin cannot be moved");
22507 if (mFrozenPackages.contains(packageName)) {
22508 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
22509 "Failed to move already frozen package");
22512 codeFile = new File(pkg.codePath);
22513 installerPackageName = ps.installerPackageName;
22514 packageAbiOverride = ps.cpuAbiOverrideString;
22515 appId = UserHandle.getAppId(pkg.applicationInfo.uid);
22516 seinfo = pkg.applicationInfo.seInfo;
22517 label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
22518 targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
22519 freezer = freezePackage(packageName, "movePackageInternal");
22520 installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
22523 final Bundle extras = new Bundle();
22524 extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
22525 extras.putString(Intent.EXTRA_TITLE, label);
22526 mMoveCallbacks.notifyCreated(moveId, extras);
22529 final boolean moveCompleteApp;
22530 final File measurePath;
22532 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
22533 installFlags = INSTALL_INTERNAL;
22534 moveCompleteApp = !currentAsec;
22535 measurePath = Environment.getDataAppDirectory(volumeUuid);
22536 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
22537 installFlags = INSTALL_EXTERNAL;
22538 moveCompleteApp = false;
22539 measurePath = storage.getPrimaryPhysicalVolume().getPath();
22541 final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
22542 if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
22543 || !volume.isMountedWritable()) {
22545 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22546 "Move location not mounted private volume");
22549 Preconditions.checkState(!currentAsec);
22551 installFlags = INSTALL_INTERNAL;
22552 moveCompleteApp = true;
22553 measurePath = Environment.getDataAppDirectory(volumeUuid);
22556 final PackageStats stats = new PackageStats(null, -1);
22557 synchronized (mInstaller) {
22558 for (int userId : installedUserIds) {
22559 if (!getPackageSizeInfoLI(packageName, userId, stats)) {
22561 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22562 "Failed to measure package size");
22567 if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
22570 final long startFreeBytes = measurePath.getUsableSpace();
22571 final long sizeBytes;
22572 if (moveCompleteApp) {
22573 sizeBytes = stats.codeSize + stats.dataSize;
22575 sizeBytes = stats.codeSize;
22578 if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
22580 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22581 "Not enough free space to move");
22584 mMoveCallbacks.notifyStatusChanged(moveId, 10);
22586 final CountDownLatch installedLatch = new CountDownLatch(1);
22587 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
22589 public void onUserActionRequired(Intent intent) throws RemoteException {
22590 throw new IllegalStateException();
22594 public void onPackageInstalled(String basePackageName, int returnCode, String msg,
22595 Bundle extras) throws RemoteException {
22596 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
22597 + PackageManager.installStatusToString(returnCode, msg));
22599 installedLatch.countDown();
22602 final int status = PackageManager.installStatusToPublicStatus(returnCode);
22604 case PackageInstaller.STATUS_SUCCESS:
22605 mMoveCallbacks.notifyStatusChanged(moveId,
22606 PackageManager.MOVE_SUCCEEDED);
22608 case PackageInstaller.STATUS_FAILURE_STORAGE:
22609 mMoveCallbacks.notifyStatusChanged(moveId,
22610 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
22613 mMoveCallbacks.notifyStatusChanged(moveId,
22614 PackageManager.MOVE_FAILED_INTERNAL_ERROR);
22620 final MoveInfo move;
22621 if (moveCompleteApp) {
22622 // Kick off a thread to report progress estimates
22625 public void run() {
22628 if (installedLatch.await(1, TimeUnit.SECONDS)) {
22631 } catch (InterruptedException ignored) {
22634 final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
22635 final int progress = 10 + (int) MathUtils.constrain(
22636 ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
22637 mMoveCallbacks.notifyStatusChanged(moveId, progress);
22642 final String dataAppName = codeFile.getName();
22643 move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
22644 dataAppName, appId, seinfo, targetSdkVersion);
22649 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
22651 final Message msg = mHandler.obtainMessage(INIT_COPY);
22652 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
22653 final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
22654 installerPackageName, volumeUuid, null /*verificationInfo*/, user,
22655 packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/,
22656 PackageManager.INSTALL_REASON_UNKNOWN);
22657 params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
22660 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
22661 System.identityHashCode(msg.obj));
22662 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
22663 System.identityHashCode(msg.obj));
22665 mHandler.sendMessage(msg);
22669 public int movePrimaryStorage(String volumeUuid) throws RemoteException {
22670 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22672 final int realMoveId = mNextMoveId.getAndIncrement();
22673 final Bundle extras = new Bundle();
22674 extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
22675 mMoveCallbacks.notifyCreated(realMoveId, extras);
22677 final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
22679 public void onCreated(int moveId, Bundle extras) {
22684 public void onStatusChanged(int moveId, int status, long estMillis) {
22685 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
22689 final StorageManager storage = mContext.getSystemService(StorageManager.class);
22690 storage.setPrimaryStorageUuid(volumeUuid, callback);
22695 public int getMoveStatus(int moveId) {
22696 mContext.enforceCallingOrSelfPermission(
22697 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22698 return mMoveCallbacks.mLastStatus.get(moveId);
22702 public void registerMoveCallback(IPackageMoveObserver callback) {
22703 mContext.enforceCallingOrSelfPermission(
22704 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22705 mMoveCallbacks.register(callback);
22709 public void unregisterMoveCallback(IPackageMoveObserver callback) {
22710 mContext.enforceCallingOrSelfPermission(
22711 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22712 mMoveCallbacks.unregister(callback);
22716 public boolean setInstallLocation(int loc) {
22717 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
22719 if (getInstallLocation() == loc) {
22722 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
22723 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
22724 android.provider.Settings.Global.putInt(mContext.getContentResolver(),
22725 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
22732 public int getInstallLocation() {
22733 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
22734 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
22735 PackageHelper.APP_INSTALL_AUTO);
22738 /** Called by UserManagerService */
22739 void cleanUpUser(UserManagerService userManager, int userHandle) {
22740 synchronized (mPackages) {
22741 mDirtyUsers.remove(userHandle);
22742 mUserNeedsBadging.delete(userHandle);
22743 mSettings.removeUserLPw(userHandle);
22744 mPendingBroadcasts.remove(userHandle);
22745 mInstantAppRegistry.onUserRemovedLPw(userHandle);
22746 removeUnusedPackagesLPw(userManager, userHandle);
22751 * We're removing userHandle and would like to remove any downloaded packages
22752 * that are no longer in use by any other user.
22753 * @param userHandle the user being removed
22755 private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
22756 final boolean DEBUG_CLEAN_APKS = false;
22757 int [] users = userManager.getUserIds();
22758 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
22759 while (psit.hasNext()) {
22760 PackageSetting ps = psit.next();
22761 if (ps.pkg == null) {
22764 final String packageName = ps.pkg.packageName;
22765 // Skip over if system app
22766 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
22769 if (DEBUG_CLEAN_APKS) {
22770 Slog.i(TAG, "Checking package " + packageName);
22772 boolean keep = shouldKeepUninstalledPackageLPr(packageName);
22774 if (DEBUG_CLEAN_APKS) {
22775 Slog.i(TAG, " Keeping package " + packageName + " - requested by DO");
22778 for (int i = 0; i < users.length; i++) {
22779 if (users[i] != userHandle && ps.getInstalled(users[i])) {
22781 if (DEBUG_CLEAN_APKS) {
22782 Slog.i(TAG, " Keeping package " + packageName + " for user "
22790 if (DEBUG_CLEAN_APKS) {
22791 Slog.i(TAG, " Removing package " + packageName);
22793 mHandler.post(new Runnable() {
22794 public void run() {
22795 deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
22803 /** Called by UserManagerService */
22804 void createNewUser(int userId, String[] disallowedPackages) {
22805 synchronized (mInstallLock) {
22806 mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages);
22808 synchronized (mPackages) {
22809 scheduleWritePackageRestrictionsLocked(userId);
22810 scheduleWritePackageListLocked(userId);
22811 applyFactoryDefaultBrowserLPw(userId);
22812 primeDomainVerificationsLPw(userId);
22816 void onNewUserCreated(final int userId) {
22817 mDefaultPermissionPolicy.grantDefaultPermissions(userId);
22818 // If permission review for legacy apps is required, we represent
22819 // dagerous permissions for such apps as always granted runtime
22820 // permissions to keep per user flag state whether review is needed.
22821 // Hence, if a new user is added we have to propagate dangerous
22822 // permission grants for these legacy apps.
22823 if (mPermissionReviewRequired) {
22824 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
22825 | UPDATE_PERMISSIONS_REPLACE_ALL);
22830 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
22831 mContext.enforceCallingOrSelfPermission(
22832 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
22833 "Only package verification agents can read the verifier device identity");
22835 synchronized (mPackages) {
22836 return mSettings.getVerifierDeviceIdentityLPw();
22841 public void setPermissionEnforced(String permission, boolean enforced) {
22842 // TODO: Now that we no longer change GID for storage, this should to away.
22843 mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
22844 "setPermissionEnforced");
22845 if (READ_EXTERNAL_STORAGE.equals(permission)) {
22846 synchronized (mPackages) {
22847 if (mSettings.mReadExternalStorageEnforced == null
22848 || mSettings.mReadExternalStorageEnforced != enforced) {
22849 mSettings.mReadExternalStorageEnforced = enforced;
22850 mSettings.writeLPr();
22853 // kill any non-foreground processes so we restart them and
22854 // grant/revoke the GID.
22855 final IActivityManager am = ActivityManager.getService();
22857 final long token = Binder.clearCallingIdentity();
22859 am.killProcessesBelowForeground("setPermissionEnforcement");
22860 } catch (RemoteException e) {
22862 Binder.restoreCallingIdentity(token);
22866 throw new IllegalArgumentException("No selective enforcement for " + permission);
22872 public boolean isPermissionEnforced(String permission) {
22877 public boolean isStorageLow() {
22878 final long token = Binder.clearCallingIdentity();
22880 final DeviceStorageMonitorInternal
22881 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
22883 return dsm.isMemoryLow();
22888 Binder.restoreCallingIdentity(token);
22893 public IPackageInstaller getPackageInstaller() {
22894 return mInstallerService;
22897 private boolean userNeedsBadging(int userId) {
22898 int index = mUserNeedsBadging.indexOfKey(userId);
22900 final UserInfo userInfo;
22901 final long token = Binder.clearCallingIdentity();
22903 userInfo = sUserManager.getUserInfo(userId);
22905 Binder.restoreCallingIdentity(token);
22908 if (userInfo != null && userInfo.isManagedProfile()) {
22913 mUserNeedsBadging.put(userId, b);
22916 return mUserNeedsBadging.valueAt(index);
22920 public KeySet getKeySetByAlias(String packageName, String alias) {
22921 if (packageName == null || alias == null) {
22924 synchronized(mPackages) {
22925 final PackageParser.Package pkg = mPackages.get(packageName);
22927 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22928 throw new IllegalArgumentException("Unknown package: " + packageName);
22930 KeySetManagerService ksms = mSettings.mKeySetManagerService;
22931 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
22936 public KeySet getSigningKeySet(String packageName) {
22937 if (packageName == null) {
22940 synchronized(mPackages) {
22941 final PackageParser.Package pkg = mPackages.get(packageName);
22943 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22944 throw new IllegalArgumentException("Unknown package: " + packageName);
22946 if (pkg.applicationInfo.uid != Binder.getCallingUid()
22947 && Process.SYSTEM_UID != Binder.getCallingUid()) {
22948 throw new SecurityException("May not access signing KeySet of other apps.");
22950 KeySetManagerService ksms = mSettings.mKeySetManagerService;
22951 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
22956 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
22957 if (packageName == null || ks == null) {
22960 synchronized(mPackages) {
22961 final PackageParser.Package pkg = mPackages.get(packageName);
22963 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22964 throw new IllegalArgumentException("Unknown package: " + packageName);
22966 IBinder ksh = ks.getToken();
22967 if (ksh instanceof KeySetHandle) {
22968 KeySetManagerService ksms = mSettings.mKeySetManagerService;
22969 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
22976 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
22977 if (packageName == null || ks == null) {
22980 synchronized(mPackages) {
22981 final PackageParser.Package pkg = mPackages.get(packageName);
22983 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22984 throw new IllegalArgumentException("Unknown package: " + packageName);
22986 IBinder ksh = ks.getToken();
22987 if (ksh instanceof KeySetHandle) {
22988 KeySetManagerService ksms = mSettings.mKeySetManagerService;
22989 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
22995 private void deletePackageIfUnusedLPr(final String packageName) {
22996 PackageSetting ps = mSettings.mPackages.get(packageName);
23000 if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
23001 // TODO Implement atomic delete if package is unused
23002 // It is currently possible that the package will be deleted even if it is installed
23003 // after this method returns.
23004 mHandler.post(new Runnable() {
23005 public void run() {
23006 deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
23007 0, PackageManager.DELETE_ALL_USERS);
23014 * Check and throw if the given before/after packages would be considered a
23017 private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
23018 throws PackageManagerException {
23019 if (after.versionCode < before.mVersionCode) {
23020 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23021 "Update version code " + after.versionCode + " is older than current "
23022 + before.mVersionCode);
23023 } else if (after.versionCode == before.mVersionCode) {
23024 if (after.baseRevisionCode < before.baseRevisionCode) {
23025 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23026 "Update base revision code " + after.baseRevisionCode
23027 + " is older than current " + before.baseRevisionCode);
23030 if (!ArrayUtils.isEmpty(after.splitNames)) {
23031 for (int i = 0; i < after.splitNames.length; i++) {
23032 final String splitName = after.splitNames[i];
23033 final int j = ArrayUtils.indexOf(before.splitNames, splitName);
23035 if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
23036 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23037 "Update split " + splitName + " revision code "
23038 + after.splitRevisionCodes[i] + " is older than current "
23039 + before.splitRevisionCodes[j]);
23047 private static class MoveCallbacks extends Handler {
23048 private static final int MSG_CREATED = 1;
23049 private static final int MSG_STATUS_CHANGED = 2;
23051 private final RemoteCallbackList<IPackageMoveObserver>
23052 mCallbacks = new RemoteCallbackList<>();
23054 private final SparseIntArray mLastStatus = new SparseIntArray();
23056 public MoveCallbacks(Looper looper) {
23060 public void register(IPackageMoveObserver callback) {
23061 mCallbacks.register(callback);
23064 public void unregister(IPackageMoveObserver callback) {
23065 mCallbacks.unregister(callback);
23069 public void handleMessage(Message msg) {
23070 final SomeArgs args = (SomeArgs) msg.obj;
23071 final int n = mCallbacks.beginBroadcast();
23072 for (int i = 0; i < n; i++) {
23073 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
23075 invokeCallback(callback, msg.what, args);
23076 } catch (RemoteException ignored) {
23079 mCallbacks.finishBroadcast();
23083 private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
23084 throws RemoteException {
23086 case MSG_CREATED: {
23087 callback.onCreated(args.argi1, (Bundle) args.arg2);
23090 case MSG_STATUS_CHANGED: {
23091 callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
23097 private void notifyCreated(int moveId, Bundle extras) {
23098 Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
23100 final SomeArgs args = SomeArgs.obtain();
23101 args.argi1 = moveId;
23102 args.arg2 = extras;
23103 obtainMessage(MSG_CREATED, args).sendToTarget();
23106 private void notifyStatusChanged(int moveId, int status) {
23107 notifyStatusChanged(moveId, status, -1);
23110 private void notifyStatusChanged(int moveId, int status, long estMillis) {
23111 Slog.v(TAG, "Move " + moveId + " status " + status);
23113 final SomeArgs args = SomeArgs.obtain();
23114 args.argi1 = moveId;
23115 args.argi2 = status;
23116 args.arg3 = estMillis;
23117 obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
23119 synchronized (mLastStatus) {
23120 mLastStatus.put(moveId, status);
23125 private final static class OnPermissionChangeListeners extends Handler {
23126 private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
23128 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
23129 new RemoteCallbackList<>();
23131 public OnPermissionChangeListeners(Looper looper) {
23136 public void handleMessage(Message msg) {
23137 switch (msg.what) {
23138 case MSG_ON_PERMISSIONS_CHANGED: {
23139 final int uid = msg.arg1;
23140 handleOnPermissionsChanged(uid);
23145 public void addListenerLocked(IOnPermissionsChangeListener listener) {
23146 mPermissionListeners.register(listener);
23150 public void removeListenerLocked(IOnPermissionsChangeListener listener) {
23151 mPermissionListeners.unregister(listener);
23154 public void onPermissionsChanged(int uid) {
23155 if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
23156 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
23160 private void handleOnPermissionsChanged(int uid) {
23161 final int count = mPermissionListeners.beginBroadcast();
23163 for (int i = 0; i < count; i++) {
23164 IOnPermissionsChangeListener callback = mPermissionListeners
23165 .getBroadcastItem(i);
23167 callback.onPermissionsChanged(uid);
23168 } catch (RemoteException e) {
23169 Log.e(TAG, "Permission listener is dead", e);
23173 mPermissionListeners.finishBroadcast();
23178 private class PackageManagerInternalImpl extends PackageManagerInternal {
23180 public void setLocationPackagesProvider(PackagesProvider provider) {
23181 synchronized (mPackages) {
23182 mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
23187 public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
23188 synchronized (mPackages) {
23189 mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
23194 public void setSmsAppPackagesProvider(PackagesProvider provider) {
23195 synchronized (mPackages) {
23196 mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
23201 public void setDialerAppPackagesProvider(PackagesProvider provider) {
23202 synchronized (mPackages) {
23203 mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
23208 public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
23209 synchronized (mPackages) {
23210 mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider);
23215 public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
23216 synchronized (mPackages) {
23217 mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider);
23222 public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
23223 synchronized (mPackages) {
23224 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
23225 packageName, userId);
23230 public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
23231 synchronized (mPackages) {
23232 mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
23233 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
23234 packageName, userId);
23239 public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
23240 synchronized (mPackages) {
23241 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr(
23242 packageName, userId);
23247 public void setKeepUninstalledPackages(final List<String> packageList) {
23248 Preconditions.checkNotNull(packageList);
23249 List<String> removedFromList = null;
23250 synchronized (mPackages) {
23251 if (mKeepUninstalledPackages != null) {
23252 final int packagesCount = mKeepUninstalledPackages.size();
23253 for (int i = 0; i < packagesCount; i++) {
23254 String oldPackage = mKeepUninstalledPackages.get(i);
23255 if (packageList != null && packageList.contains(oldPackage)) {
23258 if (removedFromList == null) {
23259 removedFromList = new ArrayList<>();
23261 removedFromList.add(oldPackage);
23264 mKeepUninstalledPackages = new ArrayList<>(packageList);
23265 if (removedFromList != null) {
23266 final int removedCount = removedFromList.size();
23267 for (int i = 0; i < removedCount; i++) {
23268 deletePackageIfUnusedLPr(removedFromList.get(i));
23275 public boolean isPermissionsReviewRequired(String packageName, int userId) {
23276 synchronized (mPackages) {
23277 // If we do not support permission review, done.
23278 if (!mPermissionReviewRequired) {
23282 PackageSetting packageSetting = mSettings.mPackages.get(packageName);
23283 if (packageSetting == null) {
23287 // Permission review applies only to apps not supporting the new permission model.
23288 if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
23292 // Legacy apps have the permission and get user consent on launch.
23293 PermissionsState permissionsState = packageSetting.getPermissionsState();
23294 return permissionsState.isPermissionReviewRequired(userId);
23299 public ApplicationInfo getApplicationInfo(String packageName, int userId) {
23300 return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId);
23304 public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
23306 return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
23310 public void setDeviceAndProfileOwnerPackages(
23311 int deviceOwnerUserId, String deviceOwnerPackage,
23312 SparseArray<String> profileOwnerPackages) {
23313 mProtectedPackages.setDeviceAndProfileOwnerPackages(
23314 deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
23318 public boolean isPackageDataProtected(int userId, String packageName) {
23319 return mProtectedPackages.isPackageDataProtected(userId, packageName);
23323 public boolean isPackageEphemeral(int userId, String packageName) {
23324 synchronized (mPackages) {
23325 final PackageSetting ps = mSettings.mPackages.get(packageName);
23326 return ps != null ? ps.getInstantApp(userId) : false;
23331 public boolean wasPackageEverLaunched(String packageName, int userId) {
23332 synchronized (mPackages) {
23333 return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
23338 public void grantRuntimePermission(String packageName, String name, int userId,
23339 boolean overridePolicy) {
23340 PackageManagerService.this.grantRuntimePermission(packageName, name, userId,
23345 public void revokeRuntimePermission(String packageName, String name, int userId,
23346 boolean overridePolicy) {
23347 PackageManagerService.this.revokeRuntimePermission(packageName, name, userId,
23352 public String getNameForUid(int uid) {
23353 return PackageManagerService.this.getNameForUid(uid);
23357 public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
23358 Intent origIntent, String resolvedType, String callingPackage, int userId) {
23359 PackageManagerService.this.requestInstantAppResolutionPhaseTwo(
23360 responseObj, origIntent, resolvedType, callingPackage, userId);
23364 public void grantEphemeralAccess(int userId, Intent intent,
23365 int targetAppId, int ephemeralAppId) {
23366 synchronized (mPackages) {
23367 mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
23368 targetAppId, ephemeralAppId);
23373 public boolean isInstantAppInstallerComponent(ComponentName component) {
23374 synchronized (mPackages) {
23375 return mInstantAppInstallerActivity != null
23376 && mInstantAppInstallerActivity.getComponentName().equals(component);
23381 public void pruneInstantApps() {
23382 synchronized (mPackages) {
23383 mInstantAppRegistry.pruneInstantAppsLPw();
23388 public String getSetupWizardPackageName() {
23389 return mSetupWizardPackage;
23392 public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
23393 if (policy != null) {
23394 mExternalSourcesPolicy = policy;
23399 public boolean isPackagePersistent(String packageName) {
23400 synchronized (mPackages) {
23401 PackageParser.Package pkg = mPackages.get(packageName);
23403 ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM
23404 | ApplicationInfo.FLAG_PERSISTENT)) ==
23405 (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT))
23411 public List<PackageInfo> getOverlayPackages(int userId) {
23412 final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
23413 synchronized (mPackages) {
23414 for (PackageParser.Package p : mPackages.values()) {
23415 if (p.mOverlayTarget != null) {
23416 PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
23418 overlayPackages.add(pkg);
23423 return overlayPackages;
23427 public List<String> getTargetPackageNames(int userId) {
23428 List<String> targetPackages = new ArrayList<>();
23429 synchronized (mPackages) {
23430 for (PackageParser.Package p : mPackages.values()) {
23431 if (p.mOverlayTarget == null) {
23432 targetPackages.add(p.packageName);
23436 return targetPackages;
23440 public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
23441 @Nullable List<String> overlayPackageNames) {
23442 synchronized (mPackages) {
23443 if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
23444 Slog.e(TAG, "failed to find package " + targetPackageName);
23448 ArrayList<String> paths = null;
23449 if (overlayPackageNames != null) {
23450 final int N = overlayPackageNames.size();
23451 paths = new ArrayList<>(N);
23452 for (int i = 0; i < N; i++) {
23453 final String packageName = overlayPackageNames.get(i);
23454 final PackageParser.Package pkg = mPackages.get(packageName);
23456 Slog.e(TAG, "failed to find package " + packageName);
23459 paths.add(pkg.baseCodePath);
23463 ArrayMap<String, ArrayList<String>> userSpecificOverlays =
23464 mEnabledOverlayPaths.get(userId);
23465 if (userSpecificOverlays == null) {
23466 userSpecificOverlays = new ArrayMap<>();
23467 mEnabledOverlayPaths.put(userId, userSpecificOverlays);
23470 if (paths != null && paths.size() > 0) {
23471 userSpecificOverlays.put(targetPackageName, paths);
23473 userSpecificOverlays.remove(targetPackageName);
23480 public ResolveInfo resolveIntent(Intent intent, String resolvedType,
23481 int flags, int userId) {
23482 return resolveIntentInternal(
23483 intent, resolvedType, flags, userId, true /*includeInstantApps*/);
23487 public ResolveInfo resolveService(Intent intent, String resolvedType,
23488 int flags, int userId, int callingUid) {
23489 return resolveServiceInternal(
23490 intent, resolvedType, flags, userId, callingUid, true /*includeInstantApps*/);
23494 public void addIsolatedUid(int isolatedUid, int ownerUid) {
23495 synchronized (mPackages) {
23496 mIsolatedOwners.put(isolatedUid, ownerUid);
23501 public void removeIsolatedUid(int isolatedUid) {
23502 synchronized (mPackages) {
23503 mIsolatedOwners.delete(isolatedUid);
23509 public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
23510 enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
23511 synchronized (mPackages) {
23512 final long identity = Binder.clearCallingIdentity();
23514 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
23515 packageNames, userId);
23517 Binder.restoreCallingIdentity(identity);
23523 public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
23524 enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
23525 synchronized (mPackages) {
23526 final long identity = Binder.clearCallingIdentity();
23528 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServicesLPr(
23529 packageNames, userId);
23531 Binder.restoreCallingIdentity(identity);
23536 private static void enforceSystemOrPhoneCaller(String tag) {
23537 int callingUid = Binder.getCallingUid();
23538 if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
23539 throw new SecurityException(
23540 "Cannot call " + tag + " from UID " + callingUid);
23544 boolean isHistoricalPackageUsageAvailable() {
23545 return mPackageUsage.isHistoricalPackageUsageAvailable();
23549 * Return a <b>copy</b> of the collection of packages known to the package manager.
23550 * @return A copy of the values of mPackages.
23552 Collection<PackageParser.Package> getPackages() {
23553 synchronized (mPackages) {
23554 return new ArrayList<>(mPackages.values());
23559 * Logs process start information (including base APK hash) to the security log.
23562 public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
23563 String apkFile, int pid) {
23564 if (!SecurityLog.isLoggingEnabled()) {
23567 Bundle data = new Bundle();
23568 data.putLong("startTimestamp", System.currentTimeMillis());
23569 data.putString("processName", processName);
23570 data.putInt("uid", uid);
23571 data.putString("seinfo", seinfo);
23572 data.putString("apkFile", apkFile);
23573 data.putInt("pid", pid);
23574 Message msg = mProcessLoggingHandler.obtainMessage(
23575 ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
23577 mProcessLoggingHandler.sendMessage(msg);
23580 public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
23581 return mCompilerStats.getPackageStats(pkgName);
23584 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
23585 return getOrCreateCompilerPackageStats(pkg.packageName);
23588 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
23589 return mCompilerStats.getOrCreatePackageStats(pkgName);
23592 public void deleteCompilerPackageStats(String pkgName) {
23593 mCompilerStats.deletePackageStats(pkgName);
23597 public int getInstallReason(String packageName, int userId) {
23598 enforceCrossUserPermission(Binder.getCallingUid(), userId,
23599 true /* requireFullPermission */, false /* checkShell */,
23600 "get install reason");
23601 synchronized (mPackages) {
23602 final PackageSetting ps = mSettings.mPackages.get(packageName);
23604 return ps.getInstallReason(userId);
23607 return PackageManager.INSTALL_REASON_UNKNOWN;
23611 public boolean canRequestPackageInstalls(String packageName, int userId) {
23612 int callingUid = Binder.getCallingUid();
23613 int uid = getPackageUid(packageName, 0, userId);
23614 if (callingUid != uid && callingUid != Process.ROOT_UID
23615 && callingUid != Process.SYSTEM_UID) {
23616 throw new SecurityException(
23617 "Caller uid " + callingUid + " does not own package " + packageName);
23619 ApplicationInfo info = getApplicationInfo(packageName, 0, userId);
23620 if (info == null) {
23623 if (info.targetSdkVersion < Build.VERSION_CODES.O) {
23624 throw new UnsupportedOperationException(
23625 "Operation only supported on apps targeting Android O or higher");
23627 String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
23628 String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission);
23629 if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
23630 throw new SecurityException("Need to declare " + appOpPermission + " to call this api");
23632 if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) {
23635 if (mExternalSourcesPolicy != null) {
23636 int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
23637 if (isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_DEFAULT) {
23638 return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
23641 return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED;
23645 public ComponentName getInstantAppResolverSettingsComponent() {
23646 return mInstantAppResolverSettingsComponent;
23650 public ComponentName getInstantAppInstallerComponent() {
23651 return mInstantAppInstallerActivity == null
23652 ? null : mInstantAppInstallerActivity.getComponentName();
23656 interface PackageSender {
23657 void sendPackageBroadcast(final String action, final String pkg,
23658 final Bundle extras, final int flags, final String targetPkg,
23659 final IIntentReceiver finishedReceiver, final int[] userIds);
23660 void sendPackageAddedForNewUsers(String packageName, boolean isSystem,
23661 int appId, int... userIds);