Home | History | Annotate | Download | only in pm
      1 /*
      2  * Copyright (C) 2006 The Android Open Source Project
      3  *
      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
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     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.
     15  */
     16 
     17 package com.android.server.pm;
     18 
     19 import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
     20 import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
     21 import static android.Manifest.permission.WRITE_MEDIA_STORAGE;
     22 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
     23 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
     24 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
     25 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
     26 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
     27 import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
     28 import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
     29 import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
     30 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
     31 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
     32 import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
     33 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
     34 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
     35 import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
     36 import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
     37 import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
     38 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
     39 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
     40 import static android.content.pm.PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID;
     41 import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
     42 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
     43 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
     44 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
     45 import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
     46 import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
     47 import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
     48 import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
     49 import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
     50 import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
     51 import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
     52 import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
     53 import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK;
     54 import static android.content.pm.PackageManager.INSTALL_INTERNAL;
     55 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
     56 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
     57 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
     58 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
     59 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
     60 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
     61 import static android.content.pm.PackageManager.MATCH_ALL;
     62 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
     63 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
     64 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
     65 import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
     66 import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
     67 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
     68 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
     69 import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN;
     70 import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
     71 import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
     72 import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
     73 import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
     74 import static android.content.pm.PackageManager.PERMISSION_DENIED;
     75 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
     76 import static android.content.pm.PackageParser.PARSE_IS_PRIVILEGED;
     77 import static android.content.pm.PackageParser.isApkFile;
     78 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
     79 import static android.system.OsConstants.O_CREAT;
     80 import static android.system.OsConstants.O_RDWR;
     81 
     82 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
     83 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
     84 import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
     85 import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
     86 import static com.android.internal.util.ArrayUtils.appendInt;
     87 import static com.android.server.pm.Installer.DEXOPT_PUBLIC;
     88 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
     89 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
     90 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
     91 import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
     92 import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
     93 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
     94 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getFullCompilerFilter;
     95 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getNonProfileGuidedCompilerFilter;
     96 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
     97 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
     98 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
     99 
    100 import android.Manifest;
    101 import android.annotation.NonNull;
    102 import android.annotation.Nullable;
    103 import android.app.ActivityManager;
    104 import android.app.ActivityManagerNative;
    105 import android.app.IActivityManager;
    106 import android.app.ResourcesManager;
    107 import android.app.admin.IDevicePolicyManager;
    108 import android.app.admin.SecurityLog;
    109 import android.app.backup.IBackupManager;
    110 import android.content.BroadcastReceiver;
    111 import android.content.ComponentName;
    112 import android.content.ContentResolver;
    113 import android.content.Context;
    114 import android.content.IIntentReceiver;
    115 import android.content.Intent;
    116 import android.content.IntentFilter;
    117 import android.content.IntentSender;
    118 import android.content.IntentSender.SendIntentException;
    119 import android.content.ServiceConnection;
    120 import android.content.pm.ActivityInfo;
    121 import android.content.pm.ApplicationInfo;
    122 import android.content.pm.AppsQueryHelper;
    123 import android.content.pm.ComponentInfo;
    124 import android.content.pm.EphemeralApplicationInfo;
    125 import android.content.pm.EphemeralResolveInfo;
    126 import android.content.pm.EphemeralResolveInfo.EphemeralDigest;
    127 import android.content.pm.EphemeralResolveInfo.EphemeralResolveIntentInfo;
    128 import android.content.pm.FeatureInfo;
    129 import android.content.pm.IOnPermissionsChangeListener;
    130 import android.content.pm.IPackageDataObserver;
    131 import android.content.pm.IPackageDeleteObserver;
    132 import android.content.pm.IPackageDeleteObserver2;
    133 import android.content.pm.IPackageInstallObserver2;
    134 import android.content.pm.IPackageInstaller;
    135 import android.content.pm.IPackageManager;
    136 import android.content.pm.IPackageMoveObserver;
    137 import android.content.pm.IPackageStatsObserver;
    138 import android.content.pm.InstrumentationInfo;
    139 import android.content.pm.IntentFilterVerificationInfo;
    140 import android.content.pm.KeySet;
    141 import android.content.pm.PackageCleanItem;
    142 import android.content.pm.PackageInfo;
    143 import android.content.pm.PackageInfoLite;
    144 import android.content.pm.PackageInstaller;
    145 import android.content.pm.PackageManager;
    146 import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
    147 import android.content.pm.PackageManagerInternal;
    148 import android.content.pm.PackageParser;
    149 import android.content.pm.PackageParser.ActivityIntentInfo;
    150 import android.content.pm.PackageParser.PackageLite;
    151 import android.content.pm.PackageParser.PackageParserException;
    152 import android.content.pm.PackageStats;
    153 import android.content.pm.PackageUserState;
    154 import android.content.pm.ParceledListSlice;
    155 import android.content.pm.PermissionGroupInfo;
    156 import android.content.pm.PermissionInfo;
    157 import android.content.pm.ProviderInfo;
    158 import android.content.pm.ResolveInfo;
    159 import android.content.pm.ServiceInfo;
    160 import android.content.pm.Signature;
    161 import android.content.pm.UserInfo;
    162 import android.content.pm.VerifierDeviceIdentity;
    163 import android.content.pm.VerifierInfo;
    164 import android.content.res.Resources;
    165 import android.graphics.Bitmap;
    166 import android.hardware.display.DisplayManager;
    167 import android.net.Uri;
    168 import android.os.Binder;
    169 import android.os.Build;
    170 import android.os.Bundle;
    171 import android.os.Debug;
    172 import android.os.Environment;
    173 import android.os.Environment.UserEnvironment;
    174 import android.os.FileUtils;
    175 import android.os.Handler;
    176 import android.os.IBinder;
    177 import android.os.Looper;
    178 import android.os.Message;
    179 import android.os.Parcel;
    180 import android.os.ParcelFileDescriptor;
    181 import android.os.PatternMatcher;
    182 import android.os.Process;
    183 import android.os.RemoteCallbackList;
    184 import android.os.RemoteException;
    185 import android.os.ResultReceiver;
    186 import android.os.SELinux;
    187 import android.os.ServiceManager;
    188 import android.os.SystemClock;
    189 import android.os.SystemProperties;
    190 import android.os.Trace;
    191 import android.os.UserHandle;
    192 import android.os.UserManager;
    193 import android.os.UserManagerInternal;
    194 import android.os.storage.IMountService;
    195 import android.os.storage.MountServiceInternal;
    196 import android.os.storage.StorageEventListener;
    197 import android.os.storage.StorageManager;
    198 import android.os.storage.VolumeInfo;
    199 import android.os.storage.VolumeRecord;
    200 import android.provider.Settings.Global;
    201 import android.provider.Settings.Secure;
    202 import android.security.KeyStore;
    203 import android.security.SystemKeyStore;
    204 import android.system.ErrnoException;
    205 import android.system.Os;
    206 import android.text.TextUtils;
    207 import android.text.format.DateUtils;
    208 import android.util.ArrayMap;
    209 import android.util.ArraySet;
    210 import android.util.DisplayMetrics;
    211 import android.util.EventLog;
    212 import android.util.ExceptionUtils;
    213 import android.util.Log;
    214 import android.util.LogPrinter;
    215 import android.util.MathUtils;
    216 import android.util.Pair;
    217 import android.util.PrintStreamPrinter;
    218 import android.util.Slog;
    219 import android.util.SparseArray;
    220 import android.util.SparseBooleanArray;
    221 import android.util.SparseIntArray;
    222 import android.util.Xml;
    223 import android.util.jar.StrictJarFile;
    224 import android.view.Display;
    225 
    226 import com.android.internal.R;
    227 import com.android.internal.annotations.GuardedBy;
    228 import com.android.internal.app.IMediaContainerService;
    229 import com.android.internal.app.ResolverActivity;
    230 import com.android.internal.content.NativeLibraryHelper;
    231 import com.android.internal.content.PackageHelper;
    232 import com.android.internal.logging.MetricsLogger;
    233 import com.android.internal.os.IParcelFileDescriptorFactory;
    234 import com.android.internal.os.InstallerConnection.InstallerException;
    235 import com.android.internal.os.SomeArgs;
    236 import com.android.internal.os.Zygote;
    237 import com.android.internal.telephony.CarrierAppUtils;
    238 import com.android.internal.util.ArrayUtils;
    239 import com.android.internal.util.FastPrintWriter;
    240 import com.android.internal.util.FastXmlSerializer;
    241 import com.android.internal.util.IndentingPrintWriter;
    242 import com.android.internal.util.Preconditions;
    243 import com.android.internal.util.XmlUtils;
    244 import com.android.server.AttributeCache;
    245 import com.android.server.EventLogTags;
    246 import com.android.server.FgThread;
    247 import com.android.server.IntentResolver;
    248 import com.android.server.LocalServices;
    249 import com.android.server.ServiceThread;
    250 import com.android.server.SystemConfig;
    251 import com.android.server.Watchdog;
    252 import com.android.server.net.NetworkPolicyManagerInternal;
    253 import com.android.server.pm.PermissionsState.PermissionState;
    254 import com.android.server.pm.Settings.DatabaseVersion;
    255 import com.android.server.pm.Settings.VersionInfo;
    256 import com.android.server.storage.DeviceStorageMonitorInternal;
    257 
    258 import dalvik.system.CloseGuard;
    259 import dalvik.system.DexFile;
    260 import dalvik.system.VMRuntime;
    261 
    262 import libcore.io.IoUtils;
    263 import libcore.util.EmptyArray;
    264 
    265 import org.xmlpull.v1.XmlPullParser;
    266 import org.xmlpull.v1.XmlPullParserException;
    267 import org.xmlpull.v1.XmlSerializer;
    268 
    269 import java.io.BufferedOutputStream;
    270 import java.io.BufferedReader;
    271 import java.io.ByteArrayInputStream;
    272 import java.io.ByteArrayOutputStream;
    273 import java.io.File;
    274 import java.io.FileDescriptor;
    275 import java.io.FileInputStream;
    276 import java.io.FileNotFoundException;
    277 import java.io.FileOutputStream;
    278 import java.io.FileReader;
    279 import java.io.FilenameFilter;
    280 import java.io.IOException;
    281 import java.io.PrintWriter;
    282 import java.nio.charset.StandardCharsets;
    283 import java.security.DigestInputStream;
    284 import java.security.MessageDigest;
    285 import java.security.NoSuchAlgorithmException;
    286 import java.security.PublicKey;
    287 import java.security.cert.Certificate;
    288 import java.security.cert.CertificateEncodingException;
    289 import java.security.cert.CertificateException;
    290 import java.text.SimpleDateFormat;
    291 import java.util.ArrayList;
    292 import java.util.Arrays;
    293 import java.util.Collection;
    294 import java.util.Collections;
    295 import java.util.Comparator;
    296 import java.util.Date;
    297 import java.util.HashSet;
    298 import java.util.Iterator;
    299 import java.util.List;
    300 import java.util.Map;
    301 import java.util.Objects;
    302 import java.util.Set;
    303 import java.util.concurrent.CountDownLatch;
    304 import java.util.concurrent.TimeUnit;
    305 import java.util.concurrent.atomic.AtomicBoolean;
    306 import java.util.concurrent.atomic.AtomicInteger;
    307 
    308 /**
    309  * Keep track of all those APKs everywhere.
    310  * <p>
    311  * Internally there are two important locks:
    312  * <ul>
    313  * <li>{@link #mPackages} is used to guard all in-memory parsed package details
    314  * and other related state. It is a fine-grained lock that should only be held
    315  * momentarily, as it's one of the most contended locks in the system.
    316  * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
    317  * operations typically involve heavy lifting of application data on disk. Since
    318  * {@code installd} is single-threaded, and it's operations can often be slow,
    319  * this lock should never be acquired while already holding {@link #mPackages}.
    320  * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
    321  * holding {@link #mInstallLock}.
    322  * </ul>
    323  * Many internal methods rely on the caller to hold the appropriate locks, and
    324  * this contract is expressed through method name suffixes:
    325  * <ul>
    326  * <li>fooLI(): the caller must hold {@link #mInstallLock}
    327  * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
    328  * being modified must be frozen
    329  * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
    330  * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
    331  * </ul>
    332  * <p>
    333  * Because this class is very central to the platform's security; please run all
    334  * CTS and unit tests whenever making modifications:
    335  *
    336  * <pre>
    337  * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
    338  * $ cts-tradefed run commandAndExit cts -m AppSecurityTests
    339  * </pre>
    340  */
    341 public class PackageManagerService extends IPackageManager.Stub {
    342     static final String TAG = "PackageManager";
    343     static final boolean DEBUG_SETTINGS = false;
    344     static final boolean DEBUG_PREFERRED = false;
    345     static final boolean DEBUG_UPGRADE = false;
    346     static final boolean DEBUG_DOMAIN_VERIFICATION = false;
    347     private static final boolean DEBUG_BACKUP = false;
    348     private static final boolean DEBUG_INSTALL = false;
    349     private static final boolean DEBUG_REMOVE = false;
    350     private static final boolean DEBUG_BROADCASTS = false;
    351     private static final boolean DEBUG_SHOW_INFO = false;
    352     private static final boolean DEBUG_PACKAGE_INFO = false;
    353     private static final boolean DEBUG_INTENT_MATCHING = false;
    354     private static final boolean DEBUG_PACKAGE_SCANNING = false;
    355     private static final boolean DEBUG_VERIFY = false;
    356     private static final boolean DEBUG_FILTERS = false;
    357 
    358     // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
    359     // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
    360     // user, but by default initialize to this.
    361     static final boolean DEBUG_DEXOPT = false;
    362 
    363     private static final boolean DEBUG_ABI_SELECTION = false;
    364     private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE;
    365     private static final boolean DEBUG_TRIAGED_MISSING = false;
    366     private static final boolean DEBUG_APP_DATA = false;
    367 
    368     static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
    369 
    370     private static final boolean DISABLE_EPHEMERAL_APPS = false;
    371     private static final boolean HIDE_EPHEMERAL_APIS = true;
    372 
    373     private static final int RADIO_UID = Process.PHONE_UID;
    374     private static final int LOG_UID = Process.LOG_UID;
    375     private static final int NFC_UID = Process.NFC_UID;
    376     private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
    377     private static final int SHELL_UID = Process.SHELL_UID;
    378 
    379     // Cap the size of permission trees that 3rd party apps can define
    380     private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
    381 
    382     // Suffix used during package installation when copying/moving
    383     // package apks to install directory.
    384     private static final String INSTALL_PACKAGE_SUFFIX = "-";
    385 
    386     static final int SCAN_NO_DEX = 1<<1;
    387     static final int SCAN_FORCE_DEX = 1<<2;
    388     static final int SCAN_UPDATE_SIGNATURE = 1<<3;
    389     static final int SCAN_NEW_INSTALL = 1<<4;
    390     static final int SCAN_NO_PATHS = 1<<5;
    391     static final int SCAN_UPDATE_TIME = 1<<6;
    392     static final int SCAN_DEFER_DEX = 1<<7;
    393     static final int SCAN_BOOTING = 1<<8;
    394     static final int SCAN_TRUSTED_OVERLAY = 1<<9;
    395     static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10;
    396     static final int SCAN_REPLACING = 1<<11;
    397     static final int SCAN_REQUIRE_KNOWN = 1<<12;
    398     static final int SCAN_MOVE = 1<<13;
    399     static final int SCAN_INITIAL = 1<<14;
    400     static final int SCAN_CHECK_ONLY = 1<<15;
    401     static final int SCAN_DONT_KILL_APP = 1<<17;
    402     static final int SCAN_IGNORE_FROZEN = 1<<18;
    403 
    404     static final int REMOVE_CHATTY = 1<<16;
    405 
    406     private static final int[] EMPTY_INT_ARRAY = new int[0];
    407 
    408     /**
    409      * Timeout (in milliseconds) after which the watchdog should declare that
    410      * our handler thread is wedged.  The usual default for such things is one
    411      * minute but we sometimes do very lengthy I/O operations on this thread,
    412      * such as installing multi-gigabyte applications, so ours needs to be longer.
    413      */
    414     private static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
    415 
    416     /**
    417      * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
    418      * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
    419      * settings entry if available, otherwise we use the hardcoded default.  If it's been
    420      * more than this long since the last fstrim, we force one during the boot sequence.
    421      *
    422      * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
    423      * one gets run at the next available charging+idle time.  This final mandatory
    424      * no-fstrim check kicks in only of the other scheduling criteria is never met.
    425      */
    426     private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
    427 
    428     /**
    429      * Whether verification is enabled by default.
    430      */
    431     private static final boolean DEFAULT_VERIFY_ENABLE = true;
    432 
    433     /**
    434      * The default maximum time to wait for the verification agent to return in
    435      * milliseconds.
    436      */
    437     private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
    438 
    439     /**
    440      * The default response for package verification timeout.
    441      *
    442      * This can be either PackageManager.VERIFICATION_ALLOW or
    443      * PackageManager.VERIFICATION_REJECT.
    444      */
    445     private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
    446 
    447     static final String PLATFORM_PACKAGE_NAME = "android";
    448 
    449     static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
    450 
    451     static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
    452             DEFAULT_CONTAINER_PACKAGE,
    453             "com.android.defcontainer.DefaultContainerService");
    454 
    455     private static final String KILL_APP_REASON_GIDS_CHANGED =
    456             "permission grant or revoke changed gids";
    457 
    458     private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
    459             "permissions revoked";
    460 
    461     private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
    462 
    463     private static final String PACKAGE_SCHEME = "package";
    464 
    465     private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
    466 
    467     private static int DEFAULT_EPHEMERAL_HASH_PREFIX_MASK = 0xFFFFF000;
    468     private static int DEFAULT_EPHEMERAL_HASH_PREFIX_COUNT = 5;
    469 
    470     /** Permission grant: not grant the permission. */
    471     private static final int GRANT_DENIED = 1;
    472 
    473     /** Permission grant: grant the permission as an install permission. */
    474     private static final int GRANT_INSTALL = 2;
    475 
    476     /** Permission grant: grant the permission as a runtime one. */
    477     private static final int GRANT_RUNTIME = 3;
    478 
    479     /** Permission grant: grant as runtime a permission that was granted as an install time one. */
    480     private static final int GRANT_UPGRADE = 4;
    481 
    482     /** Canonical intent used to identify what counts as a "web browser" app */
    483     private static final Intent sBrowserIntent;
    484     static {
    485         sBrowserIntent = new Intent();
    486         sBrowserIntent.setAction(Intent.ACTION_VIEW);
    487         sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
    488         sBrowserIntent.setData(Uri.parse("http:"));
    489     }
    490 
    491     /**
    492      * The set of all protected actions [i.e. those actions for which a high priority
    493      * intent filter is disallowed].
    494      */
    495     private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
    496     static {
    497         PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
    498         PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
    499         PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
    500         PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
    501     }
    502 
    503     // Compilation reasons.
    504     public static final int REASON_FIRST_BOOT = 0;
    505     public static final int REASON_BOOT = 1;
    506     public static final int REASON_INSTALL = 2;
    507     public static final int REASON_BACKGROUND_DEXOPT = 3;
    508     public static final int REASON_AB_OTA = 4;
    509     public static final int REASON_NON_SYSTEM_LIBRARY = 5;
    510     public static final int REASON_SHARED_APK = 6;
    511     public static final int REASON_FORCED_DEXOPT = 7;
    512     public static final int REASON_CORE_APP = 8;
    513 
    514     public static final int REASON_LAST = REASON_CORE_APP;
    515 
    516     /** Special library name that skips shared libraries check during compilation. */
    517     private static final String SKIP_SHARED_LIBRARY_CHECK = "&";
    518 
    519     final ServiceThread mHandlerThread;
    520 
    521     final PackageHandler mHandler;
    522 
    523     private final ProcessLoggingHandler mProcessLoggingHandler;
    524 
    525     /**
    526      * Messages for {@link #mHandler} that need to wait for system ready before
    527      * being dispatched.
    528      */
    529     private ArrayList<Message> mPostSystemReadyMessages;
    530 
    531     final int mSdkVersion = Build.VERSION.SDK_INT;
    532 
    533     final Context mContext;
    534     final boolean mFactoryTest;
    535     final boolean mOnlyCore;
    536     final DisplayMetrics mMetrics;
    537     final int mDefParseFlags;
    538     final String[] mSeparateProcesses;
    539     final boolean mIsUpgrade;
    540     final boolean mIsPreNUpgrade;
    541     final boolean mIsPreNMR1Upgrade;
    542 
    543     @GuardedBy("mPackages")
    544     private boolean mDexOptDialogShown;
    545 
    546     /** The location for ASEC container files on internal storage. */
    547     final String mAsecInternalPath;
    548 
    549     // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
    550     // LOCK HELD.  Can be called with mInstallLock held.
    551     @GuardedBy("mInstallLock")
    552     final Installer mInstaller;
    553 
    554     /** Directory where installed third-party apps stored */
    555     final File mAppInstallDir;
    556     final File mEphemeralInstallDir;
    557 
    558     /**
    559      * Directory to which applications installed internally have their
    560      * 32 bit native libraries copied.
    561      */
    562     private File mAppLib32InstallDir;
    563 
    564     // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
    565     // apps.
    566     final File mDrmAppPrivateInstallDir;
    567 
    568     // ----------------------------------------------------------------
    569 
    570     // Lock for state used when installing and doing other long running
    571     // operations.  Methods that must be called with this lock held have
    572     // the suffix "LI".
    573     final Object mInstallLock = new Object();
    574 
    575     // ----------------------------------------------------------------
    576 
    577     // Keys are String (package name), values are Package.  This also serves
    578     // as the lock for the global state.  Methods that must be called with
    579     // this lock held have the prefix "LP".
    580     @GuardedBy("mPackages")
    581     final ArrayMap<String, PackageParser.Package> mPackages =
    582             new ArrayMap<String, PackageParser.Package>();
    583 
    584     final ArrayMap<String, Set<String>> mKnownCodebase =
    585             new ArrayMap<String, Set<String>>();
    586 
    587     // Tracks available target package names -> overlay package paths.
    588     final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays =
    589         new ArrayMap<String, ArrayMap<String, PackageParser.Package>>();
    590 
    591     /**
    592      * Tracks new system packages [received in an OTA] that we expect to
    593      * find updated user-installed versions. Keys are package name, values
    594      * are package location.
    595      */
    596     final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
    597     /**
    598      * Tracks high priority intent filters for protected actions. During boot, certain
    599      * filter actions are protected and should never be allowed to have a high priority
    600      * intent filter for them. However, there is one, and only one exception -- the
    601      * setup wizard. It must be able to define a high priority intent filter for these
    602      * actions to ensure there are no escapes from the wizard. We need to delay processing
    603      * of these during boot as we need to look at all of the system packages in order
    604      * to know which component is the setup wizard.
    605      */
    606     private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
    607     /**
    608      * Whether or not processing protected filters should be deferred.
    609      */
    610     private boolean mDeferProtectedFilters = true;
    611 
    612     /**
    613      * Tracks existing system packages prior to receiving an OTA. Keys are package name.
    614      */
    615     final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
    616     /**
    617      * Whether or not system app permissions should be promoted from install to runtime.
    618      */
    619     boolean mPromoteSystemApps;
    620 
    621     @GuardedBy("mPackages")
    622     final Settings mSettings;
    623 
    624     /**
    625      * Set of package names that are currently "frozen", which means active
    626      * surgery is being done on the code/data for that package. The platform
    627      * will refuse to launch frozen packages to avoid race conditions.
    628      *
    629      * @see PackageFreezer
    630      */
    631     @GuardedBy("mPackages")
    632     final ArraySet<String> mFrozenPackages = new ArraySet<>();
    633 
    634     final ProtectedPackages mProtectedPackages;
    635 
    636     boolean mFirstBoot;
    637 
    638     // System configuration read by SystemConfig.
    639     final int[] mGlobalGids;
    640     final SparseArray<ArraySet<String>> mSystemPermissions;
    641     final ArrayMap<String, FeatureInfo> mAvailableFeatures;
    642 
    643     // If mac_permissions.xml was found for seinfo labeling.
    644     boolean mFoundPolicyFile;
    645 
    646     private final EphemeralApplicationRegistry mEphemeralApplicationRegistry;
    647 
    648     public static final class SharedLibraryEntry {
    649         public final String path;
    650         public final String apk;
    651 
    652         SharedLibraryEntry(String _path, String _apk) {
    653             path = _path;
    654             apk = _apk;
    655         }
    656     }
    657 
    658     // Currently known shared libraries.
    659     final ArrayMap<String, SharedLibraryEntry> mSharedLibraries =
    660             new ArrayMap<String, SharedLibraryEntry>();
    661 
    662     // All available activities, for your resolving pleasure.
    663     final ActivityIntentResolver mActivities =
    664             new ActivityIntentResolver();
    665 
    666     // All available receivers, for your resolving pleasure.
    667     final ActivityIntentResolver mReceivers =
    668             new ActivityIntentResolver();
    669 
    670     // All available services, for your resolving pleasure.
    671     final ServiceIntentResolver mServices = new ServiceIntentResolver();
    672 
    673     // All available providers, for your resolving pleasure.
    674     final ProviderIntentResolver mProviders = new ProviderIntentResolver();
    675 
    676     // Mapping from provider base names (first directory in content URI codePath)
    677     // to the provider information.
    678     final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
    679             new ArrayMap<String, PackageParser.Provider>();
    680 
    681     // Mapping from instrumentation class names to info about them.
    682     final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
    683             new ArrayMap<ComponentName, PackageParser.Instrumentation>();
    684 
    685     // Mapping from permission names to info about them.
    686     final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
    687             new ArrayMap<String, PackageParser.PermissionGroup>();
    688 
    689     // Packages whose data we have transfered into another package, thus
    690     // should no longer exist.
    691     final ArraySet<String> mTransferedPackages = new ArraySet<String>();
    692 
    693     // Broadcast actions that are only available to the system.
    694     final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>();
    695 
    696     /** List of packages waiting for verification. */
    697     final SparseArray<PackageVerificationState> mPendingVerification
    698             = new SparseArray<PackageVerificationState>();
    699 
    700     /** Set of packages associated with each app op permission. */
    701     final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
    702 
    703     final PackageInstallerService mInstallerService;
    704 
    705     private final PackageDexOptimizer mPackageDexOptimizer;
    706 
    707     private AtomicInteger mNextMoveId = new AtomicInteger();
    708     private final MoveCallbacks mMoveCallbacks;
    709 
    710     private final OnPermissionChangeListeners mOnPermissionChangeListeners;
    711 
    712     // Cache of users who need badging.
    713     SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
    714 
    715     /** Token for keys in mPendingVerification. */
    716     private int mPendingVerificationToken = 0;
    717 
    718     volatile boolean mSystemReady;
    719     volatile boolean mSafeMode;
    720     volatile boolean mHasSystemUidErrors;
    721 
    722     ApplicationInfo mAndroidApplication;
    723     final ActivityInfo mResolveActivity = new ActivityInfo();
    724     final ResolveInfo mResolveInfo = new ResolveInfo();
    725     ComponentName mResolveComponentName;
    726     PackageParser.Package mPlatformPackage;
    727     ComponentName mCustomResolverComponentName;
    728 
    729     boolean mResolverReplaced = false;
    730 
    731     private final @Nullable ComponentName mIntentFilterVerifierComponent;
    732     private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
    733 
    734     private int mIntentFilterVerificationToken = 0;
    735 
    736     /** Component that knows whether or not an ephemeral application exists */
    737     final ComponentName mEphemeralResolverComponent;
    738     /** The service connection to the ephemeral resolver */
    739     final EphemeralResolverConnection mEphemeralResolverConnection;
    740 
    741     /** Component used to install ephemeral applications */
    742     final ComponentName mEphemeralInstallerComponent;
    743     final ActivityInfo mEphemeralInstallerActivity = new ActivityInfo();
    744     final ResolveInfo mEphemeralInstallerInfo = new ResolveInfo();
    745 
    746     final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
    747             = new SparseArray<IntentFilterVerificationState>();
    748 
    749     final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
    750 
    751     // List of packages names to keep cached, even if they are uninstalled for all users
    752     private List<String> mKeepUninstalledPackages;
    753 
    754     private UserManagerInternal mUserManagerInternal;
    755 
    756     private static class IFVerificationParams {
    757         PackageParser.Package pkg;
    758         boolean replacing;
    759         int userId;
    760         int verifierUid;
    761 
    762         public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
    763                 int _userId, int _verifierUid) {
    764             pkg = _pkg;
    765             replacing = _replacing;
    766             userId = _userId;
    767             replacing = _replacing;
    768             verifierUid = _verifierUid;
    769         }
    770     }
    771 
    772     private interface IntentFilterVerifier<T extends IntentFilter> {
    773         boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
    774                                                T filter, String packageName);
    775         void startVerifications(int userId);
    776         void receiveVerificationResponse(int verificationId);
    777     }
    778 
    779     private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
    780         private Context mContext;
    781         private ComponentName mIntentFilterVerifierComponent;
    782         private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
    783 
    784         public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
    785             mContext = context;
    786             mIntentFilterVerifierComponent = verifierComponent;
    787         }
    788 
    789         private String getDefaultScheme() {
    790             return IntentFilter.SCHEME_HTTPS;
    791         }
    792 
    793         @Override
    794         public void startVerifications(int userId) {
    795             // Launch verifications requests
    796             int count = mCurrentIntentFilterVerifications.size();
    797             for (int n=0; n<count; n++) {
    798                 int verificationId = mCurrentIntentFilterVerifications.get(n);
    799                 final IntentFilterVerificationState ivs =
    800                         mIntentFilterVerificationStates.get(verificationId);
    801 
    802                 String packageName = ivs.getPackageName();
    803 
    804                 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
    805                 final int filterCount = filters.size();
    806                 ArraySet<String> domainsSet = new ArraySet<>();
    807                 for (int m=0; m<filterCount; m++) {
    808                     PackageParser.ActivityIntentInfo filter = filters.get(m);
    809                     domainsSet.addAll(filter.getHostsList());
    810                 }
    811                 ArrayList<String> domainsList = new ArrayList<>(domainsSet);
    812                 synchronized (mPackages) {
    813                     if (mSettings.createIntentFilterVerificationIfNeededLPw(
    814                             packageName, domainsList) != null) {
    815                         scheduleWriteSettingsLocked();
    816                     }
    817                 }
    818                 sendVerificationRequest(userId, verificationId, ivs);
    819             }
    820             mCurrentIntentFilterVerifications.clear();
    821         }
    822 
    823         private void sendVerificationRequest(int userId, int verificationId,
    824                 IntentFilterVerificationState ivs) {
    825 
    826             Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
    827             verificationIntent.putExtra(
    828                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
    829                     verificationId);
    830             verificationIntent.putExtra(
    831                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
    832                     getDefaultScheme());
    833             verificationIntent.putExtra(
    834                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
    835                     ivs.getHostsString());
    836             verificationIntent.putExtra(
    837                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
    838                     ivs.getPackageName());
    839             verificationIntent.setComponent(mIntentFilterVerifierComponent);
    840             verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
    841 
    842             UserHandle user = new UserHandle(userId);
    843             mContext.sendBroadcastAsUser(verificationIntent, user);
    844             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
    845                     "Sending IntentFilter verification broadcast");
    846         }
    847 
    848         public void receiveVerificationResponse(int verificationId) {
    849             IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
    850 
    851             final boolean verified = ivs.isVerified();
    852 
    853             ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
    854             final int count = filters.size();
    855             if (DEBUG_DOMAIN_VERIFICATION) {
    856                 Slog.i(TAG, "Received verification response " + verificationId
    857                         + " for " + count + " filters, verified=" + verified);
    858             }
    859             for (int n=0; n<count; n++) {
    860                 PackageParser.ActivityIntentInfo filter = filters.get(n);
    861                 filter.setVerified(verified);
    862 
    863                 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
    864                         + " verified with result:" + verified + " and hosts:"
    865                         + ivs.getHostsString());
    866             }
    867 
    868             mIntentFilterVerificationStates.remove(verificationId);
    869 
    870             final String packageName = ivs.getPackageName();
    871             IntentFilterVerificationInfo ivi = null;
    872 
    873             synchronized (mPackages) {
    874                 ivi = mSettings.getIntentFilterVerificationLPr(packageName);
    875             }
    876             if (ivi == null) {
    877                 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
    878                         + verificationId + " packageName:" + packageName);
    879                 return;
    880             }
    881             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
    882                     "Updating IntentFilterVerificationInfo for package " + packageName
    883                             +" verificationId:" + verificationId);
    884 
    885             synchronized (mPackages) {
    886                 if (verified) {
    887                     ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
    888                 } else {
    889                     ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
    890                 }
    891                 scheduleWriteSettingsLocked();
    892 
    893                 final int userId = ivs.getUserId();
    894                 if (userId != UserHandle.USER_ALL) {
    895                     final int userStatus =
    896                             mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
    897 
    898                     int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
    899                     boolean needUpdate = false;
    900 
    901                     // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
    902                     // already been set by the User thru the Disambiguation dialog
    903                     switch (userStatus) {
    904                         case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
    905                             if (verified) {
    906                                 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
    907                             } else {
    908                                 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
    909                             }
    910                             needUpdate = true;
    911                             break;
    912 
    913                         case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
    914                             if (verified) {
    915                                 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
    916                                 needUpdate = true;
    917                             }
    918                             break;
    919 
    920                         default:
    921                             // Nothing to do
    922                     }
    923 
    924                     if (needUpdate) {
    925                         mSettings.updateIntentFilterVerificationStatusLPw(
    926                                 packageName, updatedStatus, userId);
    927                         scheduleWritePackageRestrictionsLocked(userId);
    928                     }
    929                 }
    930             }
    931         }
    932 
    933         @Override
    934         public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
    935                     ActivityIntentInfo filter, String packageName) {
    936             if (!hasValidDomains(filter)) {
    937                 return false;
    938             }
    939             IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
    940             if (ivs == null) {
    941                 ivs = createDomainVerificationState(verifierUid, userId, verificationId,
    942                         packageName);
    943             }
    944             if (DEBUG_DOMAIN_VERIFICATION) {
    945                 Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
    946             }
    947             ivs.addFilter(filter);
    948             return true;
    949         }
    950 
    951         private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
    952                 int userId, int verificationId, String packageName) {
    953             IntentFilterVerificationState ivs = new IntentFilterVerificationState(
    954                     verifierUid, userId, packageName);
    955             ivs.setPendingState();
    956             synchronized (mPackages) {
    957                 mIntentFilterVerificationStates.append(verificationId, ivs);
    958                 mCurrentIntentFilterVerifications.add(verificationId);
    959             }
    960             return ivs;
    961         }
    962     }
    963 
    964     private static boolean hasValidDomains(ActivityIntentInfo filter) {
    965         return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
    966                 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
    967                         filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
    968     }
    969 
    970     // Set of pending broadcasts for aggregating enable/disable of components.
    971     static class PendingPackageBroadcasts {
    972         // for each user id, a map of <package name -> components within that package>
    973         final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
    974 
    975         public PendingPackageBroadcasts() {
    976             mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
    977         }
    978 
    979         public ArrayList<String> get(int userId, String packageName) {
    980             ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
    981             return packages.get(packageName);
    982         }
    983 
    984         public void put(int userId, String packageName, ArrayList<String> components) {
    985             ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
    986             packages.put(packageName, components);
    987         }
    988 
    989         public void remove(int userId, String packageName) {
    990             ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
    991             if (packages != null) {
    992                 packages.remove(packageName);
    993             }
    994         }
    995 
    996         public void remove(int userId) {
    997             mUidMap.remove(userId);
    998         }
    999 
   1000         public int userIdCount() {
   1001             return mUidMap.size();
   1002         }
   1003 
   1004         public int userIdAt(int n) {
   1005             return mUidMap.keyAt(n);
   1006         }
   1007 
   1008         public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
   1009             return mUidMap.get(userId);
   1010         }
   1011 
   1012         public int size() {
   1013             // total number of pending broadcast entries across all userIds
   1014             int num = 0;
   1015             for (int i = 0; i< mUidMap.size(); i++) {
   1016                 num += mUidMap.valueAt(i).size();
   1017             }
   1018             return num;
   1019         }
   1020 
   1021         public void clear() {
   1022             mUidMap.clear();
   1023         }
   1024 
   1025         private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
   1026             ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
   1027             if (map == null) {
   1028                 map = new ArrayMap<String, ArrayList<String>>();
   1029                 mUidMap.put(userId, map);
   1030             }
   1031             return map;
   1032         }
   1033     }
   1034     final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
   1035 
   1036     // Service Connection to remote media container service to copy
   1037     // package uri's from external media onto secure containers
   1038     // or internal storage.
   1039     private IMediaContainerService mContainerService = null;
   1040 
   1041     static final int SEND_PENDING_BROADCAST = 1;
   1042     static final int MCS_BOUND = 3;
   1043     static final int END_COPY = 4;
   1044     static final int INIT_COPY = 5;
   1045     static final int MCS_UNBIND = 6;
   1046     static final int START_CLEANING_PACKAGE = 7;
   1047     static final int FIND_INSTALL_LOC = 8;
   1048     static final int POST_INSTALL = 9;
   1049     static final int MCS_RECONNECT = 10;
   1050     static final int MCS_GIVE_UP = 11;
   1051     static final int UPDATED_MEDIA_STATUS = 12;
   1052     static final int WRITE_SETTINGS = 13;
   1053     static final int WRITE_PACKAGE_RESTRICTIONS = 14;
   1054     static final int PACKAGE_VERIFIED = 15;
   1055     static final int CHECK_PENDING_VERIFICATION = 16;
   1056     static final int START_INTENT_FILTER_VERIFICATIONS = 17;
   1057     static final int INTENT_FILTER_VERIFIED = 18;
   1058     static final int WRITE_PACKAGE_LIST = 19;
   1059 
   1060     static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
   1061 
   1062     // Delay time in millisecs
   1063     static final int BROADCAST_DELAY = 10 * 1000;
   1064 
   1065     static UserManagerService sUserManager;
   1066 
   1067     // Stores a list of users whose package restrictions file needs to be updated
   1068     private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
   1069 
   1070     final private DefaultContainerConnection mDefContainerConn =
   1071             new DefaultContainerConnection();
   1072     class DefaultContainerConnection implements ServiceConnection {
   1073         public void onServiceConnected(ComponentName name, IBinder service) {
   1074             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
   1075             IMediaContainerService imcs =
   1076                 IMediaContainerService.Stub.asInterface(service);
   1077             mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
   1078         }
   1079 
   1080         public void onServiceDisconnected(ComponentName name) {
   1081             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
   1082         }
   1083     }
   1084 
   1085     // Recordkeeping of restore-after-install operations that are currently in flight
   1086     // between the Package Manager and the Backup Manager
   1087     static class PostInstallData {
   1088         public InstallArgs args;
   1089         public PackageInstalledInfo res;
   1090 
   1091         PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
   1092             args = _a;
   1093             res = _r;
   1094         }
   1095     }
   1096 
   1097     final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
   1098     int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
   1099 
   1100     // XML tags for backup/restore of various bits of state
   1101     private static final String TAG_PREFERRED_BACKUP = "pa";
   1102     private static final String TAG_DEFAULT_APPS = "da";
   1103     private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
   1104 
   1105     private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
   1106     private static final String TAG_ALL_GRANTS = "rt-grants";
   1107     private static final String TAG_GRANT = "grant";
   1108     private static final String ATTR_PACKAGE_NAME = "pkg";
   1109 
   1110     private static final String TAG_PERMISSION = "perm";
   1111     private static final String ATTR_PERMISSION_NAME = "name";
   1112     private static final String ATTR_IS_GRANTED = "g";
   1113     private static final String ATTR_USER_SET = "set";
   1114     private static final String ATTR_USER_FIXED = "fixed";
   1115     private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
   1116 
   1117     // System/policy permission grants are not backed up
   1118     private static final int SYSTEM_RUNTIME_GRANT_MASK =
   1119             FLAG_PERMISSION_POLICY_FIXED
   1120             | FLAG_PERMISSION_SYSTEM_FIXED
   1121             | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
   1122 
   1123     // And we back up these user-adjusted states
   1124     private static final int USER_RUNTIME_GRANT_MASK =
   1125             FLAG_PERMISSION_USER_SET
   1126             | FLAG_PERMISSION_USER_FIXED
   1127             | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
   1128 
   1129     final @Nullable String mRequiredVerifierPackage;
   1130     final @NonNull String mRequiredInstallerPackage;
   1131     final @NonNull String mRequiredUninstallerPackage;
   1132     final @Nullable String mSetupWizardPackage;
   1133     final @Nullable String mStorageManagerPackage;
   1134     final @NonNull String mServicesSystemSharedLibraryPackageName;
   1135     final @NonNull String mSharedSystemSharedLibraryPackageName;
   1136 
   1137     private final PackageUsage mPackageUsage = new PackageUsage();
   1138     private final CompilerStats mCompilerStats = new CompilerStats();
   1139 
   1140     class PackageHandler extends Handler {
   1141         private boolean mBound = false;
   1142         final ArrayList<HandlerParams> mPendingInstalls =
   1143             new ArrayList<HandlerParams>();
   1144 
   1145         private boolean connectToService() {
   1146             if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
   1147                     " DefaultContainerService");
   1148             Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
   1149             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
   1150             if (mContext.bindServiceAsUser(service, mDefContainerConn,
   1151                     Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
   1152                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
   1153                 mBound = true;
   1154                 return true;
   1155             }
   1156             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
   1157             return false;
   1158         }
   1159 
   1160         private void disconnectService() {
   1161             mContainerService = null;
   1162             mBound = false;
   1163             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
   1164             mContext.unbindService(mDefContainerConn);
   1165             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
   1166         }
   1167 
   1168         PackageHandler(Looper looper) {
   1169             super(looper);
   1170         }
   1171 
   1172         public void handleMessage(Message msg) {
   1173             try {
   1174                 doHandleMessage(msg);
   1175             } finally {
   1176                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
   1177             }
   1178         }
   1179 
   1180         void doHandleMessage(Message msg) {
   1181             switch (msg.what) {
   1182                 case INIT_COPY: {
   1183                     HandlerParams params = (HandlerParams) msg.obj;
   1184                     int idx = mPendingInstalls.size();
   1185                     if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
   1186                     // If a bind was already initiated we dont really
   1187                     // need to do anything. The pending install
   1188                     // will be processed later on.
   1189                     if (!mBound) {
   1190                         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
   1191                                 System.identityHashCode(mHandler));
   1192                         // If this is the only one pending we might
   1193                         // have to bind to the service again.
   1194                         if (!connectToService()) {
   1195                             Slog.e(TAG, "Failed to bind to media container service");
   1196                             params.serviceError();
   1197                             Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
   1198                                     System.identityHashCode(mHandler));
   1199                             if (params.traceMethod != null) {
   1200                                 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
   1201                                         params.traceCookie);
   1202                             }
   1203                             return;
   1204                         } else {
   1205                             // Once we bind to the service, the first
   1206                             // pending request will be processed.
   1207                             mPendingInstalls.add(idx, params);
   1208                         }
   1209                     } else {
   1210                         mPendingInstalls.add(idx, params);
   1211                         // Already bound to the service. Just make
   1212                         // sure we trigger off processing the first request.
   1213                         if (idx == 0) {
   1214                             mHandler.sendEmptyMessage(MCS_BOUND);
   1215                         }
   1216                     }
   1217                     break;
   1218                 }
   1219                 case MCS_BOUND: {
   1220                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
   1221                     if (msg.obj != null) {
   1222                         mContainerService = (IMediaContainerService) msg.obj;
   1223                         Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
   1224                                 System.identityHashCode(mHandler));
   1225                     }
   1226                     if (mContainerService == null) {
   1227                         if (!mBound) {
   1228                             // Something seriously wrong since we are not bound and we are not
   1229                             // waiting for connection. Bail out.
   1230                             Slog.e(TAG, "Cannot bind to media container service");
   1231                             for (HandlerParams params : mPendingInstalls) {
   1232                                 // Indicate service bind error
   1233                                 params.serviceError();
   1234                                 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
   1235                                         System.identityHashCode(params));
   1236                                 if (params.traceMethod != null) {
   1237                                     Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
   1238                                             params.traceMethod, params.traceCookie);
   1239                                 }
   1240                                 return;
   1241                             }
   1242                             mPendingInstalls.clear();
   1243                         } else {
   1244                             Slog.w(TAG, "Waiting to connect to media container service");
   1245                         }
   1246                     } else if (mPendingInstalls.size() > 0) {
   1247                         HandlerParams params = mPendingInstalls.get(0);
   1248                         if (params != null) {
   1249                             Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
   1250                                     System.identityHashCode(params));
   1251                             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
   1252                             if (params.startCopy()) {
   1253                                 // We are done...  look for more work or to
   1254                                 // go idle.
   1255                                 if (DEBUG_SD_INSTALL) Log.i(TAG,
   1256                                         "Checking for more work or unbind...");
   1257                                 // Delete pending install
   1258                                 if (mPendingInstalls.size() > 0) {
   1259                                     mPendingInstalls.remove(0);
   1260                                 }
   1261                                 if (mPendingInstalls.size() == 0) {
   1262                                     if (mBound) {
   1263                                         if (DEBUG_SD_INSTALL) Log.i(TAG,
   1264                                                 "Posting delayed MCS_UNBIND");
   1265                                         removeMessages(MCS_UNBIND);
   1266                                         Message ubmsg = obtainMessage(MCS_UNBIND);
   1267                                         // Unbind after a little delay, to avoid
   1268                                         // continual thrashing.
   1269                                         sendMessageDelayed(ubmsg, 10000);
   1270                                     }
   1271                                 } else {
   1272                                     // There are more pending requests in queue.
   1273                                     // Just post MCS_BOUND message to trigger processing
   1274                                     // of next pending install.
   1275                                     if (DEBUG_SD_INSTALL) Log.i(TAG,
   1276                                             "Posting MCS_BOUND for next work");
   1277                                     mHandler.sendEmptyMessage(MCS_BOUND);
   1278                                 }
   1279                             }
   1280                             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
   1281                         }
   1282                     } else {
   1283                         // Should never happen ideally.
   1284                         Slog.w(TAG, "Empty queue");
   1285                     }
   1286                     break;
   1287                 }
   1288                 case MCS_RECONNECT: {
   1289                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
   1290                     if (mPendingInstalls.size() > 0) {
   1291                         if (mBound) {
   1292                             disconnectService();
   1293                         }
   1294                         if (!connectToService()) {
   1295                             Slog.e(TAG, "Failed to bind to media container service");
   1296                             for (HandlerParams params : mPendingInstalls) {
   1297                                 // Indicate service bind error
   1298                                 params.serviceError();
   1299                                 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
   1300                                         System.identityHashCode(params));
   1301                             }
   1302                             mPendingInstalls.clear();
   1303                         }
   1304                     }
   1305                     break;
   1306                 }
   1307                 case MCS_UNBIND: {
   1308                     // If there is no actual work left, then time to unbind.
   1309                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
   1310 
   1311                     if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
   1312                         if (mBound) {
   1313                             if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
   1314 
   1315                             disconnectService();
   1316                         }
   1317                     } else if (mPendingInstalls.size() > 0) {
   1318                         // There are more pending requests in queue.
   1319                         // Just post MCS_BOUND message to trigger processing
   1320                         // of next pending install.
   1321                         mHandler.sendEmptyMessage(MCS_BOUND);
   1322                     }
   1323 
   1324                     break;
   1325                 }
   1326                 case MCS_GIVE_UP: {
   1327                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
   1328                     HandlerParams params = mPendingInstalls.remove(0);
   1329                     Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
   1330                             System.identityHashCode(params));
   1331                     break;
   1332                 }
   1333                 case SEND_PENDING_BROADCAST: {
   1334                     String packages[];
   1335                     ArrayList<String> components[];
   1336                     int size = 0;
   1337                     int uids[];
   1338                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
   1339                     synchronized (mPackages) {
   1340                         if (mPendingBroadcasts == null) {
   1341                             return;
   1342                         }
   1343                         size = mPendingBroadcasts.size();
   1344                         if (size <= 0) {
   1345                             // Nothing to be done. Just return
   1346                             return;
   1347                         }
   1348                         packages = new String[size];
   1349                         components = new ArrayList[size];
   1350                         uids = new int[size];
   1351                         int i = 0;  // filling out the above arrays
   1352 
   1353                         for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
   1354                             int packageUserId = mPendingBroadcasts.userIdAt(n);
   1355                             Iterator<Map.Entry<String, ArrayList<String>>> it
   1356                                     = mPendingBroadcasts.packagesForUserId(packageUserId)
   1357                                             .entrySet().iterator();
   1358                             while (it.hasNext() && i < size) {
   1359                                 Map.Entry<String, ArrayList<String>> ent = it.next();
   1360                                 packages[i] = ent.getKey();
   1361                                 components[i] = ent.getValue();
   1362                                 PackageSetting ps = mSettings.mPackages.get(ent.getKey());
   1363                                 uids[i] = (ps != null)
   1364                                         ? UserHandle.getUid(packageUserId, ps.appId)
   1365                                         : -1;
   1366                                 i++;
   1367                             }
   1368                         }
   1369                         size = i;
   1370                         mPendingBroadcasts.clear();
   1371                     }
   1372                     // Send broadcasts
   1373                     for (int i = 0; i < size; i++) {
   1374                         sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
   1375                     }
   1376                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
   1377                     break;
   1378                 }
   1379                 case START_CLEANING_PACKAGE: {
   1380                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
   1381                     final String packageName = (String)msg.obj;
   1382                     final int userId = msg.arg1;
   1383                     final boolean andCode = msg.arg2 != 0;
   1384                     synchronized (mPackages) {
   1385                         if (userId == UserHandle.USER_ALL) {
   1386                             int[] users = sUserManager.getUserIds();
   1387                             for (int user : users) {
   1388                                 mSettings.addPackageToCleanLPw(
   1389                                         new PackageCleanItem(user, packageName, andCode));
   1390                             }
   1391                         } else {
   1392                             mSettings.addPackageToCleanLPw(
   1393                                     new PackageCleanItem(userId, packageName, andCode));
   1394                         }
   1395                     }
   1396                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
   1397                     startCleaningPackages();
   1398                 } break;
   1399                 case POST_INSTALL: {
   1400                     if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
   1401 
   1402                     PostInstallData data = mRunningInstalls.get(msg.arg1);
   1403                     final boolean didRestore = (msg.arg2 != 0);
   1404                     mRunningInstalls.delete(msg.arg1);
   1405 
   1406                     if (data != null) {
   1407                         InstallArgs args = data.args;
   1408                         PackageInstalledInfo parentRes = data.res;
   1409 
   1410                         final boolean grantPermissions = (args.installFlags
   1411                                 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
   1412                         final boolean killApp = (args.installFlags
   1413                                 & PackageManager.INSTALL_DONT_KILL_APP) == 0;
   1414                         final String[] grantedPermissions = args.installGrantPermissions;
   1415 
   1416                         // Handle the parent package
   1417                         handlePackagePostInstall(parentRes, grantPermissions, killApp,
   1418                                 grantedPermissions, didRestore, args.installerPackageName,
   1419                                 args.observer);
   1420 
   1421                         // Handle the child packages
   1422                         final int childCount = (parentRes.addedChildPackages != null)
   1423                                 ? parentRes.addedChildPackages.size() : 0;
   1424                         for (int i = 0; i < childCount; i++) {
   1425                             PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
   1426                             handlePackagePostInstall(childRes, grantPermissions, killApp,
   1427                                     grantedPermissions, false, args.installerPackageName,
   1428                                     args.observer);
   1429                         }
   1430 
   1431                         // Log tracing if needed
   1432                         if (args.traceMethod != null) {
   1433                             Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
   1434                                     args.traceCookie);
   1435                         }
   1436                     } else {
   1437                         Slog.e(TAG, "Bogus post-install token " + msg.arg1);
   1438                     }
   1439 
   1440                     Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
   1441                 } break;
   1442                 case UPDATED_MEDIA_STATUS: {
   1443                     if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
   1444                     boolean reportStatus = msg.arg1 == 1;
   1445                     boolean doGc = msg.arg2 == 1;
   1446                     if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
   1447                     if (doGc) {
   1448                         // Force a gc to clear up stale containers.
   1449                         Runtime.getRuntime().gc();
   1450                     }
   1451                     if (msg.obj != null) {
   1452                         @SuppressWarnings("unchecked")
   1453                         Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
   1454                         if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
   1455                         // Unload containers
   1456                         unloadAllContainers(args);
   1457                     }
   1458                     if (reportStatus) {
   1459                         try {
   1460                             if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back");
   1461                             PackageHelper.getMountService().finishMediaUpdate();
   1462                         } catch (RemoteException e) {
   1463                             Log.e(TAG, "MountService not running?");
   1464                         }
   1465                     }
   1466                 } break;
   1467                 case WRITE_SETTINGS: {
   1468                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
   1469                     synchronized (mPackages) {
   1470                         removeMessages(WRITE_SETTINGS);
   1471                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
   1472                         mSettings.writeLPr();
   1473                         mDirtyUsers.clear();
   1474                     }
   1475                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
   1476                 } break;
   1477                 case WRITE_PACKAGE_RESTRICTIONS: {
   1478                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
   1479                     synchronized (mPackages) {
   1480                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
   1481                         for (int userId : mDirtyUsers) {
   1482                             mSettings.writePackageRestrictionsLPr(userId);
   1483                         }
   1484                         mDirtyUsers.clear();
   1485                     }
   1486                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
   1487                 } break;
   1488                 case WRITE_PACKAGE_LIST: {
   1489                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
   1490                     synchronized (mPackages) {
   1491                         removeMessages(WRITE_PACKAGE_LIST);
   1492                         mSettings.writePackageListLPr(msg.arg1);
   1493                     }
   1494                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
   1495                 } break;
   1496                 case CHECK_PENDING_VERIFICATION: {
   1497                     final int verificationId = msg.arg1;
   1498                     final PackageVerificationState state = mPendingVerification.get(verificationId);
   1499 
   1500                     if ((state != null) && !state.timeoutExtended()) {
   1501                         final InstallArgs args = state.getInstallArgs();
   1502                         final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
   1503 
   1504                         Slog.i(TAG, "Verification timed out for " + originUri);
   1505                         mPendingVerification.remove(verificationId);
   1506 
   1507                         int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
   1508 
   1509                         if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
   1510                             Slog.i(TAG, "Continuing with installation of " + originUri);
   1511                             state.setVerifierResponse(Binder.getCallingUid(),
   1512                                     PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
   1513                             broadcastPackageVerified(verificationId, originUri,
   1514                                     PackageManager.VERIFICATION_ALLOW,
   1515                                     state.getInstallArgs().getUser());
   1516                             try {
   1517                                 ret = args.copyApk(mContainerService, true);
   1518                             } catch (RemoteException e) {
   1519                                 Slog.e(TAG, "Could not contact the ContainerService");
   1520                             }
   1521                         } else {
   1522                             broadcastPackageVerified(verificationId, originUri,
   1523                                     PackageManager.VERIFICATION_REJECT,
   1524                                     state.getInstallArgs().getUser());
   1525                         }
   1526 
   1527                         Trace.asyncTraceEnd(
   1528                                 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
   1529 
   1530                         processPendingInstall(args, ret);
   1531                         mHandler.sendEmptyMessage(MCS_UNBIND);
   1532                     }
   1533                     break;
   1534                 }
   1535                 case PACKAGE_VERIFIED: {
   1536                     final int verificationId = msg.arg1;
   1537 
   1538                     final PackageVerificationState state = mPendingVerification.get(verificationId);
   1539                     if (state == null) {
   1540                         Slog.w(TAG, "Invalid verification token " + verificationId + " received");
   1541                         break;
   1542                     }
   1543 
   1544                     final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
   1545 
   1546                     state.setVerifierResponse(response.callerUid, response.code);
   1547 
   1548                     if (state.isVerificationComplete()) {
   1549                         mPendingVerification.remove(verificationId);
   1550 
   1551                         final InstallArgs args = state.getInstallArgs();
   1552                         final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
   1553 
   1554                         int ret;
   1555                         if (state.isInstallAllowed()) {
   1556                             ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
   1557                             broadcastPackageVerified(verificationId, originUri,
   1558                                     response.code, state.getInstallArgs().getUser());
   1559                             try {
   1560                                 ret = args.copyApk(mContainerService, true);
   1561                             } catch (RemoteException e) {
   1562                                 Slog.e(TAG, "Could not contact the ContainerService");
   1563                             }
   1564                         } else {
   1565                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
   1566                         }
   1567 
   1568                         Trace.asyncTraceEnd(
   1569                                 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
   1570 
   1571                         processPendingInstall(args, ret);
   1572                         mHandler.sendEmptyMessage(MCS_UNBIND);
   1573                     }
   1574 
   1575                     break;
   1576                 }
   1577                 case START_INTENT_FILTER_VERIFICATIONS: {
   1578                     IFVerificationParams params = (IFVerificationParams) msg.obj;
   1579                     verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
   1580                             params.replacing, params.pkg);
   1581                     break;
   1582                 }
   1583                 case INTENT_FILTER_VERIFIED: {
   1584                     final int verificationId = msg.arg1;
   1585 
   1586                     final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
   1587                             verificationId);
   1588                     if (state == null) {
   1589                         Slog.w(TAG, "Invalid IntentFilter verification token "
   1590                                 + verificationId + " received");
   1591                         break;
   1592                     }
   1593 
   1594                     final int userId = state.getUserId();
   1595 
   1596                     if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
   1597                             "Processing IntentFilter verification with token:"
   1598                             + verificationId + " and userId:" + userId);
   1599 
   1600                     final IntentFilterVerificationResponse response =
   1601                             (IntentFilterVerificationResponse) msg.obj;
   1602 
   1603                     state.setVerifierResponse(response.callerUid, response.code);
   1604 
   1605                     if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
   1606                             "IntentFilter verification with token:" + verificationId
   1607                             + " and userId:" + userId
   1608                             + " is settings verifier response with response code:"
   1609                             + response.code);
   1610 
   1611                     if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
   1612                         if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
   1613                                 + response.getFailedDomainsString());
   1614                     }
   1615 
   1616                     if (state.isVerificationComplete()) {
   1617                         mIntentFilterVerifier.receiveVerificationResponse(verificationId);
   1618                     } else {
   1619                         if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
   1620                                 "IntentFilter verification with token:" + verificationId
   1621                                 + " was not said to be complete");
   1622                     }
   1623 
   1624                     break;
   1625                 }
   1626             }
   1627         }
   1628     }
   1629 
   1630     private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
   1631             boolean killApp, String[] grantedPermissions,
   1632             boolean launchedForRestore, String installerPackage,
   1633             IPackageInstallObserver2 installObserver) {
   1634         if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
   1635             // Send the removed broadcasts
   1636             if (res.removedInfo != null) {
   1637                 res.removedInfo.sendPackageRemovedBroadcasts(killApp);
   1638             }
   1639 
   1640             // Now that we successfully installed the package, grant runtime
   1641             // permissions if requested before broadcasting the install.
   1642             if (grantPermissions && res.pkg.applicationInfo.targetSdkVersion
   1643                     >= Build.VERSION_CODES.M) {
   1644                 grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions);
   1645             }
   1646 
   1647             final boolean update = res.removedInfo != null
   1648                     && res.removedInfo.removedPackage != null;
   1649 
   1650             // If this is the first time we have child packages for a disabled privileged
   1651             // app that had no children, we grant requested runtime permissions to the new
   1652             // children if the parent on the system image had them already granted.
   1653             if (res.pkg.parentPackage != null) {
   1654                 synchronized (mPackages) {
   1655                     grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg);
   1656                 }
   1657             }
   1658 
   1659             synchronized (mPackages) {
   1660                 mEphemeralApplicationRegistry.onPackageInstalledLPw(res.pkg);
   1661             }
   1662 
   1663             final String packageName = res.pkg.applicationInfo.packageName;
   1664             Bundle extras = new Bundle(1);
   1665             extras.putInt(Intent.EXTRA_UID, res.uid);
   1666 
   1667             // Determine the set of users who are adding this package for
   1668             // the first time vs. those who are seeing an update.
   1669             int[] firstUsers = EMPTY_INT_ARRAY;
   1670             int[] updateUsers = EMPTY_INT_ARRAY;
   1671             if (res.origUsers == null || res.origUsers.length == 0) {
   1672                 firstUsers = res.newUsers;
   1673             } else {
   1674                 for (int newUser : res.newUsers) {
   1675                     boolean isNew = true;
   1676                     for (int origUser : res.origUsers) {
   1677                         if (origUser == newUser) {
   1678                             isNew = false;
   1679                             break;
   1680                         }
   1681                     }
   1682                     if (isNew) {
   1683                         firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
   1684                     } else {
   1685                         updateUsers = ArrayUtils.appendInt(updateUsers, newUser);
   1686                     }
   1687                 }
   1688             }
   1689 
   1690             // Send installed broadcasts if the install/update is not ephemeral
   1691             if (!isEphemeral(res.pkg)) {
   1692                 mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
   1693 
   1694                 // Send added for users that see the package for the first time
   1695                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
   1696                         extras, 0 /*flags*/, null /*targetPackage*/,
   1697                         null /*finishedReceiver*/, firstUsers);
   1698 
   1699                 // Send added for users that don't see the package for the first time
   1700                 if (update) {
   1701                     extras.putBoolean(Intent.EXTRA_REPLACING, true);
   1702                 }
   1703                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
   1704                         extras, 0 /*flags*/, null /*targetPackage*/,
   1705                         null /*finishedReceiver*/, updateUsers);
   1706 
   1707                 // Send replaced for users that don't see the package for the first time
   1708                 if (update) {
   1709                     sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
   1710                             packageName, extras, 0 /*flags*/,
   1711                             null /*targetPackage*/, null /*finishedReceiver*/,
   1712                             updateUsers);
   1713                     sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
   1714                             null /*package*/, null /*extras*/, 0 /*flags*/,
   1715                             packageName /*targetPackage*/,
   1716                             null /*finishedReceiver*/, updateUsers);
   1717                 } else if (launchedForRestore && !isSystemApp(res.pkg)) {
   1718                     // First-install and we did a restore, so we're responsible for the
   1719                     // first-launch broadcast.
   1720                     if (DEBUG_BACKUP) {
   1721                         Slog.i(TAG, "Post-restore of " + packageName
   1722                                 + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers));
   1723                     }
   1724                     sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers);
   1725                 }
   1726 
   1727                 // Send broadcast package appeared if forward locked/external for all users
   1728                 // treat asec-hosted packages like removable media on upgrade
   1729                 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
   1730                     if (DEBUG_INSTALL) {
   1731                         Slog.i(TAG, "upgrading pkg " + res.pkg
   1732                                 + " is ASEC-hosted -> AVAILABLE");
   1733                     }
   1734                     final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
   1735                     ArrayList<String> pkgList = new ArrayList<>(1);
   1736                     pkgList.add(packageName);
   1737                     sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
   1738                 }
   1739             }
   1740 
   1741             // Work that needs to happen on first install within each user
   1742             if (firstUsers != null && firstUsers.length > 0) {
   1743                 synchronized (mPackages) {
   1744                     for (int userId : firstUsers) {
   1745                         // If this app is a browser and it's newly-installed for some
   1746                         // users, clear any default-browser state in those users. The
   1747                         // app's nature doesn't depend on the user, so we can just check
   1748                         // its browser nature in any user and generalize.
   1749                         if (packageIsBrowser(packageName, userId)) {
   1750                             mSettings.setDefaultBrowserPackageNameLPw(null, userId);
   1751                         }
   1752 
   1753                         // We may also need to apply pending (restored) runtime
   1754                         // permission grants within these users.
   1755                         mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
   1756                     }
   1757                 }
   1758             }
   1759 
   1760             // Log current value of "unknown sources" setting
   1761             EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
   1762                     getUnknownSourcesSettings());
   1763 
   1764             // Force a gc to clear up things
   1765             Runtime.getRuntime().gc();
   1766 
   1767             // Remove the replaced package's older resources safely now
   1768             // We delete after a gc for applications  on sdcard.
   1769             if (res.removedInfo != null && res.removedInfo.args != null) {
   1770                 synchronized (mInstallLock) {
   1771                     res.removedInfo.args.doPostDeleteLI(true);
   1772                 }
   1773             }
   1774         }
   1775 
   1776         // If someone is watching installs - notify them
   1777         if (installObserver != null) {
   1778             try {
   1779                 Bundle extras = extrasForInstallResult(res);
   1780                 installObserver.onPackageInstalled(res.name, res.returnCode,
   1781                         res.returnMsg, extras);
   1782             } catch (RemoteException e) {
   1783                 Slog.i(TAG, "Observer no longer exists.");
   1784             }
   1785         }
   1786     }
   1787 
   1788     private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(
   1789             PackageParser.Package pkg) {
   1790         if (pkg.parentPackage == null) {
   1791             return;
   1792         }
   1793         if (pkg.requestedPermissions == null) {
   1794             return;
   1795         }
   1796         final PackageSetting disabledSysParentPs = mSettings
   1797                 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
   1798         if (disabledSysParentPs == null || disabledSysParentPs.pkg == null
   1799                 || !disabledSysParentPs.isPrivileged()
   1800                 || (disabledSysParentPs.childPackageNames != null
   1801                         && !disabledSysParentPs.childPackageNames.isEmpty())) {
   1802             return;
   1803         }
   1804         final int[] allUserIds = sUserManager.getUserIds();
   1805         final int permCount = pkg.requestedPermissions.size();
   1806         for (int i = 0; i < permCount; i++) {
   1807             String permission = pkg.requestedPermissions.get(i);
   1808             BasePermission bp = mSettings.mPermissions.get(permission);
   1809             if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
   1810                 continue;
   1811             }
   1812             for (int userId : allUserIds) {
   1813                 if (disabledSysParentPs.getPermissionsState().hasRuntimePermission(
   1814                         permission, userId)) {
   1815                     grantRuntimePermission(pkg.packageName, permission, userId);
   1816                 }
   1817             }
   1818         }
   1819     }
   1820 
   1821     private StorageEventListener mStorageListener = new StorageEventListener() {
   1822         @Override
   1823         public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
   1824             if (vol.type == VolumeInfo.TYPE_PRIVATE) {
   1825                 if (vol.state == VolumeInfo.STATE_MOUNTED) {
   1826                     final String volumeUuid = vol.getFsUuid();
   1827 
   1828                     // Clean up any users or apps that were removed or recreated
   1829                     // while this volume was missing
   1830                     reconcileUsers(volumeUuid);
   1831                     reconcileApps(volumeUuid);
   1832 
   1833                     // Clean up any install sessions that expired or were
   1834                     // cancelled while this volume was missing
   1835                     mInstallerService.onPrivateVolumeMounted(volumeUuid);
   1836 
   1837                     loadPrivatePackages(vol);
   1838 
   1839                 } else if (vol.state == VolumeInfo.STATE_EJECTING) {
   1840                     unloadPrivatePackages(vol);
   1841                 }
   1842             }
   1843 
   1844             if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) {
   1845                 if (vol.state == VolumeInfo.STATE_MOUNTED) {
   1846                     updateExternalMediaStatus(true, false);
   1847                 } else if (vol.state == VolumeInfo.STATE_EJECTING) {
   1848                     updateExternalMediaStatus(false, false);
   1849                 }
   1850             }
   1851         }
   1852 
   1853         @Override
   1854         public void onVolumeForgotten(String fsUuid) {
   1855             if (TextUtils.isEmpty(fsUuid)) {
   1856                 Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
   1857                 return;
   1858             }
   1859 
   1860             // Remove any apps installed on the forgotten volume
   1861             synchronized (mPackages) {
   1862                 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
   1863                 for (PackageSetting ps : packages) {
   1864                     Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
   1865                     deletePackage(ps.name, new LegacyPackageDeleteObserver(null).getBinder(),
   1866                             UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
   1867                 }
   1868 
   1869                 mSettings.onVolumeForgotten(fsUuid);
   1870                 mSettings.writeLPr();
   1871             }
   1872         }
   1873     };
   1874 
   1875     private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
   1876             String[] grantedPermissions) {
   1877         for (int userId : userIds) {
   1878             grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions);
   1879         }
   1880 
   1881         // We could have touched GID membership, so flush out packages.list
   1882         synchronized (mPackages) {
   1883             mSettings.writePackageListLPr();
   1884         }
   1885     }
   1886 
   1887     private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
   1888             String[] grantedPermissions) {
   1889         SettingBase sb = (SettingBase) pkg.mExtras;
   1890         if (sb == null) {
   1891             return;
   1892         }
   1893 
   1894         PermissionsState permissionsState = sb.getPermissionsState();
   1895 
   1896         final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
   1897                 | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
   1898 
   1899         for (String permission : pkg.requestedPermissions) {
   1900             final BasePermission bp;
   1901             synchronized (mPackages) {
   1902                 bp = mSettings.mPermissions.get(permission);
   1903             }
   1904             if (bp != null && (bp.isRuntime() || bp.isDevelopment())
   1905                     && (grantedPermissions == null
   1906                            || ArrayUtils.contains(grantedPermissions, permission))) {
   1907                 final int flags = permissionsState.getPermissionFlags(permission, userId);
   1908                 // Installer cannot change immutable permissions.
   1909                 if ((flags & immutableFlags) == 0) {
   1910                     grantRuntimePermission(pkg.packageName, permission, userId);
   1911                 }
   1912             }
   1913         }
   1914     }
   1915 
   1916     Bundle extrasForInstallResult(PackageInstalledInfo res) {
   1917         Bundle extras = null;
   1918         switch (res.returnCode) {
   1919             case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
   1920                 extras = new Bundle();
   1921                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
   1922                         res.origPermission);
   1923                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
   1924                         res.origPackage);
   1925                 break;
   1926             }
   1927             case PackageManager.INSTALL_SUCCEEDED: {
   1928                 extras = new Bundle();
   1929                 extras.putBoolean(Intent.EXTRA_REPLACING,
   1930                         res.removedInfo != null && res.removedInfo.removedPackage != null);
   1931                 break;
   1932             }
   1933         }
   1934         return extras;
   1935     }
   1936 
   1937     void scheduleWriteSettingsLocked() {
   1938         if (!mHandler.hasMessages(WRITE_SETTINGS)) {
   1939             mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
   1940         }
   1941     }
   1942 
   1943     void scheduleWritePackageListLocked(int userId) {
   1944         if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
   1945             Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
   1946             msg.arg1 = userId;
   1947             mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
   1948         }
   1949     }
   1950 
   1951     void scheduleWritePackageRestrictionsLocked(UserHandle user) {
   1952         final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
   1953         scheduleWritePackageRestrictionsLocked(userId);
   1954     }
   1955 
   1956     void scheduleWritePackageRestrictionsLocked(int userId) {
   1957         final int[] userIds = (userId == UserHandle.USER_ALL)
   1958                 ? sUserManager.getUserIds() : new int[]{userId};
   1959         for (int nextUserId : userIds) {
   1960             if (!sUserManager.exists(nextUserId)) return;
   1961             mDirtyUsers.add(nextUserId);
   1962             if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
   1963                 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
   1964             }
   1965         }
   1966     }
   1967 
   1968     public static PackageManagerService main(Context context, Installer installer,
   1969             boolean factoryTest, boolean onlyCore) {
   1970         // Self-check for initial settings.
   1971         PackageManagerServiceCompilerMapping.checkProperties();
   1972 
   1973         PackageManagerService m = new PackageManagerService(context, installer,
   1974                 factoryTest, onlyCore);
   1975         m.enableSystemUserPackages();
   1976         ServiceManager.addService("package", m);
   1977         return m;
   1978     }
   1979 
   1980     private void enableSystemUserPackages() {
   1981         if (!UserManager.isSplitSystemUser()) {
   1982             return;
   1983         }
   1984         // For system user, enable apps based on the following conditions:
   1985         // - app is whitelisted or belong to one of these groups:
   1986         //   -- system app which has no launcher icons
   1987         //   -- system app which has INTERACT_ACROSS_USERS permission
   1988         //   -- system IME app
   1989         // - app is not in the blacklist
   1990         AppsQueryHelper queryHelper = new AppsQueryHelper(this);
   1991         Set<String> enableApps = new ArraySet<>();
   1992         enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
   1993                 | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
   1994                 | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
   1995         ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
   1996         enableApps.addAll(wlApps);
   1997         enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
   1998                 /* systemAppsOnly */ false, UserHandle.SYSTEM));
   1999         ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
   2000         enableApps.removeAll(blApps);
   2001         Log.i(TAG, "Applications installed for system user: " + enableApps);
   2002         List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
   2003                 UserHandle.SYSTEM);
   2004         final int allAppsSize = allAps.size();
   2005         synchronized (mPackages) {
   2006             for (int i = 0; i < allAppsSize; i++) {
   2007                 String pName = allAps.get(i);
   2008                 PackageSetting pkgSetting = mSettings.mPackages.get(pName);
   2009                 // Should not happen, but we shouldn't be failing if it does
   2010                 if (pkgSetting == null) {
   2011                     continue;
   2012                 }
   2013                 boolean install = enableApps.contains(pName);
   2014                 if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
   2015                     Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
   2016                             + " for system user");
   2017                     pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
   2018                 }
   2019             }
   2020         }
   2021     }
   2022 
   2023     private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
   2024         DisplayManager displayManager = (DisplayManager) context.getSystemService(
   2025                 Context.DISPLAY_SERVICE);
   2026         displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
   2027     }
   2028 
   2029     /**
   2030      * Requests that files preopted on a secondary system partition be copied to the data partition
   2031      * if possible.  Note that the actual copying of the files is accomplished by init for security
   2032      * reasons. This simply requests that the copy takes place and awaits confirmation of its
   2033      * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
   2034      */
   2035     private static void requestCopyPreoptedFiles() {
   2036         final int WAIT_TIME_MS = 100;
   2037         final String CP_PREOPT_PROPERTY = "sys.cppreopt";
   2038         if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
   2039             SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
   2040             // We will wait for up to 100 seconds.
   2041             final long timeEnd = SystemClock.uptimeMillis() + 100 * 1000;
   2042             while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
   2043                 try {
   2044                     Thread.sleep(WAIT_TIME_MS);
   2045                 } catch (InterruptedException e) {
   2046                     // Do nothing
   2047                 }
   2048                 if (SystemClock.uptimeMillis() > timeEnd) {
   2049                     SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
   2050                     Slog.wtf(TAG, "cppreopt did not finish!");
   2051                     break;
   2052                 }
   2053             }
   2054         }
   2055     }
   2056 
   2057     public PackageManagerService(Context context, Installer installer,
   2058             boolean factoryTest, boolean onlyCore) {
   2059         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
   2060                 SystemClock.uptimeMillis());
   2061 
   2062         if (mSdkVersion <= 0) {
   2063             Slog.w(TAG, "**** ro.build.version.sdk not set!");
   2064         }
   2065 
   2066         mContext = context;
   2067         mFactoryTest = factoryTest;
   2068         mOnlyCore = onlyCore;
   2069         mMetrics = new DisplayMetrics();
   2070         mSettings = new Settings(mPackages);
   2071         mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
   2072                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
   2073         mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
   2074                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
   2075         mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
   2076                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
   2077         mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
   2078                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
   2079         mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
   2080                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
   2081         mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
   2082                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
   2083 
   2084         String separateProcesses = SystemProperties.get("debug.separate_processes");
   2085         if (separateProcesses != null && separateProcesses.length() > 0) {
   2086             if ("*".equals(separateProcesses)) {
   2087                 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
   2088                 mSeparateProcesses = null;
   2089                 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
   2090             } else {
   2091                 mDefParseFlags = 0;
   2092                 mSeparateProcesses = separateProcesses.split(",");
   2093                 Slog.w(TAG, "Running with debug.separate_processes: "
   2094                         + separateProcesses);
   2095             }
   2096         } else {
   2097             mDefParseFlags = 0;
   2098             mSeparateProcesses = null;
   2099         }
   2100 
   2101         mInstaller = installer;
   2102         mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
   2103                 "*dexopt*");
   2104         mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
   2105 
   2106         mOnPermissionChangeListeners = new OnPermissionChangeListeners(
   2107                 FgThread.get().getLooper());
   2108 
   2109         getDefaultDisplayMetrics(context, mMetrics);
   2110 
   2111         SystemConfig systemConfig = SystemConfig.getInstance();
   2112         mGlobalGids = systemConfig.getGlobalGids();
   2113         mSystemPermissions = systemConfig.getSystemPermissions();
   2114         mAvailableFeatures = systemConfig.getAvailableFeatures();
   2115 
   2116         mProtectedPackages = new ProtectedPackages(mContext);
   2117 
   2118         synchronized (mInstallLock) {
   2119         // writer
   2120         synchronized (mPackages) {
   2121             mHandlerThread = new ServiceThread(TAG,
   2122                     Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
   2123             mHandlerThread.start();
   2124             mHandler = new PackageHandler(mHandlerThread.getLooper());
   2125             mProcessLoggingHandler = new ProcessLoggingHandler();
   2126             Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
   2127 
   2128             mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this);
   2129 
   2130             File dataDir = Environment.getDataDirectory();
   2131             mAppInstallDir = new File(dataDir, "app");
   2132             mAppLib32InstallDir = new File(dataDir, "app-lib");
   2133             mEphemeralInstallDir = new File(dataDir, "app-ephemeral");
   2134             mAsecInternalPath = new File(dataDir, "app-asec").getPath();
   2135             mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
   2136 
   2137             sUserManager = new UserManagerService(context, this, mPackages);
   2138 
   2139             // Propagate permission configuration in to package manager.
   2140             ArrayMap<String, SystemConfig.PermissionEntry> permConfig
   2141                     = systemConfig.getPermissions();
   2142             for (int i=0; i<permConfig.size(); i++) {
   2143                 SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
   2144                 BasePermission bp = mSettings.mPermissions.get(perm.name);
   2145                 if (bp == null) {
   2146                     bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
   2147                     mSettings.mPermissions.put(perm.name, bp);
   2148                 }
   2149                 if (perm.gids != null) {
   2150                     bp.setGids(perm.gids, perm.perUser);
   2151                 }
   2152             }
   2153 
   2154             ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
   2155             for (int i=0; i<libConfig.size(); i++) {
   2156                 mSharedLibraries.put(libConfig.keyAt(i),
   2157                         new SharedLibraryEntry(libConfig.valueAt(i), null));
   2158             }
   2159 
   2160             mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
   2161 
   2162             mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
   2163 
   2164             // Clean up orphaned packages for which the code path doesn't exist
   2165             // and they are an update to a system app - caused by bug/32321269
   2166             final int packageSettingCount = mSettings.mPackages.size();
   2167             for (int i = packageSettingCount - 1; i >= 0; i--) {
   2168                 PackageSetting ps = mSettings.mPackages.valueAt(i);
   2169                 if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
   2170                         && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
   2171                     mSettings.mPackages.removeAt(i);
   2172                     mSettings.enableSystemPackageLPw(ps.name);
   2173                 }
   2174             }
   2175 
   2176             if (mFirstBoot) {
   2177                 requestCopyPreoptedFiles();
   2178             }
   2179 
   2180             String customResolverActivity = Resources.getSystem().getString(
   2181                     R.string.config_customResolverActivity);
   2182             if (TextUtils.isEmpty(customResolverActivity)) {
   2183                 customResolverActivity = null;
   2184             } else {
   2185                 mCustomResolverComponentName = ComponentName.unflattenFromString(
   2186                         customResolverActivity);
   2187             }
   2188 
   2189             long startTime = SystemClock.uptimeMillis();
   2190 
   2191             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
   2192                     startTime);
   2193 
   2194             // Set flag to monitor and not change apk file paths when
   2195             // scanning install directories.
   2196             final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING | SCAN_INITIAL;
   2197 
   2198             final String bootClassPath = System.getenv("BOOTCLASSPATH");
   2199             final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
   2200 
   2201             if (bootClassPath == null) {
   2202                 Slog.w(TAG, "No BOOTCLASSPATH found!");
   2203             }
   2204 
   2205             if (systemServerClassPath == null) {
   2206                 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
   2207             }
   2208 
   2209             final List<String> allInstructionSets = InstructionSets.getAllInstructionSets();
   2210             final String[] dexCodeInstructionSets =
   2211                     getDexCodeInstructionSets(
   2212                             allInstructionSets.toArray(new String[allInstructionSets.size()]));
   2213 
   2214             /**
   2215              * Ensure all external libraries have had dexopt run on them.
   2216              */
   2217             if (mSharedLibraries.size() > 0) {
   2218                 // NOTE: For now, we're compiling these system "shared libraries"
   2219                 // (and framework jars) into all available architectures. It's possible
   2220                 // to compile them only when we come across an app that uses them (there's
   2221                 // already logic for that in scanPackageLI) but that adds some complexity.
   2222                 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
   2223                     for (SharedLibraryEntry libEntry : mSharedLibraries.values()) {
   2224                         final String lib = libEntry.path;
   2225                         if (lib == null) {
   2226                             continue;
   2227                         }
   2228 
   2229                         try {
   2230                             // Shared libraries do not have profiles so we perform a full
   2231                             // AOT compilation (if needed).
   2232                             int dexoptNeeded = DexFile.getDexOptNeeded(
   2233                                     lib, dexCodeInstructionSet,
   2234                                     getCompilerFilterForReason(REASON_SHARED_APK),
   2235                                     false /* newProfile */);
   2236                             if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
   2237                                 mInstaller.dexopt(lib, Process.SYSTEM_UID, dexCodeInstructionSet,
   2238                                         dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/,
   2239                                         getCompilerFilterForReason(REASON_SHARED_APK),
   2240                                         StorageManager.UUID_PRIVATE_INTERNAL,
   2241                                         SKIP_SHARED_LIBRARY_CHECK);
   2242                             }
   2243                         } catch (FileNotFoundException e) {
   2244                             Slog.w(TAG, "Library not found: " + lib);
   2245                         } catch (IOException | InstallerException e) {
   2246                             Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
   2247                                     + e.getMessage());
   2248                         }
   2249                     }
   2250                 }
   2251             }
   2252 
   2253             File frameworkDir = new File(Environment.getRootDirectory(), "framework");
   2254 
   2255             final VersionInfo ver = mSettings.getInternalVersion();
   2256             mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
   2257 
   2258             // when upgrading from pre-M, promote system app permissions from install to runtime
   2259             mPromoteSystemApps =
   2260                     mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
   2261 
   2262             // When upgrading from pre-N, we need to handle package extraction like first boot,
   2263             // as there is no profiling data available.
   2264             mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
   2265 
   2266             mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
   2267 
   2268             // save off the names of pre-existing system packages prior to scanning; we don't
   2269             // want to automatically grant runtime permissions for new system apps
   2270             if (mPromoteSystemApps) {
   2271                 Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
   2272                 while (pkgSettingIter.hasNext()) {
   2273                     PackageSetting ps = pkgSettingIter.next();
   2274                     if (isSystemApp(ps)) {
   2275                         mExistingSystemPackages.add(ps.name);
   2276                     }
   2277                 }
   2278             }
   2279 
   2280             // Collect vendor overlay packages.
   2281             // (Do this before scanning any apps.)
   2282             // For security and version matching reason, only consider
   2283             // overlay packages if they reside in VENDOR_OVERLAY_DIR.
   2284             File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR);
   2285             scanDirTracedLI(vendorOverlayDir, mDefParseFlags
   2286                     | PackageParser.PARSE_IS_SYSTEM
   2287                     | PackageParser.PARSE_IS_SYSTEM_DIR
   2288                     | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
   2289 
   2290             // Find base frameworks (resource packages without code).
   2291             scanDirTracedLI(frameworkDir, mDefParseFlags
   2292                     | PackageParser.PARSE_IS_SYSTEM
   2293                     | PackageParser.PARSE_IS_SYSTEM_DIR
   2294                     | PackageParser.PARSE_IS_PRIVILEGED,
   2295                     scanFlags | SCAN_NO_DEX, 0);
   2296 
   2297             // Collected privileged system packages.
   2298             final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
   2299             scanDirTracedLI(privilegedAppDir, mDefParseFlags
   2300                     | PackageParser.PARSE_IS_SYSTEM
   2301                     | PackageParser.PARSE_IS_SYSTEM_DIR
   2302                     | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
   2303 
   2304             // Collect ordinary system packages.
   2305             final File systemAppDir = new File(Environment.getRootDirectory(), "app");
   2306             scanDirTracedLI(systemAppDir, mDefParseFlags
   2307                     | PackageParser.PARSE_IS_SYSTEM
   2308                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
   2309 
   2310             // Collect all vendor packages.
   2311             File vendorAppDir = new File("/vendor/app");
   2312             try {
   2313                 vendorAppDir = vendorAppDir.getCanonicalFile();
   2314             } catch (IOException e) {
   2315                 // failed to look up canonical path, continue with original one
   2316             }
   2317             scanDirTracedLI(vendorAppDir, mDefParseFlags
   2318                     | PackageParser.PARSE_IS_SYSTEM
   2319                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
   2320 
   2321             // Collect all OEM packages.
   2322             final File oemAppDir = new File(Environment.getOemDirectory(), "app");
   2323             scanDirTracedLI(oemAppDir, mDefParseFlags
   2324                     | PackageParser.PARSE_IS_SYSTEM
   2325                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
   2326 
   2327             // Prune any system packages that no longer exist.
   2328             final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
   2329             if (!mOnlyCore) {
   2330                 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
   2331                 while (psit.hasNext()) {
   2332                     PackageSetting ps = psit.next();
   2333 
   2334                     /*
   2335                      * If this is not a system app, it can't be a
   2336                      * disable system app.
   2337                      */
   2338                     if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
   2339                         continue;
   2340                     }
   2341 
   2342                     /*
   2343                      * If the package is scanned, it's not erased.
   2344                      */
   2345                     final PackageParser.Package scannedPkg = mPackages.get(ps.name);
   2346                     if (scannedPkg != null) {
   2347                         /*
   2348                          * If the system app is both scanned and in the
   2349                          * disabled packages list, then it must have been
   2350                          * added via OTA. Remove it from the currently
   2351                          * scanned package so the previously user-installed
   2352                          * application can be scanned.
   2353                          */
   2354                         if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
   2355                             logCriticalInfo(Log.WARN, "Expecting better updated system app for "
   2356                                     + ps.name + "; removing system app.  Last known codePath="
   2357                                     + ps.codePathString + ", installStatus=" + ps.installStatus
   2358                                     + ", versionCode=" + ps.versionCode + "; scanned versionCode="
   2359                                     + scannedPkg.mVersionCode);
   2360                             removePackageLI(scannedPkg, true);
   2361                             mExpectingBetter.put(ps.name, ps.codePath);
   2362                         }
   2363 
   2364                         continue;
   2365                     }
   2366 
   2367                     if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
   2368                         psit.remove();
   2369                         logCriticalInfo(Log.WARN, "System package " + ps.name
   2370                                 + " no longer exists; it's data will be wiped");
   2371                         // Actual deletion of code and data will be handled by later
   2372                         // reconciliation step
   2373                     } else {
   2374                         final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
   2375                         if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
   2376                             possiblyDeletedUpdatedSystemApps.add(ps.name);
   2377                         }
   2378                     }
   2379                 }
   2380             }
   2381 
   2382             //look for any incomplete package installations
   2383             ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
   2384             for (int i = 0; i < deletePkgsList.size(); i++) {
   2385                 // Actual deletion of code and data will be handled by later
   2386                 // reconciliation step
   2387                 final String packageName = deletePkgsList.get(i).name;
   2388                 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
   2389                 synchronized (mPackages) {
   2390                     mSettings.removePackageLPw(packageName);
   2391                 }
   2392             }
   2393 
   2394             //delete tmp files
   2395             deleteTempPackageFiles();
   2396 
   2397             // Remove any shared userIDs that have no associated packages
   2398             mSettings.pruneSharedUsersLPw();
   2399 
   2400             if (!mOnlyCore) {
   2401                 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
   2402                         SystemClock.uptimeMillis());
   2403                 scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
   2404 
   2405                 scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
   2406                         | PackageParser.PARSE_FORWARD_LOCK,
   2407                         scanFlags | SCAN_REQUIRE_KNOWN, 0);
   2408 
   2409                 scanDirLI(mEphemeralInstallDir, mDefParseFlags
   2410                         | PackageParser.PARSE_IS_EPHEMERAL,
   2411                         scanFlags | SCAN_REQUIRE_KNOWN, 0);
   2412 
   2413                 /**
   2414                  * Remove disable package settings for any updated system
   2415                  * apps that were removed via an OTA. If they're not a
   2416                  * previously-updated app, remove them completely.
   2417                  * Otherwise, just revoke their system-level permissions.
   2418                  */
   2419                 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
   2420                     PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
   2421                     mSettings.removeDisabledSystemPackageLPw(deletedAppName);
   2422 
   2423                     String msg;
   2424                     if (deletedPkg == null) {
   2425                         msg = "Updated system package " + deletedAppName
   2426                                 + " no longer exists; it's data will be wiped";
   2427                         // Actual deletion of code and data will be handled by later
   2428                         // reconciliation step
   2429                     } else {
   2430                         msg = "Updated system app + " + deletedAppName
   2431                                 + " no longer present; removing system privileges for "
   2432                                 + deletedAppName;
   2433 
   2434                         deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
   2435 
   2436                         PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
   2437                         deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
   2438                     }
   2439                     logCriticalInfo(Log.WARN, msg);
   2440                 }
   2441 
   2442                 /**
   2443                  * Make sure all system apps that we expected to appear on
   2444                  * the userdata partition actually showed up. If they never
   2445                  * appeared, crawl back and revive the system version.
   2446                  */
   2447                 for (int i = 0; i < mExpectingBetter.size(); i++) {
   2448                     final String packageName = mExpectingBetter.keyAt(i);
   2449                     if (!mPackages.containsKey(packageName)) {
   2450                         final File scanFile = mExpectingBetter.valueAt(i);
   2451 
   2452                         logCriticalInfo(Log.WARN, "Expected better " + packageName
   2453                                 + " but never showed up; reverting to system");
   2454 
   2455                         int reparseFlags = mDefParseFlags;
   2456                         if (FileUtils.contains(privilegedAppDir, scanFile)) {
   2457                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
   2458                                     | PackageParser.PARSE_IS_SYSTEM_DIR
   2459                                     | PackageParser.PARSE_IS_PRIVILEGED;
   2460                         } else if (FileUtils.contains(systemAppDir, scanFile)) {
   2461                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
   2462                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
   2463                         } else if (FileUtils.contains(vendorAppDir, scanFile)) {
   2464                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
   2465                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
   2466                         } else if (FileUtils.contains(oemAppDir, scanFile)) {
   2467                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
   2468                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
   2469                         } else {
   2470                             Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
   2471                             continue;
   2472                         }
   2473 
   2474                         mSettings.enableSystemPackageLPw(packageName);
   2475 
   2476                         try {
   2477                             scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
   2478                         } catch (PackageManagerException e) {
   2479                             Slog.e(TAG, "Failed to parse original system package: "
   2480                                     + e.getMessage());
   2481                         }
   2482                     }
   2483                 }
   2484             }
   2485             mExpectingBetter.clear();
   2486 
   2487             // Resolve the storage manager.
   2488             mStorageManagerPackage = getStorageManagerPackageName();
   2489 
   2490             // Resolve protected action filters. Only the setup wizard is allowed to
   2491             // have a high priority filter for these actions.
   2492             mSetupWizardPackage = getSetupWizardPackageName();
   2493             if (mProtectedFilters.size() > 0) {
   2494                 if (DEBUG_FILTERS && mSetupWizardPackage == null) {
   2495                     Slog.i(TAG, "No setup wizard;"
   2496                         + " All protected intents capped to priority 0");
   2497                 }
   2498                 for (ActivityIntentInfo filter : mProtectedFilters) {
   2499                     if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
   2500                         if (DEBUG_FILTERS) {
   2501                             Slog.i(TAG, "Found setup wizard;"
   2502                                 + " allow priority " + filter.getPriority() + ";"
   2503                                 + " package: " + filter.activity.info.packageName
   2504                                 + " activity: " + filter.activity.className
   2505                                 + " priority: " + filter.getPriority());
   2506                         }
   2507                         // skip setup wizard; allow it to keep the high priority filter
   2508                         continue;
   2509                     }
   2510                     Slog.w(TAG, "Protected action; cap priority to 0;"
   2511                             + " package: " + filter.activity.info.packageName
   2512                             + " activity: " + filter.activity.className
   2513                             + " origPrio: " + filter.getPriority());
   2514                     filter.setPriority(0);
   2515                 }
   2516             }
   2517             mDeferProtectedFilters = false;
   2518             mProtectedFilters.clear();
   2519 
   2520             // Now that we know all of the shared libraries, update all clients to have
   2521             // the correct library paths.
   2522             updateAllSharedLibrariesLPw();
   2523 
   2524             for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
   2525                 // NOTE: We ignore potential failures here during a system scan (like
   2526                 // the rest of the commands above) because there's precious little we
   2527                 // can do about it. A settings error is reported, though.
   2528                 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */,
   2529                         false /* boot complete */);
   2530             }
   2531 
   2532             // Now that we know all the packages we are keeping,
   2533             // read and update their last usage times.
   2534             mPackageUsage.read(mPackages);
   2535             mCompilerStats.read();
   2536 
   2537             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
   2538                     SystemClock.uptimeMillis());
   2539             Slog.i(TAG, "Time to scan packages: "
   2540                     + ((SystemClock.uptimeMillis()-startTime)/1000f)
   2541                     + " seconds");
   2542 
   2543             // If the platform SDK has changed since the last time we booted,
   2544             // we need to re-grant app permission to catch any new ones that
   2545             // appear.  This is really a hack, and means that apps can in some
   2546             // cases get permissions that the user didn't initially explicitly
   2547             // allow...  it would be nice to have some better way to handle
   2548             // this situation.
   2549             int updateFlags = UPDATE_PERMISSIONS_ALL;
   2550             if (ver.sdkVersion != mSdkVersion) {
   2551                 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
   2552                         + mSdkVersion + "; regranting permissions for internal storage");
   2553                 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
   2554             }
   2555             updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
   2556             ver.sdkVersion = mSdkVersion;
   2557 
   2558             // If this is the first boot or an update from pre-M, and it is a normal
   2559             // boot, then we need to initialize the default preferred apps across
   2560             // all defined users.
   2561             if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
   2562                 for (UserInfo user : sUserManager.getUsers(true)) {
   2563                     mSettings.applyDefaultPreferredAppsLPw(this, user.id);
   2564                     applyFactoryDefaultBrowserLPw(user.id);
   2565                     primeDomainVerificationsLPw(user.id);
   2566                 }
   2567             }
   2568 
   2569             // Prepare storage for system user really early during boot,
   2570             // since core system apps like SettingsProvider and SystemUI
   2571             // can't wait for user to start
   2572             final int storageFlags;
   2573             if (StorageManager.isFileEncryptedNativeOrEmulated()) {
   2574                 storageFlags = StorageManager.FLAG_STORAGE_DE;
   2575             } else {
   2576                 storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
   2577             }
   2578             reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM,
   2579                     storageFlags);
   2580 
   2581             // If this is first boot after an OTA, and a normal boot, then
   2582             // we need to clear code cache directories.
   2583             // Note that we do *not* clear the application profiles. These remain valid
   2584             // across OTAs and are used to drive profile verification (post OTA) and
   2585             // profile compilation (without waiting to collect a fresh set of profiles).
   2586             if (mIsUpgrade && !onlyCore) {
   2587                 Slog.i(TAG, "Build fingerprint changed; clearing code caches");
   2588                 for (int i = 0; i < mSettings.mPackages.size(); i++) {
   2589                     final PackageSetting ps = mSettings.mPackages.valueAt(i);
   2590                     if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
   2591                         // No apps are running this early, so no need to freeze
   2592                         clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
   2593                                 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
   2594                                         | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
   2595                     }
   2596                 }
   2597                 ver.fingerprint = Build.FINGERPRINT;
   2598             }
   2599 
   2600             checkDefaultBrowser();
   2601 
   2602             // clear only after permissions and other defaults have been updated
   2603             mExistingSystemPackages.clear();
   2604             mPromoteSystemApps = false;
   2605 
   2606             // All the changes are done during package scanning.
   2607             ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
   2608 
   2609             // can downgrade to reader
   2610             mSettings.writeLPr();
   2611 
   2612             // Perform dexopt on all apps that mark themselves as coreApps. We do this pretty
   2613             // early on (before the package manager declares itself as early) because other
   2614             // components in the system server might ask for package contexts for these apps.
   2615             //
   2616             // Note that "onlyCore" in this context means the system is encrypted or encrypting
   2617             // (i.e, that the data partition is unavailable).
   2618             if ((isFirstBoot() || isUpgrade() || VMRuntime.didPruneDalvikCache()) && !onlyCore) {
   2619                 long start = System.nanoTime();
   2620                 List<PackageParser.Package> coreApps = new ArrayList<>();
   2621                 for (PackageParser.Package pkg : mPackages.values()) {
   2622                     if (pkg.coreApp) {
   2623                         coreApps.add(pkg);
   2624                     }
   2625                 }
   2626 
   2627                 int[] stats = performDexOptUpgrade(coreApps, false,
   2628                         getCompilerFilterForReason(REASON_CORE_APP));
   2629 
   2630                 final int elapsedTimeSeconds =
   2631                         (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start);
   2632                 MetricsLogger.histogram(mContext, "opt_coreapps_time_s", elapsedTimeSeconds);
   2633 
   2634                 if (DEBUG_DEXOPT) {
   2635                     Slog.i(TAG, "Dex-opt core apps took : " + elapsedTimeSeconds + " seconds (" +
   2636                             stats[0] + ", " + stats[1] + ", " + stats[2] + ")");
   2637                 }
   2638 
   2639 
   2640                 // TODO: Should we log these stats to tron too ?
   2641                 // MetricsLogger.histogram(mContext, "opt_coreapps_num_dexopted", stats[0]);
   2642                 // MetricsLogger.histogram(mContext, "opt_coreapps_num_skipped", stats[1]);
   2643                 // MetricsLogger.histogram(mContext, "opt_coreapps_num_failed", stats[2]);
   2644                 // MetricsLogger.histogram(mContext, "opt_coreapps_num_total", coreApps.size());
   2645             }
   2646 
   2647             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
   2648                     SystemClock.uptimeMillis());
   2649 
   2650             if (!mOnlyCore) {
   2651                 mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
   2652                 mRequiredInstallerPackage = getRequiredInstallerLPr();
   2653                 mRequiredUninstallerPackage = getRequiredUninstallerLPr();
   2654                 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
   2655                 mIntentFilterVerifier = new IntentVerifierProxy(mContext,
   2656                         mIntentFilterVerifierComponent);
   2657                 mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
   2658                         PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES);
   2659                 mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
   2660                         PackageManager.SYSTEM_SHARED_LIBRARY_SHARED);
   2661             } else {
   2662                 mRequiredVerifierPackage = null;
   2663                 mRequiredInstallerPackage = null;
   2664                 mRequiredUninstallerPackage = null;
   2665                 mIntentFilterVerifierComponent = null;
   2666                 mIntentFilterVerifier = null;
   2667                 mServicesSystemSharedLibraryPackageName = null;
   2668                 mSharedSystemSharedLibraryPackageName = null;
   2669             }
   2670 
   2671             mInstallerService = new PackageInstallerService(context, this);
   2672 
   2673             final ComponentName ephemeralResolverComponent = getEphemeralResolverLPr();
   2674             final ComponentName ephemeralInstallerComponent = getEphemeralInstallerLPr();
   2675             // both the installer and resolver must be present to enable ephemeral
   2676             if (ephemeralInstallerComponent != null && ephemeralResolverComponent != null) {
   2677                 if (DEBUG_EPHEMERAL) {
   2678                     Slog.i(TAG, "Ephemeral activated; resolver: " + ephemeralResolverComponent
   2679                             + " installer:" + ephemeralInstallerComponent);
   2680                 }
   2681                 mEphemeralResolverComponent = ephemeralResolverComponent;
   2682                 mEphemeralInstallerComponent = ephemeralInstallerComponent;
   2683                 setUpEphemeralInstallerActivityLP(mEphemeralInstallerComponent);
   2684                 mEphemeralResolverConnection =
   2685                         new EphemeralResolverConnection(mContext, mEphemeralResolverComponent);
   2686             } else {
   2687                 if (DEBUG_EPHEMERAL) {
   2688                     final String missingComponent =
   2689                             (ephemeralResolverComponent == null)
   2690                             ? (ephemeralInstallerComponent == null)
   2691                                     ? "resolver and installer"
   2692                                     : "resolver"
   2693                             : "installer";
   2694                     Slog.i(TAG, "Ephemeral deactivated; missing " + missingComponent);
   2695                 }
   2696                 mEphemeralResolverComponent = null;
   2697                 mEphemeralInstallerComponent = null;
   2698                 mEphemeralResolverConnection = null;
   2699             }
   2700 
   2701             mEphemeralApplicationRegistry = new EphemeralApplicationRegistry(this);
   2702         } // synchronized (mPackages)
   2703         } // synchronized (mInstallLock)
   2704 
   2705         // Now after opening every single application zip, make sure they
   2706         // are all flushed.  Not really needed, but keeps things nice and
   2707         // tidy.
   2708         Runtime.getRuntime().gc();
   2709 
   2710         // The initial scanning above does many calls into installd while
   2711         // holding the mPackages lock, but we're mostly interested in yelling
   2712         // once we have a booted system.
   2713         mInstaller.setWarnIfHeld(mPackages);
   2714 
   2715         // Expose private service for system components to use.
   2716         LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
   2717     }
   2718 
   2719     @Override
   2720     public boolean isFirstBoot() {
   2721         return mFirstBoot;
   2722     }
   2723 
   2724     @Override
   2725     public boolean isOnlyCoreApps() {
   2726         return mOnlyCore;
   2727     }
   2728 
   2729     @Override
   2730     public boolean isUpgrade() {
   2731         return mIsUpgrade;
   2732     }
   2733 
   2734     private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
   2735         final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
   2736 
   2737         final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
   2738                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
   2739                 UserHandle.USER_SYSTEM);
   2740         if (matches.size() == 1) {
   2741             return matches.get(0).getComponentInfo().packageName;
   2742         } else if (matches.size() == 0) {
   2743             Log.e(TAG, "There should probably be a verifier, but, none were found");
   2744             return null;
   2745         }
   2746         throw new RuntimeException("There must be exactly one verifier; found " + matches);
   2747     }
   2748 
   2749     private @NonNull String getRequiredSharedLibraryLPr(String libraryName) {
   2750         synchronized (mPackages) {
   2751             SharedLibraryEntry libraryEntry = mSharedLibraries.get(libraryName);
   2752             if (libraryEntry == null) {
   2753                 throw new IllegalStateException("Missing required shared library:" + libraryName);
   2754             }
   2755             return libraryEntry.apk;
   2756         }
   2757     }
   2758 
   2759     private @NonNull String getRequiredInstallerLPr() {
   2760         final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
   2761         intent.addCategory(Intent.CATEGORY_DEFAULT);
   2762         intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
   2763 
   2764         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
   2765                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
   2766                 UserHandle.USER_SYSTEM);
   2767         if (matches.size() == 1) {
   2768             ResolveInfo resolveInfo = matches.get(0);
   2769             if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
   2770                 throw new RuntimeException("The installer must be a privileged app");
   2771             }
   2772             return matches.get(0).getComponentInfo().packageName;
   2773         } else {
   2774             throw new RuntimeException("There must be exactly one installer; found " + matches);
   2775         }
   2776     }
   2777 
   2778     private @NonNull String getRequiredUninstallerLPr() {
   2779         final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
   2780         intent.addCategory(Intent.CATEGORY_DEFAULT);
   2781         intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
   2782 
   2783         final ResolveInfo resolveInfo = resolveIntent(intent, null,
   2784                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
   2785                 UserHandle.USER_SYSTEM);
   2786         if (resolveInfo == null ||
   2787                 mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
   2788             throw new RuntimeException("There must be exactly one uninstaller; found "
   2789                     + resolveInfo);
   2790         }
   2791         return resolveInfo.getComponentInfo().packageName;
   2792     }
   2793 
   2794     private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
   2795         final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
   2796 
   2797         final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
   2798                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
   2799                 UserHandle.USER_SYSTEM);
   2800         ResolveInfo best = null;
   2801         final int N = matches.size();
   2802         for (int i = 0; i < N; i++) {
   2803             final ResolveInfo cur = matches.get(i);
   2804             final String packageName = cur.getComponentInfo().packageName;
   2805             if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
   2806                     packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
   2807                 continue;
   2808             }
   2809 
   2810             if (best == null || cur.priority > best.priority) {
   2811                 best = cur;
   2812             }
   2813         }
   2814 
   2815         if (best != null) {
   2816             return best.getComponentInfo().getComponentName();
   2817         } else {
   2818             throw new RuntimeException("There must be at least one intent filter verifier");
   2819         }
   2820     }
   2821 
   2822     private @Nullable ComponentName getEphemeralResolverLPr() {
   2823         final String[] packageArray =
   2824                 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
   2825         if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
   2826             if (DEBUG_EPHEMERAL) {
   2827                 Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
   2828             }
   2829             return null;
   2830         }
   2831 
   2832         final int resolveFlags =
   2833                 MATCH_DIRECT_BOOT_AWARE
   2834                 | MATCH_DIRECT_BOOT_UNAWARE
   2835                 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
   2836         final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE);
   2837         final List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
   2838                 resolveFlags, UserHandle.USER_SYSTEM);
   2839 
   2840         final int N = resolvers.size();
   2841         if (N == 0) {
   2842             if (DEBUG_EPHEMERAL) {
   2843                 Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
   2844             }
   2845             return null;
   2846         }
   2847 
   2848         final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
   2849         for (int i = 0; i < N; i++) {
   2850             final ResolveInfo info = resolvers.get(i);
   2851 
   2852             if (info.serviceInfo == null) {
   2853                 continue;
   2854             }
   2855 
   2856             final String packageName = info.serviceInfo.packageName;
   2857             if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
   2858                 if (DEBUG_EPHEMERAL) {
   2859                     Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
   2860                             + " pkg: " + packageName + ", info:" + info);
   2861                 }
   2862                 continue;
   2863             }
   2864 
   2865             if (DEBUG_EPHEMERAL) {
   2866                 Slog.v(TAG, "Ephemeral resolver found;"
   2867                         + " pkg: " + packageName + ", info:" + info);
   2868             }
   2869             return new ComponentName(packageName, info.serviceInfo.name);
   2870         }
   2871         if (DEBUG_EPHEMERAL) {
   2872             Slog.v(TAG, "Ephemeral resolver NOT found");
   2873         }
   2874         return null;
   2875     }
   2876 
   2877     private @Nullable ComponentName getEphemeralInstallerLPr() {
   2878         final Intent intent = new Intent(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
   2879         intent.addCategory(Intent.CATEGORY_DEFAULT);
   2880         intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
   2881 
   2882         final int resolveFlags =
   2883                 MATCH_DIRECT_BOOT_AWARE
   2884                 | MATCH_DIRECT_BOOT_UNAWARE
   2885                 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
   2886         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
   2887                 resolveFlags, UserHandle.USER_SYSTEM);
   2888         if (matches.size() == 0) {
   2889             return null;
   2890         } else if (matches.size() == 1) {
   2891             return matches.get(0).getComponentInfo().getComponentName();
   2892         } else {
   2893             throw new RuntimeException(
   2894                     "There must be at most one ephemeral installer; found " + matches);
   2895         }
   2896     }
   2897 
   2898     private void primeDomainVerificationsLPw(int userId) {
   2899         if (DEBUG_DOMAIN_VERIFICATION) {
   2900             Slog.d(TAG, "Priming domain verifications in user " + userId);
   2901         }
   2902 
   2903         SystemConfig systemConfig = SystemConfig.getInstance();
   2904         ArraySet<String> packages = systemConfig.getLinkedApps();
   2905         ArraySet<String> domains = new ArraySet<String>();
   2906 
   2907         for (String packageName : packages) {
   2908             PackageParser.Package pkg = mPackages.get(packageName);
   2909             if (pkg != null) {
   2910                 if (!pkg.isSystemApp()) {
   2911                     Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
   2912                     continue;
   2913                 }
   2914 
   2915                 domains.clear();
   2916                 for (PackageParser.Activity a : pkg.activities) {
   2917                     for (ActivityIntentInfo filter : a.intents) {
   2918                         if (hasValidDomains(filter)) {
   2919                             domains.addAll(filter.getHostsList());
   2920                         }
   2921                     }
   2922                 }
   2923 
   2924                 if (domains.size() > 0) {
   2925                     if (DEBUG_DOMAIN_VERIFICATION) {
   2926                         Slog.v(TAG, "      + " + packageName);
   2927                     }
   2928                     // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
   2929                     // state w.r.t. the formal app-linkage "no verification attempted" state;
   2930                     // and then 'always' in the per-user state actually used for intent resolution.
   2931                     final IntentFilterVerificationInfo ivi;
   2932                     ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName,
   2933                             new ArrayList<String>(domains));
   2934                     ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
   2935                     mSettings.updateIntentFilterVerificationStatusLPw(packageName,
   2936                             INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
   2937                 } else {
   2938                     Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
   2939                             + "' does not handle web links");
   2940                 }
   2941             } else {
   2942                 Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
   2943             }
   2944         }
   2945 
   2946         scheduleWritePackageRestrictionsLocked(userId);
   2947         scheduleWriteSettingsLocked();
   2948     }
   2949 
   2950     private void applyFactoryDefaultBrowserLPw(int userId) {
   2951         // The default browser app's package name is stored in a string resource,
   2952         // with a product-specific overlay used for vendor customization.
   2953         String browserPkg = mContext.getResources().getString(
   2954                 com.android.internal.R.string.default_browser);
   2955         if (!TextUtils.isEmpty(browserPkg)) {
   2956             // non-empty string => required to be a known package
   2957             PackageSetting ps = mSettings.mPackages.get(browserPkg);
   2958             if (ps == null) {
   2959                 Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
   2960                 browserPkg = null;
   2961             } else {
   2962                 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
   2963             }
   2964         }
   2965 
   2966         // Nothing valid explicitly set? Make the factory-installed browser the explicit
   2967         // default.  If there's more than one, just leave everything alone.
   2968         if (browserPkg == null) {
   2969             calculateDefaultBrowserLPw(userId);
   2970         }
   2971     }
   2972 
   2973     private void calculateDefaultBrowserLPw(int userId) {
   2974         List<String> allBrowsers = resolveAllBrowserApps(userId);
   2975         final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
   2976         mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
   2977     }
   2978 
   2979     private List<String> resolveAllBrowserApps(int userId) {
   2980         // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
   2981         List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
   2982                 PackageManager.MATCH_ALL, userId);
   2983 
   2984         final int count = list.size();
   2985         List<String> result = new ArrayList<String>(count);
   2986         for (int i=0; i<count; i++) {
   2987             ResolveInfo info = list.get(i);
   2988             if (info.activityInfo == null
   2989                     || !info.handleAllWebDataURI
   2990                     || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
   2991                     || result.contains(info.activityInfo.packageName)) {
   2992                 continue;
   2993             }
   2994             result.add(info.activityInfo.packageName);
   2995         }
   2996 
   2997         return result;
   2998     }
   2999 
   3000     private boolean packageIsBrowser(String packageName, int userId) {
   3001         List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
   3002                 PackageManager.MATCH_ALL, userId);
   3003         final int N = list.size();
   3004         for (int i = 0; i < N; i++) {
   3005             ResolveInfo info = list.get(i);
   3006             if (packageName.equals(info.activityInfo.packageName)) {
   3007                 return true;
   3008             }
   3009         }
   3010         return false;
   3011     }
   3012 
   3013     private void checkDefaultBrowser() {
   3014         final int myUserId = UserHandle.myUserId();
   3015         final String packageName = getDefaultBrowserPackageName(myUserId);
   3016         if (packageName != null) {
   3017             PackageInfo info = getPackageInfo(packageName, 0, myUserId);
   3018             if (info == null) {
   3019                 Slog.w(TAG, "Default browser no longer installed: " + packageName);
   3020                 synchronized (mPackages) {
   3021                     applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
   3022                 }
   3023             }
   3024         }
   3025     }
   3026 
   3027     @Override
   3028     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
   3029             throws RemoteException {
   3030         try {
   3031             return super.onTransact(code, data, reply, flags);
   3032         } catch (RuntimeException e) {
   3033             if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
   3034                 Slog.wtf(TAG, "Package Manager Crash", e);
   3035             }
   3036             throw e;
   3037         }
   3038     }
   3039 
   3040     static int[] appendInts(int[] cur, int[] add) {
   3041         if (add == null) return cur;
   3042         if (cur == null) return add;
   3043         final int N = add.length;
   3044         for (int i=0; i<N; i++) {
   3045             cur = appendInt(cur, add[i]);
   3046         }
   3047         return cur;
   3048     }
   3049 
   3050     private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
   3051         if (!sUserManager.exists(userId)) return null;
   3052         if (ps == null) {
   3053             return null;
   3054         }
   3055         final PackageParser.Package p = ps.pkg;
   3056         if (p == null) {
   3057             return null;
   3058         }
   3059 
   3060         final PermissionsState permissionsState = ps.getPermissionsState();
   3061 
   3062         // Compute GIDs only if requested
   3063         final int[] gids = (flags & PackageManager.GET_GIDS) == 0
   3064                 ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
   3065         // Compute granted permissions only if package has requested permissions
   3066         final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
   3067                 ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
   3068         final PackageUserState state = ps.readUserState(userId);
   3069 
   3070         return PackageParser.generatePackageInfo(p, gids, flags,
   3071                 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
   3072     }
   3073 
   3074     @Override
   3075     public void checkPackageStartable(String packageName, int userId) {
   3076         final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
   3077 
   3078         synchronized (mPackages) {
   3079             final PackageSetting ps = mSettings.mPackages.get(packageName);
   3080             if (ps == null) {
   3081                 throw new SecurityException("Package " + packageName + " was not found!");
   3082             }
   3083 
   3084             if (!ps.getInstalled(userId)) {
   3085                 throw new SecurityException(
   3086                         "Package " + packageName + " was not installed for user " + userId + "!");
   3087             }
   3088 
   3089             if (mSafeMode && !ps.isSystem()) {
   3090                 throw new SecurityException("Package " + packageName + " not a system app!");
   3091             }
   3092 
   3093             if (mFrozenPackages.contains(packageName)) {
   3094                 throw new SecurityException("Package " + packageName + " is currently frozen!");
   3095             }
   3096 
   3097             if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware()
   3098                     || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) {
   3099                 throw new SecurityException("Package " + packageName + " is not encryption aware!");
   3100             }
   3101         }
   3102     }
   3103 
   3104     @Override
   3105     public boolean isPackageAvailable(String packageName, int userId) {
   3106         if (!sUserManager.exists(userId)) return false;
   3107         enforceCrossUserPermission(Binder.getCallingUid(), userId,
   3108                 false /* requireFullPermission */, false /* checkShell */, "is package available");
   3109         synchronized (mPackages) {
   3110             PackageParser.Package p = mPackages.get(packageName);
   3111             if (p != null) {
   3112                 final PackageSetting ps = (PackageSetting) p.mExtras;
   3113                 if (ps != null) {
   3114                     final PackageUserState state = ps.readUserState(userId);
   3115                     if (state != null) {
   3116                         return PackageParser.isAvailable(state);
   3117                     }
   3118                 }
   3119             }
   3120         }
   3121         return false;
   3122     }
   3123 
   3124     @Override
   3125     public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
   3126         if (!sUserManager.exists(userId)) return null;
   3127         flags = updateFlagsForPackage(flags, userId, packageName);
   3128         enforceCrossUserPermission(Binder.getCallingUid(), userId,
   3129                 false /* requireFullPermission */, false /* checkShell */, "get package info");
   3130 
   3131         // reader
   3132         synchronized (mPackages) {
   3133             // Normalize package name to hanlde renamed packages
   3134             packageName = normalizePackageNameLPr(packageName);
   3135 
   3136             final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
   3137             PackageParser.Package p = null;
   3138             if (matchFactoryOnly) {
   3139                 final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
   3140                 if (ps != null) {
   3141                     return generatePackageInfo(ps, flags, userId);
   3142                 }
   3143             }
   3144             if (p == null) {
   3145                 p = mPackages.get(packageName);
   3146                 if (matchFactoryOnly && p != null && !isSystemApp(p)) {
   3147                     return null;
   3148                 }
   3149             }
   3150             if (DEBUG_PACKAGE_INFO)
   3151                 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
   3152             if (p != null) {
   3153                 return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
   3154             }
   3155             if (!matchFactoryOnly && (flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
   3156                 final PackageSetting ps = mSettings.mPackages.get(packageName);
   3157                 return generatePackageInfo(ps, flags, userId);
   3158             }
   3159         }
   3160         return null;
   3161     }
   3162 
   3163     @Override
   3164     public String[] currentToCanonicalPackageNames(String[] names) {
   3165         String[] out = new String[names.length];
   3166         // reader
   3167         synchronized (mPackages) {
   3168             for (int i=names.length-1; i>=0; i--) {
   3169                 PackageSetting ps = mSettings.mPackages.get(names[i]);
   3170                 out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
   3171             }
   3172         }
   3173         return out;
   3174     }
   3175 
   3176     @Override
   3177     public String[] canonicalToCurrentPackageNames(String[] names) {
   3178         String[] out = new String[names.length];
   3179         // reader
   3180         synchronized (mPackages) {
   3181             for (int i=names.length-1; i>=0; i--) {
   3182                 String cur = mSettings.mRenamedPackages.get(names[i]);
   3183                 out[i] = cur != null ? cur : names[i];
   3184             }
   3185         }
   3186         return out;
   3187     }
   3188 
   3189     @Override
   3190     public int getPackageUid(String packageName, int flags, int userId) {
   3191         if (!sUserManager.exists(userId)) return -1;
   3192         flags = updateFlagsForPackage(flags, userId, packageName);
   3193         enforceCrossUserPermission(Binder.getCallingUid(), userId,
   3194                 false /* requireFullPermission */, false /* checkShell */, "get package uid");
   3195 
   3196         // reader
   3197         synchronized (mPackages) {
   3198             final PackageParser.Package p = mPackages.get(packageName);
   3199             if (p != null && p.isMatch(flags)) {
   3200                 return UserHandle.getUid(userId, p.applicationInfo.uid);
   3201             }
   3202             if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
   3203                 final PackageSetting ps = mSettings.mPackages.get(packageName);
   3204                 if (ps != null && ps.isMatch(flags)) {
   3205                     return UserHandle.getUid(userId, ps.appId);
   3206                 }
   3207             }
   3208         }
   3209 
   3210         return -1;
   3211     }
   3212 
   3213     @Override
   3214     public int[] getPackageGids(String packageName, int flags, int userId) {
   3215         if (!sUserManager.exists(userId)) return null;
   3216         flags = updateFlagsForPackage(flags, userId, packageName);
   3217         enforceCrossUserPermission(Binder.getCallingUid(), userId,
   3218                 false /* requireFullPermission */, false /* checkShell */,
   3219                 "getPackageGids");
   3220 
   3221         // reader
   3222         synchronized (mPackages) {
   3223             final PackageParser.Package p = mPackages.get(packageName);
   3224             if (p != null && p.isMatch(flags)) {
   3225                 PackageSetting ps = (PackageSetting) p.mExtras;
   3226                 return ps.getPermissionsState().computeGids(userId);
   3227             }
   3228             if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
   3229                 final PackageSetting ps = mSettings.mPackages.get(packageName);
   3230                 if (ps != null && ps.isMatch(flags)) {
   3231                     return ps.getPermissionsState().computeGids(userId);
   3232                 }
   3233             }
   3234         }
   3235 
   3236         return null;
   3237     }
   3238 
   3239     static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) {
   3240         if (bp.perm != null) {
   3241             return PackageParser.generatePermissionInfo(bp.perm, flags);
   3242         }
   3243         PermissionInfo pi = new PermissionInfo();
   3244         pi.name = bp.name;
   3245         pi.packageName = bp.sourcePackage;
   3246         pi.nonLocalizedLabel = bp.name;
   3247         pi.protectionLevel = bp.protectionLevel;
   3248         return pi;
   3249     }
   3250 
   3251     @Override
   3252     public PermissionInfo getPermissionInfo(String name, int flags) {
   3253         // reader
   3254         synchronized (mPackages) {
   3255             final BasePermission p = mSettings.mPermissions.get(name);
   3256             if (p != null) {
   3257                 return generatePermissionInfo(p, flags);
   3258             }
   3259             return null;
   3260         }
   3261     }
   3262 
   3263     @Override
   3264     public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group,
   3265             int flags) {
   3266         // reader
   3267         synchronized (mPackages) {
   3268             if (group != null && !mPermissionGroups.containsKey(group)) {
   3269                 // This is thrown as NameNotFoundException
   3270                 return null;
   3271             }
   3272 
   3273             ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
   3274             for (BasePermission p : mSettings.mPermissions.values()) {
   3275                 if (group == null) {
   3276                     if (p.perm == null || p.perm.info.group == null) {
   3277                         out.add(generatePermissionInfo(p, flags));
   3278                     }
   3279                 } else {
   3280                     if (p.perm != null && group.equals(p.perm.info.group)) {
   3281                         out.add(PackageParser.generatePermissionInfo(p.perm, flags));
   3282                     }
   3283                 }
   3284             }
   3285             return new ParceledListSlice<>(out);
   3286         }
   3287     }
   3288 
   3289     @Override
   3290     public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
   3291         // reader
   3292         synchronized (mPackages) {
   3293             return PackageParser.generatePermissionGroupInfo(
   3294                     mPermissionGroups.get(name), flags);
   3295         }
   3296     }
   3297 
   3298     @Override
   3299     public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
   3300         // reader
   3301         synchronized (mPackages) {
   3302             final int N = mPermissionGroups.size();
   3303             ArrayList<PermissionGroupInfo> out
   3304                     = new ArrayList<PermissionGroupInfo>(N);
   3305             for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
   3306                 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
   3307             }
   3308             return new ParceledListSlice<>(out);
   3309         }
   3310     }
   3311 
   3312     private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
   3313             int userId) {
   3314         if (!sUserManager.exists(userId)) return null;
   3315         PackageSetting ps = mSettings.mPackages.get(packageName);
   3316         if (ps != null) {
   3317             if (ps.pkg == null) {
   3318                 final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
   3319                 if (pInfo != null) {
   3320                     return pInfo.applicationInfo;
   3321                 }
   3322                 return null;
   3323             }
   3324             return PackageParser.generateApplicationInfo(ps.pkg, flags,
   3325                     ps.readUserState(userId), userId);
   3326         }
   3327         return null;
   3328     }
   3329 
   3330     @Override
   3331     public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
   3332         if (!sUserManager.exists(userId)) return null;
   3333         flags = updateFlagsForApplication(flags, userId, packageName);
   3334         enforceCrossUserPermission(Binder.getCallingUid(), userId,
   3335                 false /* requireFullPermission */, false /* checkShell */, "get application info");
   3336 
   3337         // writer
   3338         synchronized (mPackages) {
   3339             // Normalize package name to hanlde renamed packages
   3340             packageName = normalizePackageNameLPr(packageName);
   3341 
   3342             PackageParser.Package p = mPackages.get(packageName);
   3343             if (DEBUG_PACKAGE_INFO) Log.v(
   3344                     TAG, "getApplicationInfo " + packageName
   3345                     + ": " + p);
   3346             if (p != null) {
   3347                 PackageSetting ps = mSettings.mPackages.get(packageName);
   3348                 if (ps == null) return null;
   3349                 // Note: isEnabledLP() does not apply here - always return info
   3350                 return PackageParser.generateApplicationInfo(
   3351                         p, flags, ps.readUserState(userId), userId);
   3352             }
   3353             if ("android".equals(packageName)||"system".equals(packageName)) {
   3354                 return mAndroidApplication;
   3355             }
   3356             if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
   3357                 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId);
   3358             }
   3359         }
   3360         return null;
   3361     }
   3362 
   3363     private String normalizePackageNameLPr(String packageName) {
   3364         String normalizedPackageName = mSettings.mRenamedPackages.get(packageName);
   3365         return normalizedPackageName != null ? normalizedPackageName : packageName;
   3366     }
   3367 
   3368     @Override
   3369     public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
   3370             final IPackageDataObserver observer) {
   3371         mContext.enforceCallingOrSelfPermission(
   3372                 android.Manifest.permission.CLEAR_APP_CACHE, null);
   3373         // Queue up an async operation since clearing cache may take a little while.
   3374         mHandler.post(new Runnable() {
   3375             public void run() {
   3376                 mHandler.removeCallbacks(this);
   3377                 boolean success = true;
   3378                 synchronized (mInstallLock) {
   3379                     try {
   3380                         mInstaller.freeCache(volumeUuid, freeStorageSize);
   3381                     } catch (InstallerException e) {
   3382                         Slog.w(TAG, "Couldn't clear application caches: " + e);
   3383                         success = false;
   3384                     }
   3385                 }
   3386                 if (observer != null) {
   3387                     try {
   3388                         observer.onRemoveCompleted(null, success);
   3389                     } catch (RemoteException e) {
   3390                         Slog.w(TAG, "RemoveException when invoking call back");
   3391                     }
   3392                 }
   3393             }
   3394         });
   3395     }
   3396 
   3397     @Override
   3398     public void freeStorage(final String volumeUuid, final long freeStorageSize,
   3399             final IntentSender pi) {
   3400         mContext.enforceCallingOrSelfPermission(
   3401                 android.Manifest.permission.CLEAR_APP_CACHE, null);
   3402         // Queue up an async operation since clearing cache may take a little while.
   3403         mHandler.post(new Runnable() {
   3404             public void run() {
   3405                 mHandler.removeCallbacks(this);
   3406                 boolean success = true;
   3407                 synchronized (mInstallLock) {
   3408                     try {
   3409                         mInstaller.freeCache(volumeUuid, freeStorageSize);
   3410                     } catch (InstallerException e) {
   3411                         Slog.w(TAG, "Couldn't clear application caches: " + e);
   3412                         success = false;
   3413                     }
   3414                 }
   3415                 if(pi != null) {
   3416                     try {
   3417                         // Callback via pending intent
   3418                         int code = success ? 1 : 0;
   3419                         pi.sendIntent(null, code, null,
   3420                                 null, null);
   3421                     } catch (SendIntentException e1) {
   3422                         Slog.i(TAG, "Failed to send pending intent");
   3423                     }
   3424                 }
   3425             }
   3426         });
   3427     }
   3428 
   3429     void freeStorage(String volumeUuid, long freeStorageSize) throws IOException {
   3430         synchronized (mInstallLock) {
   3431             try {
   3432                 mInstaller.freeCache(volumeUuid, freeStorageSize);
   3433             } catch (InstallerException e) {
   3434                 throw new IOException("Failed to free enough space", e);
   3435             }
   3436         }
   3437     }
   3438 
   3439     /**
   3440      * Update given flags based on encryption status of current user.
   3441      */
   3442     private int updateFlags(int flags, int userId) {
   3443         if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
   3444                 | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
   3445             // Caller expressed an explicit opinion about what encryption
   3446             // aware/unaware components they want to see, so fall through and
   3447             // give them what they want
   3448         } else {
   3449             // Caller expressed no opinion, so match based on user state
   3450             if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
   3451                 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
   3452             } else {
   3453                 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
   3454             }
   3455         }
   3456         return flags;
   3457     }
   3458 
   3459     private UserManagerInternal getUserManagerInternal() {
   3460         if (mUserManagerInternal == null) {
   3461             mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
   3462         }
   3463         return mUserManagerInternal;
   3464     }
   3465 
   3466     /**
   3467      * Update given flags when being used to request {@link PackageInfo}.
   3468      */
   3469     private int updateFlagsForPackage(int flags, int userId, Object cookie) {
   3470         boolean triaged = true;
   3471         if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
   3472                 | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
   3473             // Caller is asking for component details, so they'd better be
   3474             // asking for specific encryption matching behavior, or be triaged
   3475             if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
   3476                     | PackageManager.MATCH_DIRECT_BOOT_AWARE
   3477                     | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
   3478                 triaged = false;
   3479             }
   3480         }
   3481         if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
   3482                 | PackageManager.MATCH_SYSTEM_ONLY
   3483                 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
   3484             triaged = false;
   3485         }
   3486         if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
   3487             Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
   3488                     + " with flags 0x" + Integer.toHexString(flags), new Throwable());
   3489         }
   3490         return updateFlags(flags, userId);
   3491     }
   3492 
   3493     /**
   3494      * Update given flags when being used to request {@link ApplicationInfo}.
   3495      */
   3496     private int updateFlagsForApplication(int flags, int userId, Object cookie) {
   3497         return updateFlagsForPackage(flags, userId, cookie);
   3498     }
   3499 
   3500     /**
   3501      * Update given flags when being used to request {@link ComponentInfo}.
   3502      */
   3503     private int updateFlagsForComponent(int flags, int userId, Object cookie) {
   3504         if (cookie instanceof Intent) {
   3505             if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
   3506                 flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
   3507             }
   3508         }
   3509 
   3510         boolean triaged = true;
   3511         // Caller is asking for component details, so they'd better be
   3512         // asking for specific encryption matching behavior, or be triaged
   3513         if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
   3514                 | PackageManager.MATCH_DIRECT_BOOT_AWARE
   3515                 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
   3516             triaged = false;
   3517         }
   3518         if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
   3519             Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
   3520                     + " with flags 0x" + Integer.toHexString(flags), new Throwable());
   3521         }
   3522 
   3523         return updateFlags(flags, userId);
   3524     }
   3525 
   3526     /**
   3527      * Update given flags when being used to request {@link ResolveInfo}.
   3528      */
   3529     int updateFlagsForResolve(int flags, int userId, Object cookie) {
   3530         // Safe mode means we shouldn't match any third-party components
   3531         if (mSafeMode) {
   3532             flags |= PackageManager.MATCH_SYSTEM_ONLY;
   3533         }
   3534 
   3535         return updateFlagsForComponent(flags, userId, cookie);
   3536     }
   3537 
   3538     @Override
   3539     public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
   3540         if (!sUserManager.exists(userId)) return null;
   3541         flags = updateFlagsForComponent(flags, userId, component);
   3542         enforceCrossUserPermission(Binder.getCallingUid(), userId,
   3543                 false /* requireFullPermission */, false /* checkShell */, "get activity info");
   3544         synchronized (mPackages) {
   3545             PackageParser.Activity a = mActivities.mActivities.get(component);
   3546 
   3547             if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
   3548             if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
   3549                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
   3550                 if (ps == null) return null;
   3551                 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
   3552                         userId);
   3553             }
   3554             if (mResolveComponentName.equals(component)) {
   3555                 return PackageParser.generateActivityInfo(mResolveActivity, flags,
   3556                         new PackageUserState(), userId);
   3557             }
   3558         }
   3559         return null;
   3560     }
   3561 
   3562     @Override
   3563     public boolean activitySupportsIntent(ComponentName component, Intent intent,
   3564             String resolvedType) {
   3565         synchronized (mPackages) {
   3566             if (component.equals(mResolveComponentName)) {
   3567                 // The resolver supports EVERYTHING!
   3568                 return true;
   3569             }
   3570             PackageParser.Activity a = mActivities.mActivities.get(component);
   3571             if (a == null) {
   3572                 return false;
   3573             }
   3574             for (int i=0; i<a.intents.size(); i++) {
   3575                 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
   3576                         intent.getData(), intent.getCategories(), TAG) >= 0) {
   3577                     return true;
   3578                 }
   3579             }
   3580             return false;
   3581         }
   3582     }
   3583 
   3584     @Override
   3585     public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
   3586         if (!sUserManager.exists(userId)) return null;
   3587         flags = updateFlagsForComponent(flags, userId, component);
   3588         enforceCrossUserPermission(Binder.getCallingUid(), userId,
   3589                 false /* requireFullPermission */, false /* checkShell */, "get receiver info");
   3590         synchronized (mPackages) {
   3591             PackageParser.Activity a = mReceivers.mActivities.get(component);
   3592             if (DEBUG_PACKAGE_INFO) Log.v(
   3593                 TAG, "getReceiverInfo " + component + ": " + a);
   3594             if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
   3595                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
   3596                 if (ps == null) return null;
   3597                 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
   3598                         userId);
   3599             }
   3600         }
   3601         return null;
   3602     }
   3603 
   3604     @Override
   3605     public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
   3606         if (!sUserManager.exists(userId)) return null;
   3607         flags = updateFlagsForComponent(flags, userId, component);
   3608         enforceCrossUserPermission(Binder.getCallingUid(), userId,
   3609                 false /* requireFullPermission */, false /* checkShell */, "get service info");
   3610         synchronized (mPackages) {
   3611             PackageParser.Service s = mServices.mServices.get(component);
   3612             if (DEBUG_PACKAGE_INFO) Log.v(
   3613                 TAG, "getServiceInfo " + component + ": " + s);
   3614             if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
   3615                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
   3616                 if (ps == null) return null;
   3617                 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
   3618                         userId);
   3619             }
   3620         }
   3621         return null;
   3622     }
   3623 
   3624     @Override
   3625     public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
   3626         if (!sUserManager.exists(userId)) return null;
   3627         flags = updateFlagsForComponent(flags, userId, component);
   3628         enforceCrossUserPermission(Binder.getCallingUid(), userId,
   3629                 false /* requireFullPermission */, false /* checkShell */, "get provider info");
   3630         synchronized (mPackages) {
   3631             PackageParser.Provider p = mProviders.mProviders.get(component);
   3632             if (DEBUG_PACKAGE_INFO) Log.v(
   3633                 TAG, "getProviderInfo " + component + ": " + p);
   3634             if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
   3635                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
   3636                 if (ps == null) return null;
   3637                 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
   3638                         userId);
   3639             }
   3640         }
   3641         return null;
   3642     }
   3643 
   3644     @Override
   3645     public String[] getSystemSharedLibraryNames() {
   3646         Set<String> libSet;
   3647         synchronized (mPackages) {
   3648             libSet = mSharedLibraries.keySet();
   3649             int size = libSet.size();
   3650             if (size > 0) {
   3651                 String[] libs = new String[size];
   3652                 libSet.toArray(libs);
   3653                 return libs;
   3654             }
   3655         }
   3656         return null;
   3657     }
   3658 
   3659     @Override
   3660     public @NonNull String getServicesSystemSharedLibraryPackageName() {
   3661         synchronized (mPackages) {
   3662             return mServicesSystemSharedLibraryPackageName;
   3663         }
   3664     }
   3665 
   3666     @Override
   3667     public @NonNull String getSharedSystemSharedLibraryPackageName() {
   3668         synchronized (mPackages) {
   3669             return mSharedSystemSharedLibraryPackageName;
   3670         }
   3671     }
   3672 
   3673     @Override
   3674     public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
   3675         synchronized (mPackages) {
   3676             final ArrayList<FeatureInfo> res = new ArrayList<>(mAvailableFeatures.values());
   3677 
   3678             final FeatureInfo fi = new FeatureInfo();
   3679             fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
   3680                     FeatureInfo.GL_ES_VERSION_UNDEFINED);
   3681             res.add(fi);
   3682 
   3683             return new ParceledListSlice<>(res);
   3684         }
   3685     }
   3686 
   3687     @Override
   3688     public boolean hasSystemFeature(String name, int version) {
   3689         synchronized (mPackages) {
   3690             final FeatureInfo feat = mAvailableFeatures.get(name);
   3691             if (feat == null) {
   3692                 return false;
   3693             } else {
   3694                 return feat.version >= version;
   3695             }
   3696         }
   3697     }
   3698 
   3699     @Override
   3700     public int checkPermission(String permName, String pkgName, int userId) {
   3701         if (!sUserManager.exists(userId)) {
   3702             return PackageManager.PERMISSION_DENIED;
   3703         }
   3704 
   3705         synchronized (mPackages) {
   3706             final PackageParser.Package p = mPackages.get(pkgName);
   3707             if (p != null && p.mExtras != null) {
   3708                 final PackageSetting ps = (PackageSetting) p.mExtras;
   3709                 final PermissionsState permissionsState = ps.getPermissionsState();
   3710                 if (permissionsState.hasPermission(permName, userId)) {
   3711                     return PackageManager.PERMISSION_GRANTED;
   3712                 }
   3713                 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
   3714                 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
   3715                         .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
   3716                     return PackageManager.PERMISSION_GRANTED;
   3717                 }
   3718             }
   3719         }
   3720 
   3721         return PackageManager.PERMISSION_DENIED;
   3722     }
   3723 
   3724     @Override
   3725     public int checkUidPermission(String permName, int uid) {
   3726         final int userId = UserHandle.getUserId(uid);
   3727 
   3728         if (!sUserManager.exists(userId)) {
   3729             return PackageManager.PERMISSION_DENIED;
   3730         }
   3731 
   3732         synchronized (mPackages) {
   3733             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
   3734             if (obj != null) {
   3735                 final SettingBase ps = (SettingBase) obj;
   3736                 final PermissionsState permissionsState = ps.getPermissionsState();
   3737                 if (permissionsState.hasPermission(permName, userId)) {
   3738                     return PackageManager.PERMISSION_GRANTED;
   3739                 }
   3740                 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
   3741                 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
   3742                         .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
   3743                     return PackageManager.PERMISSION_GRANTED;
   3744                 }
   3745             } else {
   3746                 ArraySet<String> perms = mSystemPermissions.get(uid);
   3747                 if (perms != null) {
   3748                     if (perms.contains(permName)) {
   3749                         return PackageManager.PERMISSION_GRANTED;
   3750                     }
   3751                     if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
   3752                             .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
   3753                         return PackageManager.PERMISSION_GRANTED;
   3754                     }
   3755                 }
   3756             }
   3757         }
   3758 
   3759         return PackageManager.PERMISSION_DENIED;
   3760     }
   3761 
   3762     @Override
   3763     public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
   3764         if (UserHandle.getCallingUserId() != userId) {
   3765             mContext.enforceCallingPermission(
   3766                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
   3767                     "isPermissionRevokedByPolicy for user " + userId);
   3768         }
   3769 
   3770         if (checkPermission(permission, packageName, userId)
   3771                 == PackageManager.PERMISSION_GRANTED) {
   3772             return false;
   3773         }
   3774 
   3775         final long identity = Binder.clearCallingIdentity();
   3776         try {
   3777             final int flags = getPermissionFlags(permission, packageName, userId);
   3778             return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
   3779         } finally {
   3780             Binder.restoreCallingIdentity(identity);
   3781         }
   3782     }
   3783 
   3784     @Override
   3785     public String getPermissionControllerPackageName() {
   3786         synchronized (mPackages) {
   3787             return mRequiredInstallerPackage;
   3788         }
   3789     }
   3790 
   3791     /**
   3792      * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
   3793      * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
   3794      * @param checkShell whether to prevent shell from access if there's a debugging restriction
   3795      * @param message the message to log on security exception
   3796      */
   3797     void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
   3798             boolean checkShell, String message) {
   3799         if (userId < 0) {
   3800             throw new IllegalArgumentException("Invalid userId " + userId);
   3801         }
   3802         if (checkShell) {
   3803             enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
   3804         }
   3805         if (userId == UserHandle.getUserId(callingUid)) return;
   3806         if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
   3807             if (requireFullPermission) {
   3808                 mContext.enforceCallingOrSelfPermission(
   3809                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
   3810             } else {
   3811                 try {
   3812                     mContext.enforceCallingOrSelfPermission(
   3813                             android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
   3814                 } catch (SecurityException se) {
   3815                     mContext.enforceCallingOrSelfPermission(
   3816                             android.Manifest.permission.INTERACT_ACROSS_USERS, message);
   3817                 }
   3818             }
   3819         }
   3820     }
   3821 
   3822     void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
   3823         if (callingUid == Process.SHELL_UID) {
   3824             if (userHandle >= 0
   3825                     && sUserManager.hasUserRestriction(restriction, userHandle)) {
   3826                 throw new SecurityException("Shell does not have permission to access user "
   3827                         + userHandle);
   3828             } else if (userHandle < 0) {
   3829                 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
   3830                         + Debug.getCallers(3));
   3831             }
   3832         }
   3833     }
   3834 
   3835     private BasePermission findPermissionTreeLP(String permName) {
   3836         for(BasePermission bp : mSettings.mPermissionTrees.values()) {
   3837             if (permName.startsWith(bp.name) &&
   3838                     permName.length() > bp.name.length() &&
   3839                     permName.charAt(bp.name.length()) == '.') {
   3840                 return bp;
   3841             }
   3842         }
   3843         return null;
   3844     }
   3845 
   3846     private BasePermission checkPermissionTreeLP(String permName) {
   3847         if (permName != null) {
   3848             BasePermission bp = findPermissionTreeLP(permName);
   3849             if (bp != null) {
   3850                 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
   3851                     return bp;
   3852                 }
   3853                 throw new SecurityException("Calling uid "
   3854                         + Binder.getCallingUid()
   3855                         + " is not allowed to add to permission tree "
   3856                         + bp.name + " owned by uid " + bp.uid);
   3857             }
   3858         }
   3859         throw new SecurityException("No permission tree found for " + permName);
   3860     }
   3861 
   3862     static boolean compareStrings(CharSequence s1, CharSequence s2) {
   3863         if (s1 == null) {
   3864             return s2 == null;
   3865         }
   3866         if (s2 == null) {
   3867             return false;
   3868         }
   3869         if (s1.getClass() != s2.getClass()) {
   3870             return false;
   3871         }
   3872         return s1.equals(s2);
   3873     }
   3874 
   3875     static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
   3876         if (pi1.icon != pi2.icon) return false;
   3877         if (pi1.logo != pi2.logo) return false;
   3878         if (pi1.protectionLevel != pi2.protectionLevel) return false;
   3879         if (!compareStrings(pi1.name, pi2.name)) return false;
   3880         if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
   3881         // We'll take care of setting this one.
   3882         if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
   3883         // These are not currently stored in settings.
   3884         //if (!compareStrings(pi1.group, pi2.group)) return false;
   3885         //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
   3886         //if (pi1.labelRes != pi2.labelRes) return false;
   3887         //if (pi1.descriptionRes != pi2.descriptionRes) return false;
   3888         return true;
   3889     }
   3890 
   3891     int permissionInfoFootprint(PermissionInfo info) {
   3892         int size = info.name.length();
   3893         if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
   3894         if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
   3895         return size;
   3896     }
   3897 
   3898     int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
   3899         int size = 0;
   3900         for (BasePermission perm : mSettings.mPermissions.values()) {
   3901             if (perm.uid == tree.uid) {
   3902                 size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
   3903             }
   3904         }
   3905         return size;
   3906     }
   3907 
   3908     void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
   3909         // We calculate the max size of permissions defined by this uid and throw
   3910         // if that plus the size of 'info' would exceed our stated maximum.
   3911         if (tree.uid != Process.SYSTEM_UID) {
   3912             final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
   3913             if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
   3914                 throw new SecurityException("Permission tree size cap exceeded");
   3915             }
   3916         }
   3917     }
   3918 
   3919     boolean addPermissionLocked(PermissionInfo info, boolean async) {
   3920         if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
   3921             throw new SecurityException("Label must be specified in permission");
   3922         }
   3923         BasePermission tree = checkPermissionTreeLP(info.name);
   3924         BasePermission bp = mSettings.mPermissions.get(info.name);
   3925         boolean added = bp == null;
   3926         boolean changed = true;
   3927         int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
   3928         if (added) {
   3929             enforcePermissionCapLocked(info, tree);
   3930             bp = new BasePermission(info.name, tree.sourcePackage,
   3931                     BasePermission.TYPE_DYNAMIC);
   3932         } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
   3933             throw new SecurityException(
   3934                     "Not allowed to modify non-dynamic permission "
   3935                     + info.name);
   3936         } else {
   3937             if (bp.protectionLevel == fixedLevel
   3938                     && bp.perm.owner.equals(tree.perm.owner)
   3939                     && bp.uid == tree.uid
   3940                     && comparePermissionInfos(bp.perm.info, info)) {
   3941                 changed = false;
   3942             }
   3943         }
   3944         bp.protectionLevel = fixedLevel;
   3945         info = new PermissionInfo(info);
   3946         info.protectionLevel = fixedLevel;
   3947         bp.perm = new PackageParser.Permission(tree.perm.owner, info);
   3948         bp.perm.info.packageName = tree.perm.info.packageName;
   3949         bp.uid = tree.uid;
   3950         if (added) {
   3951             mSettings.mPermissions.put(info.name, bp);
   3952         }
   3953         if (changed) {
   3954             if (!async) {
   3955                 mSettings.writeLPr();
   3956             } else {
   3957                 scheduleWriteSettingsLocked();
   3958             }
   3959         }
   3960         return added;
   3961     }
   3962 
   3963     @Override
   3964     public boolean addPermission(PermissionInfo info) {
   3965         synchronized (mPackages) {
   3966             return addPermissionLocked(info, false);
   3967         }
   3968     }
   3969 
   3970     @Override
   3971     public boolean addPermissionAsync(PermissionInfo info) {
   3972         synchronized (mPackages) {
   3973             return addPermissionLocked(info, true);
   3974         }
   3975     }
   3976 
   3977     @Override
   3978     public void removePermission(String name) {
   3979         synchronized (mPackages) {
   3980             checkPermissionTreeLP(name);
   3981             BasePermission bp = mSettings.mPermissions.get(name);
   3982             if (bp != null) {
   3983                 if (bp.type != BasePermission.TYPE_DYNAMIC) {
   3984                     throw new SecurityException(
   3985                             "Not allowed to modify non-dynamic permission "
   3986                             + name);
   3987                 }
   3988                 mSettings.mPermissions.remove(name);
   3989                 mSettings.writeLPr();
   3990             }
   3991         }
   3992     }
   3993 
   3994     private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg,
   3995             BasePermission bp) {
   3996         int index = pkg.requestedPermissions.indexOf(bp.name);
   3997         if (index == -1) {
   3998             throw new SecurityException("Package " + pkg.packageName
   3999                     + " has not requested permission " + bp.name);
   4000         }
   4001         if (!bp.isRuntime() && !bp.isDevelopment()) {
   4002             throw new SecurityException("Permission " + bp.name
   4003                     + " is not a changeable permission type");
   4004         }
   4005     }
   4006 
   4007     @Override
   4008     public void grantRuntimePermission(String packageName, String name, final int userId) {
   4009         if (!sUserManager.exists(userId)) {
   4010             Log.e(TAG, "No such user:" + userId);
   4011             return;
   4012         }
   4013 
   4014         mContext.enforceCallingOrSelfPermission(
   4015                 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
   4016                 "grantRuntimePermission");
   4017 
   4018         enforceCrossUserPermission(Binder.getCallingUid(), userId,
   4019                 true /* requireFullPermission */, true /* checkShell */,
   4020                 "grantRuntimePermission");
   4021 
   4022         final int uid;
   4023         final SettingBase sb;
   4024 
   4025         synchronized (mPackages) {
   4026             final PackageParser.Package pkg = mPackages.get(packageName);
   4027             if (pkg == null) {
   4028                 throw new IllegalArgumentException("Unknown package: " + packageName);
   4029             }
   4030 
   4031             final BasePermission bp = mSettings.mPermissions.get(name);
   4032             if (bp == null) {
   4033                 throw new IllegalArgumentException("Unknown permission: " + name);
   4034             }
   4035 
   4036             enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
   4037 
   4038             // If a permission review is required for legacy apps we represent
   4039             // their permissions as always granted runtime ones since we need
   4040             // to keep the review required permission flag per user while an
   4041             // install permission's state is shared across all users.
   4042             if (Build.PERMISSIONS_REVIEW_REQUIRED
   4043                     && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
   4044                     && bp.isRuntime()) {
   4045                 return;
   4046             }
   4047 
   4048             uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
   4049             sb = (SettingBase) pkg.mExtras;
   4050             if (sb == null) {
   4051                 throw new IllegalArgumentException("Unknown package: " + packageName);
   4052             }
   4053 
   4054             final PermissionsState permissionsState = sb.getPermissionsState();
   4055 
   4056             final int flags = permissionsState.getPermissionFlags(name, userId);
   4057             if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
   4058                 throw new SecurityException("Cannot grant system fixed permission "
   4059                         + name + " for package " + packageName);
   4060             }
   4061 
   4062             if (bp.isDevelopment()) {
   4063                 // Development permissions must be handled specially, since they are not
   4064                 // normal runtime permissions.  For now they apply to all users.
   4065                 if (permissionsState.grantInstallPermission(bp) !=
   4066                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
   4067                     scheduleWriteSettingsLocked();
   4068                 }
   4069                 return;
   4070             }
   4071 
   4072             if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
   4073                 Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
   4074                 return;
   4075             }
   4076 
   4077             final int result = permissionsState.grantRuntimePermission(bp, userId);
   4078             switch (result) {
   4079                 case PermissionsState.PERMISSION_OPERATION_FAILURE: {
   4080                     return;
   4081                 }
   4082 
   4083                 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
   4084                     final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
   4085                     mHandler.post(new Runnable() {
   4086                         @Override
   4087                         public void run() {
   4088                             killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
   4089                         }
   4090                     });
   4091                 }
   4092                 break;
   4093             }
   4094 
   4095             mOnPermissionChangeListeners.onPermissionsChanged(uid);
   4096 
   4097             // Not critical if that is lost - app has to request again.
   4098             mSettings.writeRuntimePermissionsForUserLPr(userId, false);
   4099         }
   4100 
   4101         // Only need to do this if user is initialized. Otherwise it's a new user
   4102         // and there are no processes running as the user yet and there's no need
   4103         // to make an expensive call to remount processes for the changed permissions.
   4104         if (READ_EXTERNAL_STORAGE.equals(name)
   4105                 || WRITE_EXTERNAL_STORAGE.equals(name)) {
   4106             final long token = Binder.clearCallingIdentity();
   4107             try {
   4108                 if (sUserManager.isInitialized(userId)) {
   4109                     MountServiceInternal mountServiceInternal = LocalServices.getService(
   4110                             MountServiceInternal.class);
   4111                     mountServiceInternal.onExternalStoragePolicyChanged(uid, packageName);
   4112                 }
   4113             } finally {
   4114                 Binder.restoreCallingIdentity(token);
   4115             }
   4116         }
   4117     }
   4118 
   4119     @Override
   4120     public void revokeRuntimePermission(String packageName, String name, int userId) {
   4121         if (!sUserManager.exists(userId)) {
   4122             Log.e(TAG, "No such user:" + userId);
   4123             return;
   4124         }
   4125 
   4126         mContext.enforceCallingOrSelfPermission(
   4127                 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
   4128                 "revokeRuntimePermission");
   4129 
   4130         enforceCrossUserPermission(Binder.getCallingUid(), userId,
   4131                 true /* requireFullPermission */, true /* checkShell */,
   4132                 "revokeRuntimePermission");
   4133 
   4134         final int appId;
   4135 
   4136         synchronized (mPackages) {
   4137             final PackageParser.Package pkg = mPackages.get(packageName);
   4138             if (pkg == null) {
   4139                 throw new IllegalArgumentException("Unknown package: " + packageName);
   4140             }
   4141 
   4142             final BasePermission bp = mSettings.mPermissions.get(name);
   4143             if (bp == null) {
   4144                 throw new IllegalArgumentException("Unknown permission: " + name);
   4145             }
   4146 
   4147             enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
   4148 
   4149             // If a permission review is required for legacy apps we represent
   4150             // their permissions as always granted runtime ones since we need
   4151             // to keep the review required permission flag per user while an
   4152             // install permission's state is shared across all users.
   4153             if (Build.PERMISSIONS_REVIEW_REQUIRED
   4154                     && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
   4155                     && bp.isRuntime()) {
   4156                 return;
   4157             }
   4158 
   4159             SettingBase sb = (SettingBase) pkg.mExtras;
   4160             if (sb == null) {
   4161                 throw new IllegalArgumentException("Unknown package: " + packageName);
   4162             }
   4163 
   4164             final PermissionsState permissionsState = sb.getPermissionsState();
   4165 
   4166             final int flags = permissionsState.getPermissionFlags(name, userId);
   4167             if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
   4168                 throw new SecurityException("Cannot revoke system fixed permission "
   4169                         + name + " for package " + packageName);
   4170             }
   4171 
   4172             if (bp.isDevelopment()) {
   4173                 // Development permissions must be handled specially, since they are not
   4174                 // normal runtime permissions.  For now they apply to all users.
   4175                 if (permissionsState.revokeInstallPermission(bp) !=
   4176                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
   4177                     scheduleWriteSettingsLocked();
   4178                 }
   4179                 return;
   4180             }
   4181 
   4182             if (permissionsState.revokeRuntimePermission(bp, userId) ==
   4183                     PermissionsState.PERMISSION_OPERATION_FAILURE) {
   4184                 return;
   4185             }
   4186 
   4187             mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
   4188 
   4189             // Critical, after this call app should never have the permission.
   4190             mSettings.writeRuntimePermissionsForUserLPr(userId, true);
   4191 
   4192             appId = UserHandle.getAppId(pkg.applicationInfo.uid);
   4193         }
   4194 
   4195         killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
   4196     }
   4197 
   4198     @Override
   4199     public void resetRuntimePermissions() {
   4200         mContext.enforceCallingOrSelfPermission(
   4201                 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
   4202                 "revokeRuntimePermission");
   4203 
   4204         int callingUid = Binder.getCallingUid();
   4205         if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
   4206             mContext.enforceCallingOrSelfPermission(
   4207                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
   4208                     "resetRuntimePermissions");
   4209         }
   4210 
   4211         synchronized (mPackages) {
   4212             updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
   4213             for (int userId : UserManagerService.getInstance().getUserIds()) {
   4214                 final int packageCount = mPackages.size();
   4215                 for (int i = 0; i < packageCount; i++) {
   4216                     PackageParser.Package pkg = mPackages.valueAt(i);
   4217                     if (!(pkg.mExtras instanceof PackageSetting)) {
   4218                         continue;
   4219                     }
   4220                     PackageSetting ps = (PackageSetting) pkg.mExtras;
   4221                     resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
   4222                 }
   4223             }
   4224         }
   4225     }
   4226 
   4227     @Override
   4228     public int getPermissionFlags(String name, String packageName, int userId) {
   4229         if (!sUserManager.exists(userId)) {
   4230             return 0;
   4231         }
   4232 
   4233         enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
   4234 
   4235         enforceCrossUserPermission(Binder.getCallingUid(), userId,
   4236                 true /* requireFullPermission */, false /* checkShell */,
   4237                 "getPermissionFlags");
   4238 
   4239         synchronized (mPackages) {
   4240             final PackageParser.Package pkg = mPackages.get(packageName);
   4241             if (pkg == null) {
   4242                 return 0;
   4243             }
   4244 
   4245             final BasePermission bp = mSettings.mPermissions.get(name);
   4246             if (bp == null) {
   4247                 return 0;
   4248             }
   4249 
   4250             SettingBase sb = (SettingBase) pkg.mExtras;
   4251             if (sb == null) {
   4252                 return 0;
   4253             }
   4254 
   4255             PermissionsState permissionsState = sb.getPermissionsState();
   4256             return permissionsState.getPermissionFlags(name, userId);
   4257         }
   4258     }
   4259 
   4260     @Override
   4261     public void updatePermissionFlags(String name, String packageName, int flagMask,
   4262             int flagValues, int userId) {
   4263         if (!sUserManager.exists(userId)) {
   4264             return;
   4265         }
   4266 
   4267         enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
   4268 
   4269         enforceCrossUserPermission(Binder.getCallingUid(), userId,
   4270                 true /* requireFullPermission */, true /* checkShell */,
   4271                 "updatePermissionFlags");
   4272 
   4273         // Only the system can change these flags and nothing else.
   4274         if (getCallingUid() != Process.SYSTEM_UID) {
   4275             flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
   4276             flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
   4277             flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
   4278             flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
   4279             flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
   4280         }
   4281 
   4282         synchronized (mPackages) {
   4283             final PackageParser.Package pkg = mPackages.get(packageName);
   4284             if (pkg == null) {
   4285                 throw new IllegalArgumentException("Unknown package: " + packageName);
   4286             }
   4287 
   4288             final BasePermission bp = mSettings.mPermissions.get(name);
   4289             if (bp == null) {
   4290                 throw new IllegalArgumentException("Unknown permission: " + name);
   4291             }
   4292 
   4293             SettingBase sb = (SettingBase) pkg.mExtras;
   4294             if (sb == null) {
   4295                 throw new IllegalArgumentException("Unknown package: " + packageName);
   4296             }
   4297 
   4298             PermissionsState permissionsState = sb.getPermissionsState();
   4299 
   4300             boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
   4301 
   4302             if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
   4303                 // Install and runtime permissions are stored in different places,
   4304                 // so figure out what permission changed and persist the change.
   4305                 if (permissionsState.getInstallPermissionState(name) != null) {
   4306                     scheduleWriteSettingsLocked();
   4307                 } else if (permissionsState.getRuntimePermissionState(name, userId) != null
   4308                         || hadState) {
   4309                     mSettings.writeRuntimePermissionsForUserLPr(userId, false);
   4310                 }
   4311             }
   4312         }
   4313     }
   4314 
   4315     /**
   4316      * Update the permission flags for all packages and runtime permissions of a user in order
   4317      * to allow device or profile owner to remove POLICY_FIXED.
   4318      */
   4319     @Override
   4320     public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
   4321         if (!sUserManager.exists(userId)) {
   4322             return;
   4323         }
   4324 
   4325         enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps");
   4326 
   4327         enforceCrossUserPermission(Binder.getCallingUid(), userId,
   4328                 true /* requireFullPermission */, true /* checkShell */,
   4329                 "updatePermissionFlagsForAllApps");
   4330 
   4331         // Only the system can change system fixed flags.
   4332         if (getCallingUid() != Process.SYSTEM_UID) {
   4333             flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
   4334             flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
   4335         }
   4336 
   4337         synchronized (mPackages) {
   4338             boolean changed = false;
   4339             final int packageCount = mPackages.size();
   4340             for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
   4341                 final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
   4342                 SettingBase sb = (SettingBase) pkg.mExtras;
   4343                 if (sb == null) {
   4344                     continue;
   4345                 }
   4346                 PermissionsState permissionsState = sb.getPermissionsState();
   4347                 changed |= permissionsState.updatePermissionFlagsForAllPermissions(
   4348                         userId, flagMask, flagValues);
   4349             }
   4350             if (changed) {
   4351                 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
   4352             }
   4353         }
   4354     }
   4355 
   4356     private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
   4357         if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
   4358                 != PackageManager.PERMISSION_GRANTED
   4359             && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
   4360                 != PackageManager.PERMISSION_GRANTED) {
   4361             throw new SecurityException(message + " requires "
   4362                     + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
   4363                     + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
   4364         }
   4365     }
   4366 
   4367     @Override
   4368     public boolean shouldShowRequestPermissionRationale(String permissionName,
   4369             String packageName, int userId) {
   4370         if (UserHandle.getCallingUserId() != userId) {
   4371             mContext.enforceCallingPermission(
   4372                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
   4373                     "canShowRequestPermissionRationale for user " + userId);
   4374         }
   4375 
   4376         final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
   4377         if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
   4378             return false;
   4379         }
   4380 
   4381         if (checkPermission(permissionName, packageName, userId)
   4382                 == PackageManager.PERMISSION_GRANTED) {
   4383             return false;
   4384         }
   4385 
   4386         final int flags;
   4387 
   4388         final long identity = Binder.clearCallingIdentity();
   4389         try {
   4390             flags = getPermissionFlags(permissionName,
   4391                     packageName, userId);
   4392         } finally {
   4393             Binder.restoreCallingIdentity(identity);
   4394         }
   4395 
   4396         final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
   4397                 | PackageManager.FLAG_PERMISSION_POLICY_FIXED
   4398                 | PackageManager.FLAG_PERMISSION_USER_FIXED;
   4399 
   4400         if ((flags & fixedFlags) != 0) {
   4401             return false;
   4402         }
   4403 
   4404         return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
   4405     }
   4406 
   4407     @Override
   4408     public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
   4409         mContext.enforceCallingOrSelfPermission(
   4410                 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
   4411                 "addOnPermissionsChangeListener");
   4412 
   4413         synchronized (mPackages) {
   4414             mOnPermissionChangeListeners.addListenerLocked(listener);
   4415         }
   4416     }
   4417 
   4418     @Override
   4419     public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
   4420         synchronized (mPackages) {
   4421             mOnPermissionChangeListeners.removeListenerLocked(listener);
   4422         }
   4423     }
   4424 
   4425     @Override
   4426     public boolean isProtectedBroadcast(String actionName) {
   4427         synchronized (mPackages) {
   4428             if (mProtectedBroadcasts.contains(actionName)) {
   4429                 return true;
   4430             } else if (actionName != null) {
   4431                 // TODO: remove these terrible hacks
   4432                 if (actionName.startsWith("android.net.netmon.lingerExpired")
   4433                         || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
   4434                         || actionName.startsWith("com.android.internal.telephony.data-reconnect")
   4435                         || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
   4436                     return true;
   4437                 }
   4438             }
   4439         }
   4440         return false;
   4441     }
   4442 
   4443     @Override
   4444     public int checkSignatures(String pkg1, String pkg2) {
   4445         synchronized (mPackages) {
   4446             final PackageParser.Package p1 = mPackages.get(pkg1);
   4447             final PackageParser.Package p2 = mPackages.get(pkg2);
   4448             if (p1 == null || p1.mExtras == null
   4449                     || p2 == null || p2.mExtras == null) {
   4450                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
   4451             }
   4452             return compareSignatures(p1.mSignatures, p2.mSignatures);
   4453         }
   4454     }
   4455 
   4456     @Override
   4457     public int checkUidSignatures(int uid1, int uid2) {
   4458         // Map to base uids.
   4459         uid1 = UserHandle.getAppId(uid1);
   4460         uid2 = UserHandle.getAppId(uid2);
   4461         // reader
   4462         synchronized (mPackages) {
   4463             Signature[] s1;
   4464             Signature[] s2;
   4465             Object obj = mSettings.getUserIdLPr(uid1);
   4466             if (obj != null) {
   4467                 if (obj instanceof SharedUserSetting) {
   4468                     s1 = ((SharedUserSetting)obj).signatures.mSignatures;
   4469                 } else if (obj instanceof PackageSetting) {
   4470                     s1 = ((PackageSetting)obj).signatures.mSignatures;
   4471                 } else {
   4472                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
   4473                 }
   4474             } else {
   4475                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
   4476             }
   4477             obj = mSettings.getUserIdLPr(uid2);
   4478             if (obj != null) {
   4479                 if (obj instanceof SharedUserSetting) {
   4480                     s2 = ((SharedUserSetting)obj).signatures.mSignatures;
   4481                 } else if (obj instanceof PackageSetting) {
   4482                     s2 = ((PackageSetting)obj).signatures.mSignatures;
   4483                 } else {
   4484                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
   4485                 }
   4486             } else {
   4487                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
   4488             }
   4489             return compareSignatures(s1, s2);
   4490         }
   4491     }
   4492 
   4493     /**
   4494      * This method should typically only be used when granting or revoking
   4495      * permissions, since the app may immediately restart after this call.
   4496      * <p>
   4497      * If you're doing surgery on app code/data, use {@link PackageFreezer} to
   4498      * guard your work against the app being relaunched.
   4499      */
   4500     private void killUid(int appId, int userId, String reason) {
   4501         final long identity = Binder.clearCallingIdentity();
   4502         try {
   4503             IActivityManager am = ActivityManagerNative.getDefault();
   4504             if (am != null) {
   4505                 try {
   4506                     am.killUid(appId, userId, reason);
   4507                 } catch (RemoteException e) {
   4508                     /* ignore - same process */
   4509                 }
   4510             }
   4511         } finally {
   4512             Binder.restoreCallingIdentity(identity);
   4513         }
   4514     }
   4515 
   4516     /**
   4517      * Compares two sets of signatures. Returns:
   4518      * <br />
   4519      * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
   4520      * <br />
   4521      * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
   4522      * <br />
   4523      * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
   4524      * <br />
   4525      * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
   4526      * <br />
   4527      * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
   4528      */
   4529     static int compareSignatures(Signature[] s1, Signature[] s2) {
   4530         if (s1 == null) {
   4531             return s2 == null
   4532                     ? PackageManager.SIGNATURE_NEITHER_SIGNED
   4533                     : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
   4534         }
   4535 
   4536         if (s2 == null) {
   4537             return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
   4538         }
   4539 
   4540         if (s1.length != s2.length) {
   4541             return PackageManager.SIGNATURE_NO_MATCH;
   4542         }
   4543 
   4544         // Since both signature sets are of size 1, we can compare without HashSets.
   4545         if (s1.length == 1) {
   4546             return s1[0].equals(s2[0]) ?
   4547                     PackageManager.SIGNATURE_MATCH :
   4548                     PackageManager.SIGNATURE_NO_MATCH;
   4549         }
   4550 
   4551         ArraySet<Signature> set1 = new ArraySet<Signature>();
   4552         for (Signature sig : s1) {
   4553             set1.add(sig);
   4554         }
   4555         ArraySet<Signature> set2 = new ArraySet<Signature>();
   4556         for (Signature sig : s2) {
   4557             set2.add(sig);
   4558         }
   4559         // Make sure s2 contains all signatures in s1.
   4560         if (set1.equals(set2)) {
   4561             return PackageManager.SIGNATURE_MATCH;
   4562         }
   4563         return PackageManager.SIGNATURE_NO_MATCH;
   4564     }
   4565 
   4566     /**
   4567      * If the database version for this type of package (internal storage or
   4568      * external storage) is less than the version where package signatures
   4569      * were updated, return true.
   4570      */
   4571     private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
   4572         final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
   4573         return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
   4574     }
   4575 
   4576     /**
   4577      * Used for backward compatibility to make sure any packages with
   4578      * certificate chains get upgraded to the new style. {@code existingSigs}
   4579      * will be in the old format (since they were stored on disk from before the
   4580      * system upgrade) and {@code scannedSigs} will be in the newer format.
   4581      */
   4582     private int compareSignaturesCompat(PackageSignatures existingSigs,
   4583             PackageParser.Package scannedPkg) {
   4584         if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
   4585             return PackageManager.SIGNATURE_NO_MATCH;
   4586         }
   4587 
   4588         ArraySet<Signature> existingSet = new ArraySet<Signature>();
   4589         for (Signature sig : existingSigs.mSignatures) {
   4590             existingSet.add(sig);
   4591         }
   4592         ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
   4593         for (Signature sig : scannedPkg.mSignatures) {
   4594             try {
   4595                 Signature[] chainSignatures = sig.getChainSignatures();
   4596                 for (Signature chainSig : chainSignatures) {
   4597                     scannedCompatSet.add(chainSig);
   4598                 }
   4599             } catch (CertificateEncodingException e) {
   4600                 scannedCompatSet.add(sig);
   4601             }
   4602         }
   4603         /*
   4604          * Make sure the expanded scanned set contains all signatures in the
   4605          * existing one.
   4606          */
   4607         if (scannedCompatSet.equals(existingSet)) {
   4608             // Migrate the old signatures to the new scheme.
   4609             existingSigs.assignSignatures(scannedPkg.mSignatures);
   4610             // The new KeySets will be re-added later in the scanning process.
   4611             synchronized (mPackages) {
   4612                 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
   4613             }
   4614             return PackageManager.SIGNATURE_MATCH;
   4615         }
   4616         return PackageManager.SIGNATURE_NO_MATCH;
   4617     }
   4618 
   4619     private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
   4620         final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
   4621         return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
   4622     }
   4623 
   4624     private int compareSignaturesRecover(PackageSignatures existingSigs,
   4625             PackageParser.Package scannedPkg) {
   4626         if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
   4627             return PackageManager.SIGNATURE_NO_MATCH;
   4628         }
   4629 
   4630         String msg = null;
   4631         try {
   4632             if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
   4633                 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
   4634                         + scannedPkg.packageName);
   4635                 return PackageManager.SIGNATURE_MATCH;
   4636             }
   4637         } catch (CertificateException e) {
   4638             msg = e.getMessage();
   4639         }
   4640 
   4641         logCriticalInfo(Log.INFO,
   4642                 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
   4643         return PackageManager.SIGNATURE_NO_MATCH;
   4644     }
   4645 
   4646     @Override
   4647     public List<String> getAllPackages() {
   4648         synchronized (mPackages) {
   4649             return new ArrayList<String>(mPackages.keySet());
   4650         }
   4651     }
   4652 
   4653     @Override
   4654     public String[] getPackagesForUid(int uid) {
   4655         uid = UserHandle.getAppId(uid);
   4656         // reader
   4657         synchronized (mPackages) {
   4658             Object obj = mSettings.getUserIdLPr(uid);
   4659             if (obj instanceof SharedUserSetting) {
   4660                 final SharedUserSetting sus = (SharedUserSetting) obj;
   4661                 final int N = sus.packages.size();
   4662                 final String[] res = new String[N];
   4663                 for (int i = 0; i < N; i++) {
   4664                     res[i] = sus.packages.valueAt(i).name;
   4665                 }
   4666                 return res;
   4667             } else if (obj instanceof PackageSetting) {
   4668                 final PackageSetting ps = (PackageSetting) obj;
   4669                 return new String[] { ps.name };
   4670             }
   4671         }
   4672         return null;
   4673     }
   4674 
   4675     @Override
   4676     public String getNameForUid(int uid) {
   4677         // reader
   4678         synchronized (mPackages) {
   4679             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
   4680             if (obj instanceof SharedUserSetting) {
   4681                 final SharedUserSetting sus = (SharedUserSetting) obj;
   4682                 return sus.name + ":" + sus.userId;
   4683             } else if (obj instanceof PackageSetting) {
   4684                 final PackageSetting ps = (PackageSetting) obj;
   4685                 return ps.name;
   4686             }
   4687         }
   4688         return null;
   4689     }
   4690 
   4691     @Override
   4692     public int getUidForSharedUser(String sharedUserName) {
   4693         if(sharedUserName == null) {
   4694             return -1;
   4695         }
   4696         // reader
   4697         synchronized (mPackages) {
   4698             final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
   4699             if (suid == null) {
   4700                 return -1;
   4701             }
   4702             return suid.userId;
   4703         }
   4704     }
   4705 
   4706     @Override
   4707     public int getFlagsForUid(int uid) {
   4708         synchronized (mPackages) {
   4709             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
   4710             if (obj instanceof SharedUserSetting) {
   4711                 final SharedUserSetting sus = (SharedUserSetting) obj;
   4712                 return sus.pkgFlags;
   4713             } else if (obj instanceof PackageSetting) {
   4714                 final PackageSetting ps = (PackageSetting) obj;
   4715                 return ps.pkgFlags;
   4716             }
   4717         }
   4718         return 0;
   4719     }
   4720 
   4721     @Override
   4722     public int getPrivateFlagsForUid(int uid) {
   4723         synchronized (mPackages) {
   4724             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
   4725             if (obj instanceof SharedUserSetting) {
   4726                 final SharedUserSetting sus = (SharedUserSetting) obj;
   4727                 return sus.pkgPrivateFlags;
   4728             } else if (obj instanceof PackageSetting) {
   4729                 final PackageSetting ps = (PackageSetting) obj;
   4730                 return ps.pkgPrivateFlags;
   4731             }
   4732         }
   4733         return 0;
   4734     }
   4735 
   4736     @Override
   4737     public boolean isUidPrivileged(int uid) {
   4738         uid = UserHandle.getAppId(uid);
   4739         // reader
   4740         synchronized (mPackages) {
   4741             Object obj = mSettings.getUserIdLPr(uid);
   4742             if (obj instanceof SharedUserSetting) {
   4743                 final SharedUserSetting sus = (SharedUserSetting) obj;
   4744                 final Iterator<PackageSetting> it = sus.packages.iterator();
   4745                 while (it.hasNext()) {
   4746                     if (it.next().isPrivileged()) {
   4747                         return true;
   4748                     }
   4749                 }
   4750             } else if (obj instanceof PackageSetting) {
   4751                 final PackageSetting ps = (PackageSetting) obj;
   4752                 return ps.isPrivileged();
   4753             }
   4754         }
   4755         return false;
   4756     }
   4757 
   4758     @Override
   4759     public String[] getAppOpPermissionPackages(String permissionName) {
   4760         synchronized (mPackages) {
   4761             ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
   4762             if (pkgs == null) {
   4763                 return null;
   4764             }
   4765             return pkgs.toArray(new String[pkgs.size()]);
   4766         }
   4767     }
   4768 
   4769     @Override
   4770     public ResolveInfo resolveIntent(Intent intent, String resolvedType,
   4771             int flags, int userId) {
   4772         try {
   4773             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
   4774 
   4775             if (!sUserManager.exists(userId)) return null;
   4776             flags = updateFlagsForResolve(flags, userId, intent);
   4777             enforceCrossUserPermission(Binder.getCallingUid(), userId,
   4778                     false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
   4779 
   4780             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
   4781             final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
   4782                     flags, userId);
   4783             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
   4784 
   4785             final ResolveInfo bestChoice =
   4786                     chooseBestActivity(intent, resolvedType, flags, query, userId);
   4787             return bestChoice;
   4788         } finally {
   4789             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
   4790         }
   4791     }
   4792 
   4793     @Override
   4794     public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
   4795             IntentFilter filter, int match, ComponentName activity) {
   4796         final int userId = UserHandle.getCallingUserId();
   4797         if (DEBUG_PREFERRED) {
   4798             Log.v(TAG, "setLastChosenActivity intent=" + intent
   4799                 + " resolvedType=" + resolvedType
   4800                 + " flags=" + flags
   4801                 + " filter=" + filter
   4802                 + " match=" + match
   4803                 + " activity=" + activity);
   4804             filter.dump(new PrintStreamPrinter(System.out), "    ");
   4805         }
   4806         intent.setComponent(null);
   4807         final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
   4808                 userId);
   4809         // Find any earlier preferred or last chosen entries and nuke them
   4810         findPreferredActivity(intent, resolvedType,
   4811                 flags, query, 0, false, true, false, userId);
   4812         // Add the new activity as the last chosen for this filter
   4813         addPreferredActivityInternal(filter, match, null, activity, false, userId,
   4814                 "Setting last chosen");
   4815     }
   4816 
   4817     @Override
   4818     public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
   4819         final int userId = UserHandle.getCallingUserId();
   4820         if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
   4821         final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
   4822                 userId);
   4823         return findPreferredActivity(intent, resolvedType, flags, query, 0,
   4824                 false, false, false, userId);
   4825     }
   4826 
   4827     private boolean isEphemeralDisabled() {
   4828         // ephemeral apps have been disabled across the board
   4829         if (DISABLE_EPHEMERAL_APPS) {
   4830             return true;
   4831         }
   4832         // system isn't up yet; can't read settings, so, assume no ephemeral apps
   4833         if (!mSystemReady) {
   4834             return true;
   4835         }
   4836         // we can't get a content resolver until the system is ready; these checks must happen last
   4837         final ContentResolver resolver = mContext.getContentResolver();
   4838         if (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) {
   4839             return true;
   4840         }
   4841         return Secure.getInt(resolver, Secure.WEB_ACTION_ENABLED, 1) == 0;
   4842     }
   4843 
   4844     private boolean isEphemeralAllowed(
   4845             Intent intent, List<ResolveInfo> resolvedActivities, int userId,
   4846             boolean skipPackageCheck) {
   4847         // Short circuit and return early if possible.
   4848         if (isEphemeralDisabled()) {
   4849             return false;
   4850         }
   4851         final int callingUser = UserHandle.getCallingUserId();
   4852         if (callingUser != UserHandle.USER_SYSTEM) {
   4853             return false;
   4854         }
   4855         if (mEphemeralResolverConnection == null) {
   4856             return false;
   4857         }
   4858         if (intent.getComponent() != null) {
   4859             return false;
   4860         }
   4861         if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
   4862             return false;
   4863         }
   4864         if (!skipPackageCheck && intent.getPackage() != null) {
   4865             return false;
   4866         }
   4867         final boolean isWebUri = hasWebURI(intent);
   4868         if (!isWebUri || intent.getData().getHost() == null) {
   4869             return false;
   4870         }
   4871         // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
   4872         synchronized (mPackages) {
   4873             final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
   4874             for (int n = 0; n < count; n++) {
   4875                 ResolveInfo info = resolvedActivities.get(n);
   4876                 String packageName = info.activityInfo.packageName;
   4877                 PackageSetting ps = mSettings.mPackages.get(packageName);
   4878                 if (ps != null) {
   4879                     // Try to get the status from User settings first
   4880                     long packedStatus = getDomainVerificationStatusLPr(ps, userId);
   4881                     int status = (int) (packedStatus >> 32);
   4882                     if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
   4883                             || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
   4884                         if (DEBUG_EPHEMERAL) {
   4885                             Slog.v(TAG, "DENY ephemeral apps;"
   4886                                 + " pkg: " + packageName + ", status: " + status);
   4887                         }
   4888                         return false;
   4889                     }
   4890                 }
   4891             }
   4892         }
   4893         // We've exhausted all ways to deny ephemeral application; let the system look for them.
   4894         return true;
   4895     }
   4896 
   4897     private static EphemeralResolveInfo getEphemeralResolveInfo(
   4898             Context context, EphemeralResolverConnection resolverConnection, Intent intent,
   4899             String resolvedType, int userId, String packageName) {
   4900         final int ephemeralPrefixMask = Global.getInt(context.getContentResolver(),
   4901                 Global.EPHEMERAL_HASH_PREFIX_MASK, DEFAULT_EPHEMERAL_HASH_PREFIX_MASK);
   4902         final int ephemeralPrefixCount = Global.getInt(context.getContentResolver(),
   4903                 Global.EPHEMERAL_HASH_PREFIX_COUNT, DEFAULT_EPHEMERAL_HASH_PREFIX_COUNT);
   4904         final EphemeralDigest digest = new EphemeralDigest(intent.getData(), ephemeralPrefixMask,
   4905                 ephemeralPrefixCount);
   4906         final int[] shaPrefix = digest.getDigestPrefix();
   4907         final byte[][] digestBytes = digest.getDigestBytes();
   4908         final List<EphemeralResolveInfo> ephemeralResolveInfoList =
   4909                 resolverConnection.getEphemeralResolveInfoList(shaPrefix, ephemeralPrefixMask);
   4910         if (ephemeralResolveInfoList == null || ephemeralResolveInfoList.size() == 0) {
   4911             // No hash prefix match; there are no ephemeral apps for this domain.
   4912             return null;
   4913         }
   4914 
   4915         // Go in reverse order so we match the narrowest scope first.
   4916         for (int i = shaPrefix.length - 1; i >= 0 ; --i) {
   4917             for (EphemeralResolveInfo ephemeralApplication : ephemeralResolveInfoList) {
   4918                 if (!Arrays.equals(digestBytes[i], ephemeralApplication.getDigestBytes())) {
   4919                     continue;
   4920                 }
   4921                 final List<IntentFilter> filters = ephemeralApplication.getFilters();
   4922                 // No filters; this should never happen.
   4923                 if (filters.isEmpty()) {
   4924                     continue;
   4925                 }
   4926                 if (packageName != null
   4927                         && !packageName.equals(ephemeralApplication.getPackageName())) {
   4928                     continue;
   4929                 }
   4930                 // We have a domain match; resolve the filters to see if anything matches.
   4931                 final EphemeralIntentResolver ephemeralResolver = new EphemeralIntentResolver();
   4932                 for (int j = filters.size() - 1; j >= 0; --j) {
   4933                     final EphemeralResolveIntentInfo intentInfo =
   4934                             new EphemeralResolveIntentInfo(filters.get(j), ephemeralApplication);
   4935                     ephemeralResolver.addFilter(intentInfo);
   4936                 }
   4937                 List<EphemeralResolveInfo> matchedResolveInfoList = ephemeralResolver.queryIntent(
   4938                         intent, resolvedType, false /*defaultOnly*/, userId);
   4939                 if (!matchedResolveInfoList.isEmpty()) {
   4940                     return matchedResolveInfoList.get(0);
   4941                 }
   4942             }
   4943         }
   4944         // Hash or filter mis-match; no ephemeral apps for this domain.
   4945         return null;
   4946     }
   4947 
   4948     private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
   4949             int flags, List<ResolveInfo> query, int userId) {
   4950         if (query != null) {
   4951             final int N = query.size();
   4952             if (N == 1) {
   4953                 return query.get(0);
   4954             } else if (N > 1) {
   4955                 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
   4956                 // If there is more than one activity with the same priority,
   4957                 // then let the user decide between them.
   4958                 ResolveInfo r0 = query.get(0);
   4959                 ResolveInfo r1 = query.get(1);
   4960                 if (DEBUG_INTENT_MATCHING || debug) {
   4961                     Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
   4962                             + r1.activityInfo.name + "=" + r1.priority);
   4963                 }
   4964                 // If the first activity has a higher priority, or a different
   4965                 // default, then it is always desirable to pick it.
   4966                 if (r0.priority != r1.priority
   4967                         || r0.preferredOrder != r1.preferredOrder
   4968                         || r0.isDefault != r1.isDefault) {
   4969                     return query.get(0);
   4970                 }
   4971                 // If we have saved a preference for a preferred activity for
   4972                 // this Intent, use that.
   4973                 ResolveInfo ri = findPreferredActivity(intent, resolvedType,
   4974                         flags, query, r0.priority, true, false, debug, userId);
   4975                 if (ri != null) {
   4976                     return ri;
   4977                 }
   4978                 ri = new ResolveInfo(mResolveInfo);
   4979                 ri.activityInfo = new ActivityInfo(ri.activityInfo);
   4980                 ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
   4981                 // If all of the options come from the same package, show the application's
   4982                 // label and icon instead of the generic resolver's.
   4983                 // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
   4984                 // and then throw away the ResolveInfo itself, meaning that the caller loses
   4985                 // the resolvePackageName. Therefore the activityInfo.labelRes above provides
   4986                 // a fallback for this case; we only set the target package's resources on
   4987                 // the ResolveInfo, not the ActivityInfo.
   4988                 final String intentPackage = intent.getPackage();
   4989                 if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
   4990                     final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
   4991                     ri.resolvePackageName = intentPackage;
   4992                     if (userNeedsBadging(userId)) {
   4993                         ri.noResourceId = true;
   4994                     } else {
   4995                         ri.icon = appi.icon;
   4996                     }
   4997                     ri.iconResourceId = appi.icon;
   4998                     ri.labelRes = appi.labelRes;
   4999                 }
   5000                 ri.activityInfo.applicationInfo = new ApplicationInfo(
   5001                         ri.activityInfo.applicationInfo);
   5002                 if (userId != 0) {
   5003                     ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
   5004                             UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
   5005                 }
   5006                 // Make sure that the resolver is displayable in car mode
   5007                 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
   5008                 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
   5009                 return ri;
   5010             }
   5011         }
   5012         return null;
   5013     }
   5014 
   5015     /**
   5016      * Return true if the given list is not empty and all of its contents have
   5017      * an activityInfo with the given package name.
   5018      */
   5019     private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
   5020         if (ArrayUtils.isEmpty(list)) {
   5021             return false;
   5022         }
   5023         for (int i = 0, N = list.size(); i < N; i++) {
   5024             final ResolveInfo ri = list.get(i);
   5025             final ActivityInfo ai = ri != null ? ri.activityInfo : null;
   5026             if (ai == null || !packageName.equals(ai.packageName)) {
   5027                 return false;
   5028             }
   5029         }
   5030         return true;
   5031     }
   5032 
   5033     private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
   5034             int flags, List<ResolveInfo> query, boolean debug, int userId) {
   5035         final int N = query.size();
   5036         PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
   5037                 .get(userId);
   5038         // Get the list of persistent preferred activities that handle the intent
   5039         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
   5040         List<PersistentPreferredActivity> pprefs = ppir != null
   5041                 ? ppir.queryIntent(intent, resolvedType,
   5042                         (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
   5043                 : null;
   5044         if (pprefs != null && pprefs.size() > 0) {
   5045             final int M = pprefs.size();
   5046             for (int i=0; i<M; i++) {
   5047                 final PersistentPreferredActivity ppa = pprefs.get(i);
   5048                 if (DEBUG_PREFERRED || debug) {
   5049                     Slog.v(TAG, "Checking PersistentPreferredActivity ds="
   5050                             + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
   5051                             + "\n  component=" + ppa.mComponent);
   5052                     ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
   5053                 }
   5054                 final ActivityInfo ai = getActivityInfo(ppa.mComponent,
   5055                         flags | MATCH_DISABLED_COMPONENTS, userId);
   5056                 if (DEBUG_PREFERRED || debug) {
   5057                     Slog.v(TAG, "Found persistent preferred activity:");
   5058                     if (ai != null) {
   5059                         ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
   5060                     } else {
   5061                         Slog.v(TAG, "  null");
   5062                     }
   5063                 }
   5064                 if (ai == null) {
   5065                     // This previously registered persistent preferred activity
   5066                     // component is no longer known. Ignore it and do NOT remove it.
   5067                     continue;
   5068                 }
   5069                 for (int j=0; j<N; j++) {
   5070                     final ResolveInfo ri = query.get(j);
   5071                     if (!ri.activityInfo.applicationInfo.packageName
   5072                             .equals(ai.applicationInfo.packageName)) {
   5073                         continue;
   5074                     }
   5075                     if (!ri.activityInfo.name.equals(ai.name)) {
   5076                         continue;
   5077                     }
   5078                     //  Found a persistent preference that can handle the intent.
   5079                     if (DEBUG_PREFERRED || debug) {
   5080                         Slog.v(TAG, "Returning persistent preferred activity: " +
   5081                                 ri.activityInfo.packageName + "/" + ri.activityInfo.name);
   5082                     }
   5083                     return ri;
   5084                 }
   5085             }
   5086         }
   5087         return null;
   5088     }
   5089 
   5090     // TODO: handle preferred activities missing while user has amnesia
   5091     ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
   5092             List<ResolveInfo> query, int priority, boolean always,
   5093             boolean removeMatches, boolean debug, int userId) {
   5094         if (!sUserManager.exists(userId)) return null;
   5095         flags = updateFlagsForResolve(flags, userId, intent);
   5096         // writer
   5097         synchronized (mPackages) {
   5098             if (intent.getSelector() != null) {
   5099                 intent = intent.getSelector();
   5100             }
   5101             if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
   5102 
   5103             // Try to find a matching persistent preferred activity.
   5104             ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
   5105                     debug, userId);
   5106 
   5107             // If a persistent preferred activity matched, use it.
   5108             if (pri != null) {
   5109                 return pri;
   5110             }
   5111 
   5112             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
   5113             // Get the list of preferred activities that handle the intent
   5114             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
   5115             List<PreferredActivity> prefs = pir != null
   5116                     ? pir.queryIntent(intent, resolvedType,
   5117                             (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
   5118                     : null;
   5119             if (prefs != null && prefs.size() > 0) {
   5120                 boolean changed = false;
   5121                 try {
   5122                     // First figure out how good the original match set is.
   5123                     // We will only allow preferred activities that came
   5124                     // from the same match quality.
   5125                     int match = 0;
   5126 
   5127                     if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
   5128 
   5129                     final int N = query.size();
   5130                     for (int j=0; j<N; j++) {
   5131                         final ResolveInfo ri = query.get(j);
   5132                         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
   5133                                 + ": 0x" + Integer.toHexString(match));
   5134                         if (ri.match > match) {
   5135                             match = ri.match;
   5136                         }
   5137                     }
   5138 
   5139                     if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
   5140                             + Integer.toHexString(match));
   5141 
   5142                     match &= IntentFilter.MATCH_CATEGORY_MASK;
   5143                     final int M = prefs.size();
   5144                     for (int i=0; i<M; i++) {
   5145                         final PreferredActivity pa = prefs.get(i);
   5146                         if (DEBUG_PREFERRED || debug) {
   5147                             Slog.v(TAG, "Checking PreferredActivity ds="
   5148                                     + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
   5149                                     + "\n  component=" + pa.mPref.mComponent);
   5150                             pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
   5151                         }
   5152                         if (pa.mPref.mMatch != match) {
   5153                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
   5154                                     + Integer.toHexString(pa.mPref.mMatch));
   5155                             continue;
   5156                         }
   5157                         // If it's not an "always" type preferred activity and that's what we're
   5158                         // looking for, skip it.
   5159                         if (always && !pa.mPref.mAlways) {
   5160                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
   5161                             continue;
   5162                         }
   5163                         final ActivityInfo ai = getActivityInfo(
   5164                                 pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
   5165                                         | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
   5166                                 userId);
   5167                         if (DEBUG_PREFERRED || debug) {
   5168                             Slog.v(TAG, "Found preferred activity:");
   5169                             if (ai != null) {
   5170                                 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
   5171                             } else {
   5172                                 Slog.v(TAG, "  null");
   5173                             }
   5174                         }
   5175                         if (ai == null) {
   5176                             // This previously registered preferred activity
   5177                             // component is no longer known.  Most likely an update
   5178                             // to the app was installed and in the new version this
   5179                             // component no longer exists.  Clean it up by removing
   5180                             // it from the preferred activities list, and skip it.
   5181                             Slog.w(TAG, "Removing dangling preferred activity: "
   5182                                     + pa.mPref.mComponent);
   5183                             pir.removeFilter(pa);
   5184                             changed = true;
   5185                             continue;
   5186                         }
   5187                         for (int j=0; j<N; j++) {
   5188                             final ResolveInfo ri = query.get(j);
   5189                             if (!ri.activityInfo.applicationInfo.packageName
   5190                                     .equals(ai.applicationInfo.packageName)) {
   5191                                 continue;
   5192                             }
   5193                             if (!ri.activityInfo.name.equals(ai.name)) {
   5194                                 continue;
   5195                             }
   5196 
   5197                             if (removeMatches) {
   5198                                 pir.removeFilter(pa);
   5199                                 changed = true;
   5200                                 if (DEBUG_PREFERRED) {
   5201                                     Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
   5202                                 }
   5203                                 break;
   5204                             }
   5205 
   5206                             // Okay we found a previously set preferred or last chosen app.
   5207                             // If the result set is different from when this
   5208                             // was created, we need to clear it and re-ask the
   5209                             // user their preference, if we're looking for an "always" type entry.
   5210                             if (always && !pa.mPref.sameSet(query)) {
   5211                                 Slog.i(TAG, "Result set changed, dropping preferred activity for "
   5212                                         + intent + " type " + resolvedType);
   5213                                 if (DEBUG_PREFERRED) {
   5214                                     Slog.v(TAG, "Removing preferred activity since set changed "
   5215                                             + pa.mPref.mComponent);
   5216                                 }
   5217                                 pir.removeFilter(pa);
   5218                                 // Re-add the filter as a "last chosen" entry (!always)
   5219                                 PreferredActivity lastChosen = new PreferredActivity(
   5220                                         pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
   5221                                 pir.addFilter(lastChosen);
   5222                                 changed = true;
   5223                                 return null;
   5224                             }
   5225 
   5226                             // Yay! Either the set matched or we're looking for the last chosen
   5227                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
   5228                                     + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
   5229                             return ri;
   5230                         }
   5231                     }
   5232                 } finally {
   5233                     if (changed) {
   5234                         if (DEBUG_PREFERRED) {
   5235                             Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
   5236                         }
   5237                         scheduleWritePackageRestrictionsLocked(userId);
   5238                     }
   5239                 }
   5240             }
   5241         }
   5242         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
   5243         return null;
   5244     }
   5245 
   5246     /*
   5247      * Returns if intent can be forwarded from the sourceUserId to the targetUserId
   5248      */
   5249     @Override
   5250     public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
   5251             int targetUserId) {
   5252         mContext.enforceCallingOrSelfPermission(
   5253                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
   5254         List<CrossProfileIntentFilter> matches =
   5255                 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
   5256         if (matches != null) {
   5257             int size = matches.size();
   5258             for (int i = 0; i < size; i++) {
   5259                 if (matches.get(i).getTargetUserId() == targetUserId) return true;
   5260             }
   5261         }
   5262         if (hasWebURI(intent)) {
   5263             // cross-profile app linking works only towards the parent.
   5264             final UserInfo parent = getProfileParent(sourceUserId);
   5265             synchronized(mPackages) {
   5266                 int flags = updateFlagsForResolve(0, parent.id, intent);
   5267                 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
   5268                         intent, resolvedType, flags, sourceUserId, parent.id);
   5269                 return xpDomainInfo != null;
   5270             }
   5271         }
   5272         return false;
   5273     }
   5274 
   5275     private UserInfo getProfileParent(int userId) {
   5276         final long identity = Binder.clearCallingIdentity();
   5277         try {
   5278             return sUserManager.getProfileParent(userId);
   5279         } finally {
   5280             Binder.restoreCallingIdentity(identity);
   5281         }
   5282     }
   5283 
   5284     private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
   5285             String resolvedType, int userId) {
   5286         CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
   5287         if (resolver != null) {
   5288             return resolver.queryIntent(intent, resolvedType, false, userId);
   5289         }
   5290         return null;
   5291     }
   5292 
   5293     @Override
   5294     public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
   5295             String resolvedType, int flags, int userId) {
   5296         try {
   5297             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
   5298 
   5299             return new ParceledListSlice<>(
   5300                     queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
   5301         } finally {
   5302             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
   5303         }
   5304     }
   5305 
   5306     private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
   5307             String resolvedType, int flags, int userId) {
   5308         if (!sUserManager.exists(userId)) return Collections.emptyList();
   5309         flags = updateFlagsForResolve(flags, userId, intent);
   5310         enforceCrossUserPermission(Binder.getCallingUid(), userId,
   5311                 false /* requireFullPermission */, false /* checkShell */,
   5312                 "query intent activities");
   5313         ComponentName comp = intent.getComponent();
   5314         if (comp == null) {
   5315             if (intent.getSelector() != null) {
   5316                 intent = intent.getSelector();
   5317                 comp = intent.getComponent();
   5318             }
   5319         }
   5320 
   5321         if (comp != null) {
   5322             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
   5323             final ActivityInfo ai = getActivityInfo(comp, flags, userId);
   5324             if (ai != null) {
   5325                 final ResolveInfo ri = new ResolveInfo();
   5326                 ri.activityInfo = ai;
   5327                 list.add(ri);
   5328             }
   5329             return list;
   5330         }
   5331 
   5332         // reader
   5333         boolean sortResult = false;
   5334         boolean addEphemeral = false;
   5335         boolean matchEphemeralPackage = false;
   5336         List<ResolveInfo> result;
   5337         final String pkgName = intent.getPackage();
   5338         synchronized (mPackages) {
   5339             if (pkgName == null) {
   5340                 List<CrossProfileIntentFilter> matchingFilters =
   5341                         getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
   5342                 // Check for results that need to skip the current profile.
   5343                 ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
   5344                         resolvedType, flags, userId);
   5345                 if (xpResolveInfo != null) {
   5346                     List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
   5347                     xpResult.add(xpResolveInfo);
   5348                     return filterIfNotSystemUser(xpResult, userId);
   5349                 }
   5350 
   5351                 // Check for results in the current profile.
   5352                 result = filterIfNotSystemUser(mActivities.queryIntent(
   5353                         intent, resolvedType, flags, userId), userId);
   5354                 addEphemeral =
   5355                         isEphemeralAllowed(intent, result, userId, false /*skipPackageCheck*/);
   5356 
   5357                 // Check for cross profile results.
   5358                 boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
   5359                 xpResolveInfo = queryCrossProfileIntents(
   5360                         matchingFilters, intent, resolvedType, flags, userId,
   5361                         hasNonNegativePriorityResult);
   5362                 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
   5363                     boolean isVisibleToUser = filterIfNotSystemUser(
   5364                             Collections.singletonList(xpResolveInfo), userId).size() > 0;
   5365                     if (isVisibleToUser) {
   5366                         result.add(xpResolveInfo);
   5367                         sortResult = true;
   5368                     }
   5369                 }
   5370                 if (hasWebURI(intent)) {
   5371                     CrossProfileDomainInfo xpDomainInfo = null;
   5372                     final UserInfo parent = getProfileParent(userId);
   5373                     if (parent != null) {
   5374                         xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
   5375                                 flags, userId, parent.id);
   5376                     }
   5377                     if (xpDomainInfo != null) {
   5378                         if (xpResolveInfo != null) {
   5379                             // If we didn't remove it, the cross-profile ResolveInfo would be twice
   5380                             // in the result.
   5381                             result.remove(xpResolveInfo);
   5382                         }
   5383                         if (result.size() == 0 && !addEphemeral) {
   5384                             result.add(xpDomainInfo.resolveInfo);
   5385                             return result;
   5386                         }
   5387                     }
   5388                     if (result.size() > 1 || addEphemeral) {
   5389                         result = filterCandidatesWithDomainPreferredActivitiesLPr(
   5390                                 intent, flags, result, xpDomainInfo, userId);
   5391                         sortResult = true;
   5392                     }
   5393                 }
   5394             } else {
   5395                 final PackageParser.Package pkg = mPackages.get(pkgName);
   5396                 if (pkg != null) {
   5397                     result = filterIfNotSystemUser(
   5398                             mActivities.queryIntentForPackage(
   5399                                     intent, resolvedType, flags, pkg.activities, userId),
   5400                             userId);
   5401                 } else {
   5402                     // the caller wants to resolve for a particular package; however, there
   5403                     // were no installed results, so, try to find an ephemeral result
   5404                     addEphemeral = isEphemeralAllowed(
   5405                             intent, null /*result*/, userId, true /*skipPackageCheck*/);
   5406                     matchEphemeralPackage = true;
   5407                     result = new ArrayList<ResolveInfo>();
   5408                 }
   5409             }
   5410         }
   5411         if (addEphemeral) {
   5412             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
   5413             final EphemeralResolveInfo ai = getEphemeralResolveInfo(
   5414                     mContext, mEphemeralResolverConnection, intent, resolvedType, userId,
   5415                     matchEphemeralPackage ? pkgName : null);
   5416             if (ai != null) {
   5417                 if (DEBUG_EPHEMERAL) {
   5418                     Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
   5419                 }
   5420                 final ResolveInfo ephemeralInstaller = new ResolveInfo(mEphemeralInstallerInfo);
   5421                 ephemeralInstaller.ephemeralResolveInfo = ai;
   5422                 // make sure this resolver is the default
   5423                 ephemeralInstaller.isDefault = true;
   5424                 ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
   5425                         | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
   5426                 // add a non-generic filter
   5427                 ephemeralInstaller.filter = new IntentFilter(intent.getAction());
   5428                 ephemeralInstaller.filter.addDataPath(
   5429                         intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
   5430                 result.add(ephemeralInstaller);
   5431             }
   5432             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
   5433         }
   5434         if (sortResult) {
   5435             Collections.sort(result, mResolvePrioritySorter);
   5436         }
   5437         return result;
   5438     }
   5439 
   5440     private static class CrossProfileDomainInfo {
   5441         /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
   5442         ResolveInfo resolveInfo;
   5443         /* Best domain verification status of the activities found in the other profile */
   5444         int bestDomainVerificationStatus;
   5445     }
   5446 
   5447     private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
   5448             String resolvedType, int flags, int sourceUserId, int parentUserId) {
   5449         if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
   5450                 sourceUserId)) {
   5451             return null;
   5452         }
   5453         List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
   5454                 resolvedType, flags, parentUserId);
   5455 
   5456         if (resultTargetUser == null || resultTargetUser.isEmpty()) {
   5457             return null;
   5458         }
   5459         CrossProfileDomainInfo result = null;
   5460         int size = resultTargetUser.size();
   5461         for (int i = 0; i < size; i++) {
   5462             ResolveInfo riTargetUser = resultTargetUser.get(i);
   5463             // Intent filter verification is only for filters that specify a host. So don't return
   5464             // those that handle all web uris.
   5465             if (riTargetUser.handleAllWebDataURI) {
   5466                 continue;
   5467             }
   5468             String packageName = riTargetUser.activityInfo.packageName;
   5469             PackageSetting ps = mSettings.mPackages.get(packageName);
   5470             if (ps == null) {
   5471                 continue;
   5472             }
   5473             long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
   5474             int status = (int)(verificationState >> 32);
   5475             if (result == null) {
   5476                 result = new CrossProfileDomainInfo();
   5477                 result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
   5478                         sourceUserId, parentUserId);
   5479                 result.bestDomainVerificationStatus = status;
   5480             } else {
   5481                 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
   5482                         result.bestDomainVerificationStatus);
   5483             }
   5484         }
   5485         // Don't consider matches with status NEVER across profiles.
   5486         if (result != null && result.bestDomainVerificationStatus
   5487                 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
   5488             return null;
   5489         }
   5490         return result;
   5491     }
   5492 
   5493     /**
   5494      * Verification statuses are ordered from the worse to the best, except for
   5495      * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
   5496      */
   5497     private int bestDomainVerificationStatus(int status1, int status2) {
   5498         if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
   5499             return status2;
   5500         }
   5501         if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
   5502             return status1;
   5503         }
   5504         return (int) MathUtils.max(status1, status2);
   5505     }
   5506 
   5507     private boolean isUserEnabled(int userId) {
   5508         long callingId = Binder.clearCallingIdentity();
   5509         try {
   5510             UserInfo userInfo = sUserManager.getUserInfo(userId);
   5511             return userInfo != null && userInfo.isEnabled();
   5512         } finally {
   5513             Binder.restoreCallingIdentity(callingId);
   5514         }
   5515     }
   5516 
   5517     /**
   5518      * Filter out activities with systemUserOnly flag set, when current user is not System.
   5519      *
   5520      * @return filtered list
   5521      */
   5522     private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
   5523         if (userId == UserHandle.USER_SYSTEM) {
   5524             return resolveInfos;
   5525         }
   5526         for (int i = resolveInfos.size() - 1; i >= 0; i--) {
   5527             ResolveInfo info = resolveInfos.get(i);
   5528             if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
   5529                 resolveInfos.remove(i);
   5530             }
   5531         }
   5532         return resolveInfos;
   5533     }
   5534 
   5535     /**
   5536      * @param resolveInfos list of resolve infos in descending priority order
   5537      * @return if the list contains a resolve info with non-negative priority
   5538      */
   5539     private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
   5540         return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
   5541     }
   5542 
   5543     private static boolean hasWebURI(Intent intent) {
   5544         if (intent.getData() == null) {
   5545             return false;
   5546         }
   5547         final String scheme = intent.getScheme();
   5548         if (TextUtils.isEmpty(scheme)) {
   5549             return false;
   5550         }
   5551         return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
   5552     }
   5553 
   5554     private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
   5555             int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
   5556             int userId) {
   5557         final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
   5558 
   5559         if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
   5560             Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
   5561                     candidates.size());
   5562         }
   5563 
   5564         ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
   5565         ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
   5566         ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
   5567         ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
   5568         ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
   5569         ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
   5570 
   5571         synchronized (mPackages) {
   5572             final int count = candidates.size();
   5573             // First, try to use linked apps. Partition the candidates into four lists:
   5574             // one for the final results, one for the "do not use ever", one for "undefined status"
   5575             // and finally one for "browser app type".
   5576             for (int n=0; n<count; n++) {
   5577                 ResolveInfo info = candidates.get(n);
   5578                 String packageName = info.activityInfo.packageName;
   5579                 PackageSetting ps = mSettings.mPackages.get(packageName);
   5580                 if (ps != null) {
   5581                     // Add to the special match all list (Browser use case)
   5582                     if (info.handleAllWebDataURI) {
   5583                         matchAllList.add(info);
   5584                         continue;
   5585                     }
   5586                     // Try to get the status from User settings first
   5587                     long packedStatus = getDomainVerificationStatusLPr(ps, userId);
   5588                     int status = (int)(packedStatus >> 32);
   5589                     int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
   5590                     if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
   5591                         if (DEBUG_DOMAIN_VERIFICATION) {
   5592                             Slog.i(TAG, "  + always: " + info.activityInfo.packageName
   5593                                     + " : linkgen=" + linkGeneration);
   5594                         }
   5595                         // Use link-enabled generation as preferredOrder, i.e.
   5596                         // prefer newly-enabled over earlier-enabled.
   5597                         info.preferredOrder = linkGeneration;
   5598                         alwaysList.add(info);
   5599                     } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
   5600                         if (DEBUG_DOMAIN_VERIFICATION) {
   5601                             Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
   5602                         }
   5603                         neverList.add(info);
   5604                     } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
   5605                         if (DEBUG_DOMAIN_VERIFICATION) {
   5606                             Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
   5607                         }
   5608                         alwaysAskList.add(info);
   5609                     } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
   5610                             status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
   5611                         if (DEBUG_DOMAIN_VERIFICATION) {
   5612                             Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
   5613                         }
   5614                         undefinedList.add(info);
   5615                     }
   5616                 }
   5617             }
   5618 
   5619             // We'll want to include browser possibilities in a few cases
   5620             boolean includeBrowser = false;
   5621 
   5622             // First try to add the "always" resolution(s) for the current user, if any
   5623             if (alwaysList.size() > 0) {
   5624                 result.addAll(alwaysList);
   5625             } else {
   5626                 // Add all undefined apps as we want them to appear in the disambiguation dialog.
   5627                 result.addAll(undefinedList);
   5628                 // Maybe add one for the other profile.
   5629                 if (xpDomainInfo != null && (
   5630                         xpDomainInfo.bestDomainVerificationStatus
   5631                         != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
   5632                     result.add(xpDomainInfo.resolveInfo);
   5633                 }
   5634                 includeBrowser = true;
   5635             }
   5636 
   5637             // The presence of any 'always ask' alternatives means we'll also offer browsers.
   5638             // If there were 'always' entries their preferred order has been set, so we also
   5639             // back that off to make the alternatives equivalent
   5640             if (alwaysAskList.size() > 0) {
   5641                 for (ResolveInfo i : result) {
   5642                     i.preferredOrder = 0;
   5643                 }
   5644                 result.addAll(alwaysAskList);
   5645                 includeBrowser = true;
   5646             }
   5647 
   5648             if (includeBrowser) {
   5649                 // Also add browsers (all of them or only the default one)
   5650                 if (DEBUG_DOMAIN_VERIFICATION) {
   5651                     Slog.v(TAG, "   ...including browsers in candidate set");
   5652                 }
   5653                 if ((matchFlags & MATCH_ALL) != 0) {
   5654                     result.addAll(matchAllList);
   5655                 } else {
   5656                     // Browser/generic handling case.  If there's a default browser, go straight
   5657                     // to that (but only if there is no other higher-priority match).
   5658                     final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
   5659                     int maxMatchPrio = 0;
   5660                     ResolveInfo defaultBrowserMatch = null;
   5661                     final int numCandidates = matchAllList.size();
   5662                     for (int n = 0; n < numCandidates; n++) {
   5663                         ResolveInfo info = matchAllList.get(n);
   5664                         // track the highest overall match priority...
   5665                         if (info.priority > maxMatchPrio) {
   5666                             maxMatchPrio = info.priority;
   5667                         }
   5668                         // ...and the highest-priority default browser match
   5669                         if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
   5670                             if (defaultBrowserMatch == null
   5671                                     || (defaultBrowserMatch.priority < info.priority)) {
   5672                                 if (debug) {
   5673                                     Slog.v(TAG, "Considering default browser match " + info);
   5674                                 }
   5675                                 defaultBrowserMatch = info;
   5676                             }
   5677                         }
   5678                     }
   5679                     if (defaultBrowserMatch != null
   5680                             && defaultBrowserMatch.priority >= maxMatchPrio
   5681                             && !TextUtils.isEmpty(defaultBrowserPackageName))
   5682                     {
   5683                         if (debug) {
   5684                             Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
   5685                         }
   5686                         result.add(defaultBrowserMatch);
   5687                     } else {
   5688                         result.addAll(matchAllList);
   5689                     }
   5690                 }
   5691 
   5692                 // If there is nothing selected, add all candidates and remove the ones that the user
   5693                 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
   5694                 if (result.size() == 0) {
   5695                     result.addAll(candidates);
   5696                     result.removeAll(neverList);
   5697                 }
   5698             }
   5699         }
   5700         if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
   5701             Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
   5702                     result.size());
   5703             for (ResolveInfo info : result) {
   5704                 Slog.v(TAG, "  + " + info.activityInfo);
   5705             }
   5706         }
   5707         return result;
   5708     }
   5709 
   5710     // Returns a packed value as a long:
   5711     //
   5712     // high 'int'-sized word: link status: undefined/ask/never/always.
   5713     // low 'int'-sized word: relative priority among 'always' results.
   5714     private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
   5715         long result = ps.getDomainVerificationStatusForUser(userId);
   5716         // if none available, get the master status
   5717         if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
   5718             if (ps.getIntentFilterVerificationInfo() != null) {
   5719                 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
   5720             }
   5721         }
   5722         return result;
   5723     }
   5724 
   5725     private ResolveInfo querySkipCurrentProfileIntents(
   5726             List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
   5727             int flags, int sourceUserId) {
   5728         if (matchingFilters != null) {
   5729             int size = matchingFilters.size();
   5730             for (int i = 0; i < size; i ++) {
   5731                 CrossProfileIntentFilter filter = matchingFilters.get(i);
   5732                 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
   5733                     // Checking if there are activities in the target user that can handle the
   5734                     // intent.
   5735                     ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
   5736                             resolvedType, flags, sourceUserId);
   5737                     if (resolveInfo != null) {
   5738                         return resolveInfo;
   5739                     }
   5740                 }
   5741             }
   5742         }
   5743         return null;
   5744     }
   5745 
   5746     // Return matching ResolveInfo in target user if any.
   5747     private ResolveInfo queryCrossProfileIntents(
   5748             List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
   5749             int flags, int sourceUserId, boolean matchInCurrentProfile) {
   5750         if (matchingFilters != null) {
   5751             // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
   5752             // match the same intent. For performance reasons, it is better not to
   5753             // run queryIntent twice for the same userId
   5754             SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
   5755             int size = matchingFilters.size();
   5756             for (int i = 0; i < size; i++) {
   5757                 CrossProfileIntentFilter filter = matchingFilters.get(i);
   5758                 int targetUserId = filter.getTargetUserId();
   5759                 boolean skipCurrentProfile =
   5760                         (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
   5761                 boolean skipCurrentProfileIfNoMatchFound =
   5762                         (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
   5763                 if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
   5764                         && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
   5765                     // Checking if there are activities in the target user that can handle the
   5766                     // intent.
   5767                     ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
   5768                             resolvedType, flags, sourceUserId);
   5769                     if (resolveInfo != null) return resolveInfo;
   5770                     alreadyTriedUserIds.put(targetUserId, true);
   5771                 }
   5772             }
   5773         }
   5774         return null;
   5775     }
   5776 
   5777     /**
   5778      * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
   5779      * will forward the intent to the filter's target user.
   5780      * Otherwise, returns null.
   5781      */
   5782     private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
   5783             String resolvedType, int flags, int sourceUserId) {
   5784         int targetUserId = filter.getTargetUserId();
   5785         List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
   5786                 resolvedType, flags, targetUserId);
   5787         if (resultTargetUser != null && isUserEnabled(targetUserId)) {
   5788             // If all the matches in the target profile are suspended, return null.
   5789             for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
   5790                 if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
   5791                         & ApplicationInfo.FLAG_SUSPENDED) == 0) {
   5792                     return createForwardingResolveInfoUnchecked(filter, sourceUserId,
   5793                             targetUserId);
   5794                 }
   5795             }
   5796         }
   5797         return null;
   5798     }
   5799 
   5800     private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
   5801             int sourceUserId, int targetUserId) {
   5802         ResolveInfo forwardingResolveInfo = new ResolveInfo();
   5803         long ident = Binder.clearCallingIdentity();
   5804         boolean targetIsProfile;
   5805         try {
   5806             targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
   5807         } finally {
   5808             Binder.restoreCallingIdentity(ident);
   5809         }
   5810         String className;
   5811         if (targetIsProfile) {
   5812             className = FORWARD_INTENT_TO_MANAGED_PROFILE;
   5813         } else {
   5814             className = FORWARD_INTENT_TO_PARENT;
   5815         }
   5816         ComponentName forwardingActivityComponentName = new ComponentName(
   5817                 mAndroidApplication.packageName, className);
   5818         ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
   5819                 sourceUserId);
   5820         if (!targetIsProfile) {
   5821             forwardingActivityInfo.showUserIcon = targetUserId;
   5822             forwardingResolveInfo.noResourceId = true;
   5823         }
   5824         forwardingResolveInfo.activityInfo = forwardingActivityInfo;
   5825         forwardingResolveInfo.priority = 0;
   5826         forwardingResolveInfo.preferredOrder = 0;
   5827         forwardingResolveInfo.match = 0;
   5828         forwardingResolveInfo.isDefault = true;
   5829         forwardingResolveInfo.filter = filter;
   5830         forwardingResolveInfo.targetUserId = targetUserId;
   5831         return forwardingResolveInfo;
   5832     }
   5833 
   5834     @Override
   5835     public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
   5836             Intent[] specifics, String[] specificTypes, Intent intent,
   5837             String resolvedType, int flags, int userId) {
   5838         return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
   5839                 specificTypes, intent, resolvedType, flags, userId));
   5840     }
   5841 
   5842     private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
   5843             Intent[] specifics, String[] specificTypes, Intent intent,
   5844             String resolvedType, int flags, int userId) {
   5845         if (!sUserManager.exists(userId)) return Collections.emptyList();
   5846         flags = updateFlagsForResolve(flags, userId, intent);
   5847         enforceCrossUserPermission(Binder.getCallingUid(), userId,
   5848                 false /* requireFullPermission */, false /* checkShell */,
   5849                 "query intent activity options");
   5850         final String resultsAction = intent.getAction();
   5851 
   5852         final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
   5853                 | PackageManager.GET_RESOLVED_FILTER, userId);
   5854 
   5855         if (DEBUG_INTENT_MATCHING) {
   5856             Log.v(TAG, "Query " + intent + ": " + results);
   5857         }
   5858 
   5859         int specificsPos = 0;
   5860         int N;
   5861 
   5862         // todo: note that the algorithm used here is O(N^2).  This
   5863         // isn't a problem in our current environment, but if we start running
   5864         // into situations where we have more than 5 or 10 matches then this
   5865         // should probably be changed to something smarter...
   5866 
   5867         // First we go through and resolve each of the specific items
   5868         // that were supplied, taking care of removing any corresponding
   5869         // duplicate items in the generic resolve list.
   5870         if (specifics != null) {
   5871             for (int i=0; i<specifics.length; i++) {
   5872                 final Intent sintent = specifics[i];
   5873                 if (sintent == null) {
   5874                     continue;
   5875                 }
   5876 
   5877                 if (DEBUG_INTENT_MATCHING) {
   5878                     Log.v(TAG, "Specific #" + i + ": " + sintent);
   5879                 }
   5880 
   5881                 String action = sintent.getAction();
   5882                 if (resultsAction != null && resultsAction.equals(action)) {
   5883                     // If this action was explicitly requested, then don't
   5884                     // remove things that have it.
   5885                     action = null;
   5886                 }
   5887 
   5888                 ResolveInfo ri = null;
   5889                 ActivityInfo ai = null;
   5890 
   5891                 ComponentName comp = sintent.getComponent();
   5892                 if (comp == null) {
   5893                     ri = resolveIntent(
   5894                         sintent,
   5895                         specificTypes != null ? specificTypes[i] : null,
   5896                             flags, userId);
   5897                     if (ri == null) {
   5898                         continue;
   5899                     }
   5900                     if (ri == mResolveInfo) {
   5901                         // ACK!  Must do something better with this.
   5902                     }
   5903                     ai = ri.activityInfo;
   5904                     comp = new ComponentName(ai.applicationInfo.packageName,
   5905                             ai.name);
   5906                 } else {
   5907                     ai = getActivityInfo(comp, flags, userId);
   5908                     if (ai == null) {
   5909                         continue;
   5910                     }
   5911                 }
   5912 
   5913                 // Look for any generic query activities that are duplicates
   5914                 // of this specific one, and remove them from the results.
   5915                 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
   5916                 N = results.size();
   5917                 int j;
   5918                 for (j=specificsPos; j<N; j++) {
   5919                     ResolveInfo sri = results.get(j);
   5920                     if ((sri.activityInfo.name.equals(comp.getClassName())
   5921                             && sri.activityInfo.applicationInfo.packageName.equals(
   5922                                     comp.getPackageName()))
   5923                         || (action != null && sri.filter.matchAction(action))) {
   5924                         results.remove(j);
   5925                         if (DEBUG_INTENT_MATCHING) Log.v(
   5926                             TAG, "Removing duplicate item from " + j
   5927                             + " due to specific " + specificsPos);
   5928                         if (ri == null) {
   5929                             ri = sri;
   5930                         }
   5931                         j--;
   5932                         N--;
   5933                     }
   5934                 }
   5935 
   5936                 // Add this specific item to its proper place.
   5937                 if (ri == null) {
   5938                     ri = new ResolveInfo();
   5939                     ri.activityInfo = ai;
   5940                 }
   5941                 results.add(specificsPos, ri);
   5942                 ri.specificIndex = i;
   5943                 specificsPos++;
   5944             }
   5945         }
   5946 
   5947         // Now we go through the remaining generic results and remove any
   5948         // duplicate actions that are found here.
   5949         N = results.size();
   5950         for (int i=specificsPos; i<N-1; i++) {
   5951             final ResolveInfo rii = results.get(i);
   5952             if (rii.filter == null) {
   5953                 continue;
   5954             }
   5955 
   5956             // Iterate over all of the actions of this result's intent
   5957             // filter...  typically this should be just one.
   5958             final Iterator<String> it = rii.filter.actionsIterator();
   5959             if (it == null) {
   5960                 continue;
   5961             }
   5962             while (it.hasNext()) {
   5963                 final String action = it.next();
   5964                 if (resultsAction != null && resultsAction.equals(action)) {
   5965                     // If this action was explicitly requested, then don't
   5966                     // remove things that have it.
   5967                     continue;
   5968                 }
   5969                 for (int j=i+1; j<N; j++) {
   5970                     final ResolveInfo rij = results.get(j);
   5971                     if (rij.filter != null && rij.filter.hasAction(action)) {
   5972                         results.remove(j);
   5973                         if (DEBUG_INTENT_MATCHING) Log.v(
   5974                             TAG, "Removing duplicate item from " + j
   5975                             + " due to action " + action + " at " + i);
   5976                         j--;
   5977                         N--;
   5978                     }
   5979                 }
   5980             }
   5981 
   5982             // If the caller didn't request filter information, drop it now
   5983             // so we don't have to marshall/unmarshall it.
   5984             if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
   5985                 rii.filter = null;
   5986             }
   5987         }
   5988 
   5989         // Filter out the caller activity if so requested.
   5990         if (caller != null) {
   5991             N = results.size();
   5992             for (int i=0; i<N; i++) {
   5993                 ActivityInfo ainfo = results.get(i).activityInfo;
   5994                 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
   5995                         && caller.getClassName().equals(ainfo.name)) {
   5996                     results.remove(i);
   5997                     break;
   5998                 }
   5999             }
   6000         }
   6001 
   6002         // If the caller didn't request filter information,
   6003         // drop them now so we don't have to
   6004         // marshall/unmarshall it.
   6005         if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
   6006             N = results.size();
   6007             for (int i=0; i<N; i++) {
   6008                 results.get(i).filter = null;
   6009             }
   6010         }
   6011 
   6012         if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
   6013         return results;
   6014     }
   6015 
   6016     @Override
   6017     public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
   6018             String resolvedType, int flags, int userId) {
   6019         return new ParceledListSlice<>(
   6020                 queryIntentReceiversInternal(intent, resolvedType, flags, userId));
   6021     }
   6022 
   6023     private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
   6024             String resolvedType, int flags, int userId) {
   6025         if (!sUserManager.exists(userId)) return Collections.emptyList();
   6026         flags = updateFlagsForResolve(flags, userId, intent);
   6027         ComponentName comp = intent.getComponent();
   6028         if (comp == null) {
   6029             if (intent.getSelector() != null) {
   6030                 intent = intent.getSelector();
   6031                 comp = intent.getComponent();
   6032             }
   6033         }
   6034         if (comp != null) {
   6035             List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
   6036             ActivityInfo ai = getReceiverInfo(comp, flags, userId);
   6037             if (ai != null) {
   6038                 ResolveInfo ri = new ResolveInfo();
   6039                 ri.activityInfo = ai;
   6040                 list.add(ri);
   6041             }
   6042             return list;
   6043         }
   6044 
   6045         // reader
   6046         synchronized (mPackages) {
   6047             String pkgName = intent.getPackage();
   6048             if (pkgName == null) {
   6049                 return mReceivers.queryIntent(intent, resolvedType, flags, userId);
   6050             }
   6051             final PackageParser.Package pkg = mPackages.get(pkgName);
   6052             if (pkg != null) {
   6053                 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
   6054                         userId);
   6055             }
   6056             return Collections.emptyList();
   6057         }
   6058     }
   6059 
   6060     @Override
   6061     public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
   6062         if (!sUserManager.exists(userId)) return null;
   6063         flags = updateFlagsForResolve(flags, userId, intent);
   6064         List<ResolveInfo> query = queryIntentServicesInternal(intent, resolvedType, flags, userId);
   6065         if (query != null) {
   6066             if (query.size() >= 1) {
   6067                 // If there is more than one service with the same priority,
   6068                 // just arbitrarily pick the first one.
   6069                 return query.get(0);
   6070             }
   6071         }
   6072         return null;
   6073     }
   6074 
   6075     @Override
   6076     public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
   6077             String resolvedType, int flags, int userId) {
   6078         return new ParceledListSlice<>(
   6079                 queryIntentServicesInternal(intent, resolvedType, flags, userId));
   6080     }
   6081 
   6082     private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
   6083             String resolvedType, int flags, int userId) {
   6084         if (!sUserManager.exists(userId)) return Collections.emptyList();
   6085         flags = updateFlagsForResolve(flags, userId, intent);
   6086         ComponentName comp = intent.getComponent();
   6087         if (comp == null) {
   6088             if (intent.getSelector() != null) {
   6089                 intent = intent.getSelector();
   6090                 comp = intent.getComponent();
   6091             }
   6092         }
   6093         if (comp != null) {
   6094             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
   6095             final ServiceInfo si = getServiceInfo(comp, flags, userId);
   6096             if (si != null) {
   6097                 final ResolveInfo ri = new ResolveInfo();
   6098                 ri.serviceInfo = si;
   6099                 list.add(ri);
   6100             }
   6101             return list;
   6102         }
   6103 
   6104         // reader
   6105         synchronized (mPackages) {
   6106             String pkgName = intent.getPackage();
   6107             if (pkgName == null) {
   6108                 return mServices.queryIntent(intent, resolvedType, flags, userId);
   6109             }
   6110             final PackageParser.Package pkg = mPackages.get(pkgName);
   6111             if (pkg != null) {
   6112                 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
   6113                         userId);
   6114             }
   6115             return Collections.emptyList();
   6116         }
   6117     }
   6118 
   6119     @Override
   6120     public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
   6121             String resolvedType, int flags, int userId) {
   6122         return new ParceledListSlice<>(
   6123                 queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
   6124     }
   6125 
   6126     private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
   6127             Intent intent, String resolvedType, int flags, int userId) {
   6128         if (!sUserManager.exists(userId)) return Collections.emptyList();
   6129         flags = updateFlagsForResolve(flags, userId, intent);
   6130         ComponentName comp = intent.getComponent();
   6131         if (comp == null) {
   6132             if (intent.getSelector() != null) {
   6133                 intent = intent.getSelector();
   6134                 comp = intent.getComponent();
   6135             }
   6136         }
   6137         if (comp != null) {
   6138             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
   6139             final ProviderInfo pi = getProviderInfo(comp, flags, userId);
   6140             if (pi != null) {
   6141                 final ResolveInfo ri = new ResolveInfo();
   6142                 ri.providerInfo = pi;
   6143                 list.add(ri);
   6144             }
   6145             return list;
   6146         }
   6147 
   6148         // reader
   6149         synchronized (mPackages) {
   6150             String pkgName = intent.getPackage();
   6151             if (pkgName == null) {
   6152                 return mProviders.queryIntent(intent, resolvedType, flags, userId);
   6153             }
   6154             final PackageParser.Package pkg = mPackages.get(pkgName);
   6155             if (pkg != null) {
   6156                 return mProviders.queryIntentForPackage(
   6157                         intent, resolvedType, flags, pkg.providers, userId);
   6158             }
   6159             return Collections.emptyList();
   6160         }
   6161     }
   6162 
   6163     @Override
   6164     public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
   6165         if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
   6166         flags = updateFlagsForPackage(flags, userId, null);
   6167         final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
   6168         enforceCrossUserPermission(Binder.getCallingUid(), userId,
   6169                 true /* requireFullPermission */, false /* checkShell */,
   6170                 "get installed packages");
   6171 
   6172         // writer
   6173         synchronized (mPackages) {
   6174             ArrayList<PackageInfo> list;
   6175             if (listUninstalled) {
   6176                 list = new ArrayList<PackageInfo>(mSettings.mPackages.size());
   6177                 for (PackageSetting ps : mSettings.mPackages.values()) {
   6178                     final PackageInfo pi;
   6179                     if (ps.pkg != null) {
   6180                         pi = generatePackageInfo(ps, flags, userId);
   6181                     } else {
   6182                         pi = generatePackageInfo(ps, flags, userId);
   6183                     }
   6184                     if (pi != null) {
   6185                         list.add(pi);
   6186                     }
   6187                 }
   6188             } else {
   6189                 list = new ArrayList<PackageInfo>(mPackages.size());
   6190                 for (PackageParser.Package p : mPackages.values()) {
   6191                     final PackageInfo pi =
   6192                             generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
   6193                     if (pi != null) {
   6194                         list.add(pi);
   6195                     }
   6196                 }
   6197             }
   6198 
   6199             return new ParceledListSlice<PackageInfo>(list);
   6200         }
   6201     }
   6202 
   6203     private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
   6204             String[] permissions, boolean[] tmp, int flags, int userId) {
   6205         int numMatch = 0;
   6206         final PermissionsState permissionsState = ps.getPermissionsState();
   6207         for (int i=0; i<permissions.length; i++) {
   6208             final String permission = permissions[i];
   6209             if (permissionsState.hasPermission(permission, userId)) {
   6210                 tmp[i] = true;
   6211                 numMatch++;
   6212             } else {
   6213                 tmp[i] = false;
   6214             }
   6215         }
   6216         if (numMatch == 0) {
   6217             return;
   6218         }
   6219         final PackageInfo pi;
   6220         if (ps.pkg != null) {
   6221             pi = generatePackageInfo(ps, flags, userId);
   6222         } else {
   6223             pi = generatePackageInfo(ps, flags, userId);
   6224         }
   6225         // The above might return null in cases of uninstalled apps or install-state
   6226         // skew across users/profiles.
   6227         if (pi != null) {
   6228             if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
   6229                 if (numMatch == permissions.length) {
   6230                     pi.requestedPermissions = permissions;
   6231                 } else {
   6232                     pi.requestedPermissions = new String[numMatch];
   6233                     numMatch = 0;
   6234                     for (int i=0; i<permissions.length; i++) {
   6235                         if (tmp[i]) {
   6236                             pi.requestedPermissions[numMatch] = permissions[i];
   6237                             numMatch++;
   6238                         }
   6239                     }
   6240                 }
   6241             }
   6242             list.add(pi);
   6243         }
   6244     }
   6245 
   6246     @Override
   6247     public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
   6248             String[] permissions, int flags, int userId) {
   6249         if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
   6250         flags = updateFlagsForPackage(flags, userId, permissions);
   6251         final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
   6252 
   6253         // writer
   6254         synchronized (mPackages) {
   6255             ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
   6256             boolean[] tmpBools = new boolean[permissions.length];
   6257             if (listUninstalled) {
   6258                 for (PackageSetting ps : mSettings.mPackages.values()) {
   6259                     addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId);
   6260                 }
   6261             } else {
   6262                 for (PackageParser.Package pkg : mPackages.values()) {
   6263                     PackageSetting ps = (PackageSetting)pkg.mExtras;
   6264                     if (ps != null) {
   6265                         addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
   6266                                 userId);
   6267                     }
   6268                 }
   6269             }
   6270 
   6271             return new ParceledListSlice<PackageInfo>(list);
   6272         }
   6273     }
   6274 
   6275     @Override
   6276     public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
   6277         if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
   6278         flags = updateFlagsForApplication(flags, userId, null);
   6279         final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
   6280 
   6281         // writer
   6282         synchronized (mPackages) {
   6283             ArrayList<ApplicationInfo> list;
   6284             if (listUninstalled) {
   6285                 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size());
   6286                 for (PackageSetting ps : mSettings.mPackages.values()) {
   6287                     ApplicationInfo ai;
   6288                     if (ps.pkg != null) {
   6289                         ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
   6290                                 ps.readUserState(userId), userId);
   6291                     } else {
   6292                         ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
   6293                     }
   6294                     if (ai != null) {
   6295                         list.add(ai);
   6296                     }
   6297                 }
   6298             } else {
   6299                 list = new ArrayList<ApplicationInfo>(mPackages.size());
   6300                 for (PackageParser.Package p : mPackages.values()) {
   6301                     if (p.mExtras != null) {
   6302                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
   6303                                 ((PackageSetting)p.mExtras).readUserState(userId), userId);
   6304                         if (ai != null) {
   6305                             list.add(ai);
   6306                         }
   6307                     }
   6308                 }
   6309             }
   6310 
   6311             return new ParceledListSlice<ApplicationInfo>(list);
   6312         }
   6313     }
   6314 
   6315     @Override
   6316     public ParceledListSlice<EphemeralApplicationInfo> getEphemeralApplications(int userId) {
   6317         if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
   6318             return null;
   6319         }
   6320 
   6321         mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS,
   6322                 "getEphemeralApplications");
   6323         enforceCrossUserPermission(Binder.getCallingUid(), userId,
   6324                 true /* requireFullPermission */, false /* checkShell */,
   6325                 "getEphemeralApplications");
   6326         synchronized (mPackages) {
   6327             List<EphemeralApplicationInfo> ephemeralApps = mEphemeralApplicationRegistry
   6328                     .getEphemeralApplicationsLPw(userId);
   6329             if (ephemeralApps != null) {
   6330                 return new ParceledListSlice<>(ephemeralApps);
   6331             }
   6332         }
   6333         return null;
   6334     }
   6335 
   6336     @Override
   6337     public boolean isEphemeralApplication(String packageName, int userId) {
   6338         enforceCrossUserPermission(Binder.getCallingUid(), userId,
   6339                 true /* requireFullPermission */, false /* checkShell */,
   6340                 "isEphemeral");
   6341         if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
   6342             return false;
   6343         }
   6344 
   6345         if (!isCallerSameApp(packageName)) {
   6346             return false;
   6347         }
   6348         synchronized (mPackages) {
   6349             PackageParser.Package pkg = mPackages.get(packageName);
   6350             if (pkg != null) {
   6351                 return pkg.applicationInfo.isEphemeralApp();
   6352             }
   6353         }
   6354         return false;
   6355     }
   6356 
   6357     @Override
   6358     public byte[] getEphemeralApplicationCookie(String packageName, int userId) {
   6359         if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
   6360             return null;
   6361         }
   6362 
   6363         enforceCrossUserPermission(Binder.getCallingUid(), userId,
   6364                 true /* requireFullPermission */, false /* checkShell */,
   6365                 "getCookie");
   6366         if (!isCallerSameApp(packageName)) {
   6367             return null;
   6368         }
   6369         synchronized (mPackages) {
   6370             return mEphemeralApplicationRegistry.getEphemeralApplicationCookieLPw(
   6371                     packageName, userId);
   6372         }
   6373     }
   6374 
   6375     @Override
   6376     public boolean setEphemeralApplicationCookie(String packageName, byte[] cookie, int userId) {
   6377         if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
   6378             return true;
   6379         }
   6380 
   6381         enforceCrossUserPermission(Binder.getCallingUid(), userId,
   6382                 true /* requireFullPermission */, true /* checkShell */,
   6383                 "setCookie");
   6384         if (!isCallerSameApp(packageName)) {
   6385             return false;
   6386         }
   6387         synchronized (mPackages) {
   6388             return mEphemeralApplicationRegistry.setEphemeralApplicationCookieLPw(
   6389                     packageName, cookie, userId);
   6390         }
   6391     }
   6392 
   6393     @Override
   6394     public Bitmap getEphemeralApplicationIcon(String packageName, int userId) {
   6395         if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
   6396             return null;
   6397         }
   6398 
   6399         mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS,
   6400                 "getEphemeralApplicationIcon");
   6401         enforceCrossUserPermission(Binder.getCallingUid(), userId,
   6402                 true /* requireFullPermission */, false /* checkShell */,
   6403                 "getEphemeralApplicationIcon");
   6404         synchronized (mPackages) {
   6405             return mEphemeralApplicationRegistry.getEphemeralApplicationIconLPw(
   6406                     packageName, userId);
   6407         }
   6408     }
   6409 
   6410     private boolean isCallerSameApp(String packageName) {
   6411         PackageParser.Package pkg = mPackages.get(packageName);
   6412         return pkg != null
   6413                 && UserHandle.getAppId(Binder.getCallingUid()) == pkg.applicationInfo.uid;
   6414     }
   6415 
   6416     @Override
   6417     public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
   6418         return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
   6419     }
   6420 
   6421     private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
   6422         final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
   6423 
   6424         // reader
   6425         synchronized (mPackages) {
   6426             final Iterator<PackageParser.Package> i = mPackages.values().iterator();
   6427             final int userId = UserHandle.getCallingUserId();
   6428             while (i.hasNext()) {
   6429                 final PackageParser.Package p = i.next();
   6430                 if (p.applicationInfo == null) continue;
   6431 
   6432                 final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
   6433                         && !p.applicationInfo.isDirectBootAware();
   6434                 final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
   6435                         && p.applicationInfo.isDirectBootAware();
   6436 
   6437                 if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
   6438                         && (!mSafeMode || isSystemApp(p))
   6439                         && (matchesUnaware || matchesAware)) {
   6440                     PackageSetting ps = mSettings.mPackages.get(p.packageName);
   6441                     if (ps != null) {
   6442                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
   6443                                 ps.readUserState(userId), userId);
   6444                         if (ai != null) {
   6445                             finalList.add(ai);
   6446                         }
   6447                     }
   6448                 }
   6449             }
   6450         }
   6451 
   6452         return finalList;
   6453     }
   6454 
   6455     @Override
   6456     public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
   6457         if (!sUserManager.exists(userId)) return null;
   6458         flags = updateFlagsForComponent(flags, userId, name);
   6459         // reader
   6460         synchronized (mPackages) {
   6461             final PackageParser.Provider provider = mProvidersByAuthority.get(name);
   6462             PackageSetting ps = provider != null
   6463                     ? mSettings.mPackages.get(provider.owner.packageName)
   6464                     : null;
   6465             return ps != null
   6466                     && mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)
   6467                     ? PackageParser.generateProviderInfo(provider, flags,
   6468                             ps.readUserState(userId), userId)
   6469                     : null;
   6470         }
   6471     }
   6472 
   6473     /**
   6474      * @deprecated
   6475      */
   6476     @Deprecated
   6477     public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
   6478         // reader
   6479         synchronized (mPackages) {
   6480             final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
   6481                     .entrySet().iterator();
   6482             final int userId = UserHandle.getCallingUserId();
   6483             while (i.hasNext()) {
   6484                 Map.Entry<String, PackageParser.Provider> entry = i.next();
   6485                 PackageParser.Provider p = entry.getValue();
   6486                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
   6487 
   6488                 if (ps != null && p.syncable
   6489                         && (!mSafeMode || (p.info.applicationInfo.flags
   6490                                 &ApplicationInfo.FLAG_SYSTEM) != 0)) {
   6491                     ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
   6492                             ps.readUserState(userId), userId);
   6493                     if (info != null) {
   6494                         outNames.add(entry.getKey());
   6495                         outInfo.add(info);
   6496                     }
   6497                 }
   6498             }
   6499         }
   6500     }
   6501 
   6502     @Override
   6503     public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
   6504             int uid, int flags) {
   6505         final int userId = processName != null ? UserHandle.getUserId(uid)
   6506                 : UserHandle.getCallingUserId();
   6507         if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
   6508         flags = updateFlagsForComponent(flags, userId, processName);
   6509 
   6510         ArrayList<ProviderInfo> finalList = null;
   6511         // reader
   6512         synchronized (mPackages) {
   6513             final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
   6514             while (i.hasNext()) {
   6515                 final PackageParser.Provider p = i.next();
   6516                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
   6517                 if (ps != null && p.info.authority != null
   6518                         && (processName == null
   6519                                 || (p.info.processName.equals(processName)
   6520                                         && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
   6521                         && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
   6522                     if (finalList == null) {
   6523                         finalList = new ArrayList<ProviderInfo>(3);
   6524                     }
   6525                     ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
   6526                             ps.readUserState(userId), userId);
   6527                     if (info != null) {
   6528                         finalList.add(info);
   6529                     }
   6530                 }
   6531             }
   6532         }
   6533 
   6534         if (finalList != null) {
   6535             Collections.sort(finalList, mProviderInitOrderSorter);
   6536             return new ParceledListSlice<ProviderInfo>(finalList);
   6537         }
   6538 
   6539         return ParceledListSlice.emptyList();
   6540     }
   6541 
   6542     @Override
   6543     public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) {
   6544         // reader
   6545         synchronized (mPackages) {
   6546             final PackageParser.Instrumentation i = mInstrumentation.get(name);
   6547             return PackageParser.generateInstrumentationInfo(i, flags);
   6548         }
   6549     }
   6550 
   6551     @Override
   6552     public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
   6553             String targetPackage, int flags) {
   6554         return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
   6555     }
   6556 
   6557     private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
   6558             int flags) {
   6559         ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
   6560 
   6561         // reader
   6562         synchronized (mPackages) {
   6563             final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
   6564             while (i.hasNext()) {
   6565                 final PackageParser.Instrumentation p = i.next();
   6566                 if (targetPackage == null
   6567                         || targetPackage.equals(p.info.targetPackage)) {
   6568                     InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
   6569                             flags);
   6570                     if (ii != null) {
   6571                         finalList.add(ii);
   6572                     }
   6573                 }
   6574             }
   6575         }
   6576 
   6577         return finalList;
   6578     }
   6579 
   6580     private void createIdmapsForPackageLI(PackageParser.Package pkg) {
   6581         ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName);
   6582         if (overlays == null) {
   6583             Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages");
   6584             return;
   6585         }
   6586         for (PackageParser.Package opkg : overlays.values()) {
   6587             // Not much to do if idmap fails: we already logged the error
   6588             // and we certainly don't want to abort installation of pkg simply
   6589             // because an overlay didn't fit properly. For these reasons,
   6590             // ignore the return value of createIdmapForPackagePairLI.
   6591             createIdmapForPackagePairLI(pkg, opkg);
   6592         }
   6593     }
   6594 
   6595     private boolean createIdmapForPackagePairLI(PackageParser.Package pkg,
   6596             PackageParser.Package opkg) {
   6597         if (!opkg.mTrustedOverlay) {
   6598             Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " +
   6599                     opkg.baseCodePath + ": overlay not trusted");
   6600             return false;
   6601         }
   6602         ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName);
   6603         if (overlaySet == null) {
   6604             Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " +
   6605                     opkg.baseCodePath + " but target package has no known overlays");
   6606             return false;
   6607         }
   6608         final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
   6609         // TODO: generate idmap for split APKs
   6610         try {
   6611             mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid);
   6612         } catch (InstallerException e) {
   6613             Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and "
   6614                     + opkg.baseCodePath);
   6615             return false;
   6616         }
   6617         PackageParser.Package[] overlayArray =
   6618             overlaySet.values().toArray(new PackageParser.Package[0]);
   6619         Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
   6620             public int compare(PackageParser.Package p1, PackageParser.Package p2) {
   6621                 return p1.mOverlayPriority - p2.mOverlayPriority;
   6622             }
   6623         };
   6624         Arrays.sort(overlayArray, cmp);
   6625 
   6626         pkg.applicationInfo.resourceDirs = new String[overlayArray.length];
   6627         int i = 0;
   6628         for (PackageParser.Package p : overlayArray) {
   6629             pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath;
   6630         }
   6631         return true;
   6632     }
   6633 
   6634     private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
   6635         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir");
   6636         try {
   6637             scanDirLI(dir, parseFlags, scanFlags, currentTime);
   6638         } finally {
   6639             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
   6640         }
   6641     }
   6642 
   6643     private void scanDirLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
   6644         final File[] files = dir.listFiles();
   6645         if (ArrayUtils.isEmpty(files)) {
   6646             Log.d(TAG, "No files in app dir " + dir);
   6647             return;
   6648         }
   6649 
   6650         if (DEBUG_PACKAGE_SCANNING) {
   6651             Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
   6652                     + " flags=0x" + Integer.toHexString(parseFlags));
   6653         }
   6654 
   6655         for (File file : files) {
   6656             final boolean isPackage = (isApkFile(file) || file.isDirectory())
   6657                     && !PackageInstallerService.isStageName(file.getName());
   6658             if (!isPackage) {
   6659                 // Ignore entries which are not packages
   6660                 continue;
   6661             }
   6662             try {
   6663                 scanPackageTracedLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
   6664                         scanFlags, currentTime, null);
   6665             } catch (PackageManagerException e) {
   6666                 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage());
   6667 
   6668                 // Delete invalid userdata apps
   6669                 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
   6670                         e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {
   6671                     logCriticalInfo(Log.WARN, "Deleting invalid package at " + file);
   6672                     removeCodePathLI(file);
   6673                 }
   6674             }
   6675         }
   6676     }
   6677 
   6678     private static File getSettingsProblemFile() {
   6679         File dataDir = Environment.getDataDirectory();
   6680         File systemDir = new File(dataDir, "system");
   6681         File fname = new File(systemDir, "uiderrors.txt");
   6682         return fname;
   6683     }
   6684 
   6685     static void reportSettingsProblem(int priority, String msg) {
   6686         logCriticalInfo(priority, msg);
   6687     }
   6688 
   6689     static void logCriticalInfo(int priority, String msg) {
   6690         Slog.println(priority, TAG, msg);
   6691         EventLogTags.writePmCriticalInfo(msg);
   6692         try {
   6693             File fname = getSettingsProblemFile();
   6694             FileOutputStream out = new FileOutputStream(fname, true);
   6695             PrintWriter pw = new FastPrintWriter(out);
   6696             SimpleDateFormat formatter = new SimpleDateFormat();
   6697             String dateString = formatter.format(new Date(System.currentTimeMillis()));
   6698             pw.println(dateString + ": " + msg);
   6699             pw.close();
   6700             FileUtils.setPermissions(
   6701                     fname.toString(),
   6702                     FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
   6703                     -1, -1);
   6704         } catch (java.io.IOException e) {
   6705         }
   6706     }
   6707 
   6708     private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) {
   6709         if (srcFile.isDirectory()) {
   6710             final File baseFile = new File(pkg.baseCodePath);
   6711             long maxModifiedTime = baseFile.lastModified();
   6712             if (pkg.splitCodePaths != null) {
   6713                 for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) {
   6714                     final File splitFile = new File(pkg.splitCodePaths[i]);
   6715                     maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified());
   6716                 }
   6717             }
   6718             return maxModifiedTime;
   6719         }
   6720         return srcFile.lastModified();
   6721     }
   6722 
   6723     private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile,
   6724             final int policyFlags) throws PackageManagerException {
   6725         // When upgrading from pre-N MR1, verify the package time stamp using the package
   6726         // directory and not the APK file.
   6727         final long lastModifiedTime = mIsPreNMR1Upgrade
   6728                 ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg, srcFile);
   6729         if (ps != null
   6730                 && ps.codePath.equals(srcFile)
   6731                 && ps.timeStamp == lastModifiedTime
   6732                 && !isCompatSignatureUpdateNeeded(pkg)
   6733                 && !isRecoverSignatureUpdateNeeded(pkg)) {
   6734             long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
   6735             KeySetManagerService ksms = mSettings.mKeySetManagerService;
   6736             ArraySet<PublicKey> signingKs;
   6737             synchronized (mPackages) {
   6738                 signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
   6739             }
   6740             if (ps.signatures.mSignatures != null
   6741                     && ps.signatures.mSignatures.length != 0
   6742                     && signingKs != null) {
   6743                 // Optimization: reuse the existing cached certificates
   6744                 // if the package appears to be unchanged.
   6745                 pkg.mSignatures = ps.signatures.mSignatures;
   6746                 pkg.mSigningKeys = signingKs;
   6747                 return;
   6748             }
   6749 
   6750             Slog.w(TAG, "PackageSetting for " + ps.name
   6751                     + " is missing signatures.  Collecting certs again to recover them.");
   6752         } else {
   6753             Slog.i(TAG, srcFile.toString() + " changed; collecting certs");
   6754         }
   6755 
   6756         try {
   6757             PackageParser.collectCertificates(pkg, policyFlags);
   6758         } catch (PackageParserException e) {
   6759             throw PackageManagerException.from(e);
   6760         }
   6761     }
   6762 
   6763     /**
   6764      *  Traces a package scan.
   6765      *  @see #scanPackageLI(File, int, int, long, UserHandle)
   6766      */
   6767     private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
   6768             int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
   6769         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
   6770         try {
   6771             return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
   6772         } finally {
   6773             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
   6774         }
   6775     }
   6776 
   6777     /**
   6778      *  Scans a package and returns the newly parsed package.
   6779      *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
   6780      */
   6781     private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
   6782             long currentTime, UserHandle user) throws PackageManagerException {
   6783         if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
   6784         PackageParser pp = new PackageParser();
   6785         pp.setSeparateProcesses(mSeparateProcesses);
   6786         pp.setOnlyCoreApps(mOnlyCore);
   6787         pp.setDisplayMetrics(mMetrics);
   6788 
   6789         if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
   6790             parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
   6791         }
   6792 
   6793         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
   6794         final PackageParser.Package pkg;
   6795         try {
   6796             pkg = pp.parsePackage(scanFile, parseFlags);
   6797         } catch (PackageParserException e) {
   6798             throw PackageManagerException.from(e);
   6799         } finally {
   6800             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
   6801         }
   6802 
   6803         return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
   6804     }
   6805 
   6806     /**
   6807      *  Scans a package and returns the newly parsed package.
   6808      *  @throws PackageManagerException on a parse error.
   6809      */
   6810     private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile,
   6811             final int policyFlags, int scanFlags, long currentTime, UserHandle user)
   6812             throws PackageManagerException {
   6813         // If the package has children and this is the first dive in the function
   6814         // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
   6815         // packages (parent and children) would be successfully scanned before the
   6816         // actual scan since scanning mutates internal state and we want to atomically
   6817         // install the package and its children.
   6818         if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
   6819             if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
   6820                 scanFlags |= SCAN_CHECK_ONLY;
   6821             }
   6822         } else {
   6823             scanFlags &= ~SCAN_CHECK_ONLY;
   6824         }
   6825 
   6826         // Scan the parent
   6827         PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags,
   6828                 scanFlags, currentTime, user);
   6829 
   6830         // Scan the children
   6831         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
   6832         for (int i = 0; i < childCount; i++) {
   6833             PackageParser.Package childPackage = pkg.childPackages.get(i);
   6834             scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags,
   6835                     currentTime, user);
   6836         }
   6837 
   6838 
   6839         if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
   6840             return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user);
   6841         }
   6842 
   6843         return scannedPkg;
   6844     }
   6845 
   6846     /**
   6847      *  Scans a package and returns the newly parsed package.
   6848      *  @throws PackageManagerException on a parse error.
   6849      */
   6850     private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile,
   6851             int policyFlags, int scanFlags, long currentTime, UserHandle user)
   6852             throws PackageManagerException {
   6853         PackageSetting ps = null;
   6854         PackageSetting updatedPkg;
   6855         // reader
   6856         synchronized (mPackages) {
   6857             // Look to see if we already know about this package.
   6858             String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
   6859             if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
   6860                 // This package has been renamed to its original name.  Let's
   6861                 // use that.
   6862                 ps = mSettings.peekPackageLPr(oldName);
   6863             }
   6864             // If there was no original package, see one for the real package name.
   6865             if (ps == null) {
   6866                 ps = mSettings.peekPackageLPr(pkg.packageName);
   6867             }
   6868             // Check to see if this package could be hiding/updating a system
   6869             // package.  Must look for it either under the original or real
   6870             // package name depending on our state.
   6871             updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
   6872             if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
   6873 
   6874             // If this is a package we don't know about on the system partition, we
   6875             // may need to remove disabled child packages on the system partition
   6876             // or may need to not add child packages if the parent apk is updated
   6877             // on the data partition and no longer defines this child package.
   6878             if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
   6879                 // If this is a parent package for an updated system app and this system
   6880                 // app got an OTA update which no longer defines some of the child packages
   6881                 // we have to prune them from the disabled system packages.
   6882                 PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
   6883                 if (disabledPs != null) {
   6884                     final int scannedChildCount = (pkg.childPackages != null)
   6885                             ? pkg.childPackages.size() : 0;
   6886                     final int disabledChildCount = disabledPs.childPackageNames != null
   6887                             ? disabledPs.childPackageNames.size() : 0;
   6888                     for (int i = 0; i < disabledChildCount; i++) {
   6889                         String disabledChildPackageName = disabledPs.childPackageNames.get(i);
   6890                         boolean disabledPackageAvailable = false;
   6891                         for (int j = 0; j < scannedChildCount; j++) {
   6892                             PackageParser.Package childPkg = pkg.childPackages.get(j);
   6893                             if (childPkg.packageName.equals(disabledChildPackageName)) {
   6894                                 disabledPackageAvailable = true;
   6895                                 break;
   6896                             }
   6897                          }
   6898                          if (!disabledPackageAvailable) {
   6899                              mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
   6900                          }
   6901                     }
   6902                 }
   6903             }
   6904         }
   6905 
   6906         boolean updatedPkgBetter = false;
   6907         // First check if this is a system package that may involve an update
   6908         if (updatedPkg != null && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
   6909             // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
   6910             // it needs to drop FLAG_PRIVILEGED.
   6911             if (locationIsPrivileged(scanFile)) {
   6912                 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
   6913             } else {
   6914                 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
   6915             }
   6916 
   6917             if (ps != null && !ps.codePath.equals(scanFile)) {
   6918                 // The path has changed from what was last scanned...  check the
   6919                 // version of the new path against what we have stored to determine
   6920                 // what to do.
   6921                 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
   6922                 if (pkg.mVersionCode <= ps.versionCode) {
   6923                     // The system package has been updated and the code path does not match
   6924                     // Ignore entry. Skip it.
   6925                     if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile
   6926                             + " ignored: updated version " + ps.versionCode
   6927                             + " better than this " + pkg.mVersionCode);
   6928                     if (!updatedPkg.codePath.equals(scanFile)) {
   6929                         Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
   6930                                 + ps.name + " changing from " + updatedPkg.codePathString
   6931                                 + " to " + scanFile);
   6932                         updatedPkg.codePath = scanFile;
   6933                         updatedPkg.codePathString = scanFile.toString();
   6934                         updatedPkg.resourcePath = scanFile;
   6935                         updatedPkg.resourcePathString = scanFile.toString();
   6936                     }
   6937                     updatedPkg.pkg = pkg;
   6938                     updatedPkg.versionCode = pkg.mVersionCode;
   6939 
   6940                     // Update the disabled system child packages to point to the package too.
   6941                     final int childCount = updatedPkg.childPackageNames != null
   6942                             ? updatedPkg.childPackageNames.size() : 0;
   6943                     for (int i = 0; i < childCount; i++) {
   6944                         String childPackageName = updatedPkg.childPackageNames.get(i);
   6945                         PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr(
   6946                                 childPackageName);
   6947                         if (updatedChildPkg != null) {
   6948                             updatedChildPkg.pkg = pkg;
   6949                             updatedChildPkg.versionCode = pkg.mVersionCode;
   6950                         }
   6951                     }
   6952 
   6953                     throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
   6954                             + scanFile + " ignored: updated version " + ps.versionCode
   6955                             + " better than this " + pkg.mVersionCode);
   6956                 } else {
   6957                     // The current app on the system partition is better than
   6958                     // what we have updated to on the data partition; switch
   6959                     // back to the system partition version.
   6960                     // At this point, its safely assumed that package installation for
   6961                     // apps in system partition will go through. If not there won't be a working
   6962                     // version of the app
   6963                     // writer
   6964                     synchronized (mPackages) {
   6965                         // Just remove the loaded entries from package lists.
   6966                         mPackages.remove(ps.name);
   6967                     }
   6968 
   6969                     logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
   6970                             + " reverting from " + ps.codePathString
   6971                             + ": new version " + pkg.mVersionCode
   6972                             + " better than installed " + ps.versionCode);
   6973 
   6974                     InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
   6975                             ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
   6976                     synchronized (mInstallLock) {
   6977                         args.cleanUpResourcesLI();
   6978                     }
   6979                     synchronized (mPackages) {
   6980                         mSettings.enableSystemPackageLPw(ps.name);
   6981                     }
   6982                     updatedPkgBetter = true;
   6983                 }
   6984             }
   6985         }
   6986 
   6987         if (updatedPkg != null) {
   6988             // An updated system app will not have the PARSE_IS_SYSTEM flag set
   6989             // initially
   6990             policyFlags |= PackageParser.PARSE_IS_SYSTEM;
   6991 
   6992             // An updated privileged app will not have the PARSE_IS_PRIVILEGED
   6993             // flag set initially
   6994             if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
   6995                 policyFlags |= PackageParser.PARSE_IS_PRIVILEGED;
   6996             }
   6997         }
   6998 
   6999         // Verify certificates against what was last scanned
   7000         collectCertificatesLI(ps, pkg, scanFile, policyFlags);
   7001 
   7002         /*
   7003          * A new system app appeared, but we already had a non-system one of the
   7004          * same name installed earlier.
   7005          */
   7006         boolean shouldHideSystemApp = false;
   7007         if (updatedPkg == null && ps != null
   7008                 && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
   7009             /*
   7010              * Check to make sure the signatures match first. If they don't,
   7011              * wipe the installed application and its data.
   7012              */
   7013             if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
   7014                     != PackageManager.SIGNATURE_MATCH) {
   7015                 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
   7016                         + " signatures don't match existing userdata copy; removing");
   7017                 try (PackageFreezer freezer = freezePackage(pkg.packageName,
   7018                         "scanPackageInternalLI")) {
   7019                     deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
   7020                 }
   7021                 ps = null;
   7022             } else {
   7023                 /*
   7024                  * If the newly-added system app is an older version than the
   7025                  * already installed version, hide it. It will be scanned later
   7026                  * and re-added like an update.
   7027                  */
   7028                 if (pkg.mVersionCode <= ps.versionCode) {
   7029                     shouldHideSystemApp = true;
   7030                     logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
   7031                             + " but new version " + pkg.mVersionCode + " better than installed "
   7032                             + ps.versionCode + "; hiding system");
   7033                 } else {
   7034                     /*
   7035                      * The newly found system app is a newer version that the
   7036                      * one previously installed. Simply remove the
   7037                      * already-installed application and replace it with our own
   7038                      * while keeping the application data.
   7039                      */
   7040                     logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
   7041                             + " reverting from " + ps.codePathString + ": new version "
   7042                             + pkg.mVersionCode + " better than installed " + ps.versionCode);
   7043                     InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
   7044                             ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
   7045                     synchronized (mInstallLock) {
   7046                         args.cleanUpResourcesLI();
   7047                     }
   7048                 }
   7049             }
   7050         }
   7051 
   7052         // The apk is forward locked (not public) if its code and resources
   7053         // are kept in different files. (except for app in either system or
   7054         // vendor path).
   7055         // TODO grab this value from PackageSettings
   7056         if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
   7057             if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
   7058                 policyFlags |= PackageParser.PARSE_FORWARD_LOCK;
   7059             }
   7060         }
   7061 
   7062         // TODO: extend to support forward-locked splits
   7063         String resourcePath = null;
   7064         String baseResourcePath = null;
   7065         if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
   7066             if (ps != null && ps.resourcePathString != null) {
   7067                 resourcePath = ps.resourcePathString;
   7068                 baseResourcePath = ps.resourcePathString;
   7069             } else {
   7070                 // Should not happen at all. Just log an error.
   7071                 Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
   7072             }
   7073         } else {
   7074             resourcePath = pkg.codePath;
   7075             baseResourcePath = pkg.baseCodePath;
   7076         }
   7077 
   7078         // Set application objects path explicitly.
   7079         pkg.setApplicationVolumeUuid(pkg.volumeUuid);
   7080         pkg.setApplicationInfoCodePath(pkg.codePath);
   7081         pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
   7082         pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
   7083         pkg.setApplicationInfoResourcePath(resourcePath);
   7084         pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
   7085         pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
   7086 
   7087         // Note that we invoke the following method only if we are about to unpack an application
   7088         PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags
   7089                 | SCAN_UPDATE_SIGNATURE, currentTime, user);
   7090 
   7091         /*
   7092          * If the system app should be overridden by a previously installed
   7093          * data, hide the system app now and let the /data/app scan pick it up
   7094          * again.
   7095          */
   7096         if (shouldHideSystemApp) {
   7097             synchronized (mPackages) {
   7098                 mSettings.disableSystemPackageLPw(pkg.packageName, true);
   7099             }
   7100         }
   7101 
   7102         return scannedPkg;
   7103     }
   7104 
   7105     private static String fixProcessName(String defProcessName,
   7106             String processName, int uid) {
   7107         if (processName == null) {
   7108             return defProcessName;
   7109         }
   7110         return processName;
   7111     }
   7112 
   7113     private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
   7114             throws PackageManagerException {
   7115         if (pkgSetting.signatures.mSignatures != null) {
   7116             // Already existing package. Make sure signatures match
   7117             boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
   7118                     == PackageManager.SIGNATURE_MATCH;
   7119             if (!match) {
   7120                 match = compareSignaturesCompat(pkgSetting.signatures, pkg)
   7121                         == PackageManager.SIGNATURE_MATCH;
   7122             }
   7123             if (!match) {
   7124                 match = compareSignaturesRecover(pkgSetting.signatures, pkg)
   7125                         == PackageManager.SIGNATURE_MATCH;
   7126             }
   7127             if (!match) {
   7128                 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
   7129                         + pkg.packageName + " signatures do not match the "
   7130                         + "previously installed version; ignoring!");
   7131             }
   7132         }
   7133 
   7134         // Check for shared user signatures
   7135         if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
   7136             // Already existing package. Make sure signatures match
   7137             boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
   7138                     pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
   7139             if (!match) {
   7140                 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
   7141                         == PackageManager.SIGNATURE_MATCH;
   7142             }
   7143             if (!match) {
   7144                 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
   7145                         == PackageManager.SIGNATURE_MATCH;
   7146             }
   7147             if (!match) {
   7148                 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
   7149                         "Package " + pkg.packageName
   7150                         + " has no signatures that match those in shared user "
   7151                         + pkgSetting.sharedUser.name + "; ignoring!");
   7152             }
   7153         }
   7154     }
   7155 
   7156     /**
   7157      * Enforces that only the system UID or root's UID can call a method exposed
   7158      * via Binder.
   7159      *
   7160      * @param message used as message if SecurityException is thrown
   7161      * @throws SecurityException if the caller is not system or root
   7162      */
   7163     private static final void enforceSystemOrRoot(String message) {
   7164         final int uid = Binder.getCallingUid();
   7165         if (uid != Process.SYSTEM_UID && uid != 0) {
   7166             throw new SecurityException(message);
   7167         }
   7168     }
   7169 
   7170     @Override
   7171     public void performFstrimIfNeeded() {
   7172         enforceSystemOrRoot("Only the system can request fstrim");
   7173 
   7174         // Before everything else, see whether we need to fstrim.
   7175         try {
   7176             IMountService ms = PackageHelper.getMountService();
   7177             if (ms != null) {
   7178                 boolean doTrim = false;
   7179                 final long interval = android.provider.Settings.Global.getLong(
   7180                         mContext.getContentResolver(),
   7181                         android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
   7182                         DEFAULT_MANDATORY_FSTRIM_INTERVAL);
   7183                 if (interval > 0) {
   7184                     final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance();
   7185                     if (timeSinceLast > interval) {
   7186                         doTrim = true;
   7187                         Slog.w(TAG, "No disk maintenance in " + timeSinceLast
   7188                                 + "; running immediately");
   7189                     }
   7190                 }
   7191                 if (doTrim) {
   7192                     final boolean dexOptDialogShown;
   7193                     synchronized (mPackages) {
   7194                         dexOptDialogShown = mDexOptDialogShown;
   7195                     }
   7196                     if (!isFirstBoot() && dexOptDialogShown) {
   7197                         try {
   7198                             ActivityManagerNative.getDefault().showBootMessage(
   7199                                     mContext.getResources().getString(
   7200                                             R.string.android_upgrading_fstrim), true);
   7201                         } catch (RemoteException e) {
   7202                         }
   7203                     }
   7204                     ms.runMaintenance();
   7205                 }
   7206             } else {
   7207                 Slog.e(TAG, "Mount service unavailable!");
   7208             }
   7209         } catch (RemoteException e) {
   7210             // Can't happen; MountService is local
   7211         }
   7212     }
   7213 
   7214     @Override
   7215     public void updatePackagesIfNeeded() {
   7216         enforceSystemOrRoot("Only the system can request package update");
   7217 
   7218         // We need to re-extract after an OTA.
   7219         boolean causeUpgrade = isUpgrade();
   7220 
   7221         // First boot or factory reset.
   7222         // Note: we also handle devices that are upgrading to N right now as if it is their
   7223         //       first boot, as they do not have profile data.
   7224         boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
   7225 
   7226         // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
   7227         boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
   7228 
   7229         if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
   7230             return;
   7231         }
   7232 
   7233         List<PackageParser.Package> pkgs;
   7234         synchronized (mPackages) {
   7235             pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
   7236         }
   7237 
   7238         final long startTime = System.nanoTime();
   7239         final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
   7240                     getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT));
   7241 
   7242         final int elapsedTimeSeconds =
   7243                 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
   7244 
   7245         MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
   7246         MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
   7247         MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
   7248         MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
   7249         MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
   7250     }
   7251 
   7252     /**
   7253      * Performs dexopt on the set of packages in {@code packages} and returns an int array
   7254      * containing statistics about the invocation. The array consists of three elements,
   7255      * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
   7256      * and {@code numberOfPackagesFailed}.
   7257      */
   7258     private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
   7259             String compilerFilter) {
   7260 
   7261         int numberOfPackagesVisited = 0;
   7262         int numberOfPackagesOptimized = 0;
   7263         int numberOfPackagesSkipped = 0;
   7264         int numberOfPackagesFailed = 0;
   7265         final int numberOfPackagesToDexopt = pkgs.size();
   7266 
   7267         for (PackageParser.Package pkg : pkgs) {
   7268             numberOfPackagesVisited++;
   7269 
   7270             if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
   7271                 if (DEBUG_DEXOPT) {
   7272                     Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
   7273                 }
   7274                 numberOfPackagesSkipped++;
   7275                 continue;
   7276             }
   7277 
   7278             if (DEBUG_DEXOPT) {
   7279                 Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
   7280                         numberOfPackagesToDexopt + ": " + pkg.packageName);
   7281             }
   7282 
   7283             if (showDialog) {
   7284                 try {
   7285                     ActivityManagerNative.getDefault().showBootMessage(
   7286                             mContext.getResources().getString(R.string.android_upgrading_apk,
   7287                                     numberOfPackagesVisited, numberOfPackagesToDexopt), true);
   7288                 } catch (RemoteException e) {
   7289                 }
   7290                 synchronized (mPackages) {
   7291                     mDexOptDialogShown = true;
   7292                 }
   7293             }
   7294 
   7295             // If the OTA updates a system app which was previously preopted to a non-preopted state
   7296             // the app might end up being verified at runtime. That's because by default the apps
   7297             // are verify-profile but for preopted apps there's no profile.
   7298             // Do a hacky check to ensure that if we have no profiles (a reasonable indication
   7299             // that before the OTA the app was preopted) the app gets compiled with a non-profile
   7300             // filter (by default interpret-only).
   7301             // Note that at this stage unused apps are already filtered.
   7302             if (isSystemApp(pkg) &&
   7303                     DexFile.isProfileGuidedCompilerFilter(compilerFilter) &&
   7304                     !Environment.getReferenceProfile(pkg.packageName).exists()) {
   7305                 compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter);
   7306             }
   7307 
   7308             // checkProfiles is false to avoid merging profiles during boot which
   7309             // might interfere with background compilation (b/28612421).
   7310             // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
   7311             // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
   7312             // trade-off worth doing to save boot time work.
   7313             int dexOptStatus = performDexOptTraced(pkg.packageName,
   7314                     false /* checkProfiles */,
   7315                     compilerFilter,
   7316                     false /* force */);
   7317             switch (dexOptStatus) {
   7318                 case PackageDexOptimizer.DEX_OPT_PERFORMED:
   7319                     numberOfPackagesOptimized++;
   7320                     break;
   7321                 case PackageDexOptimizer.DEX_OPT_SKIPPED:
   7322                     numberOfPackagesSkipped++;
   7323                     break;
   7324                 case PackageDexOptimizer.DEX_OPT_FAILED:
   7325                     numberOfPackagesFailed++;
   7326                     break;
   7327                 default:
   7328                     Log.e(TAG, "Unexpected dexopt return code " + dexOptStatus);
   7329                     break;
   7330             }
   7331         }
   7332 
   7333         return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
   7334                 numberOfPackagesFailed };
   7335     }
   7336 
   7337     @Override
   7338     public void notifyPackageUse(String packageName, int reason) {
   7339         synchronized (mPackages) {
   7340             PackageParser.Package p = mPackages.get(packageName);
   7341             if (p == null) {
   7342                 return;
   7343             }
   7344             p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
   7345         }
   7346     }
   7347 
   7348     // TODO: this is not used nor needed. Delete it.
   7349     @Override
   7350     public boolean performDexOptIfNeeded(String packageName) {
   7351         int dexOptStatus = performDexOptTraced(packageName,
   7352                 false /* checkProfiles */, getFullCompilerFilter(), false /* force */);
   7353         return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
   7354     }
   7355 
   7356     @Override
   7357     public boolean performDexOpt(String packageName,
   7358             boolean checkProfiles, int compileReason, boolean force) {
   7359         int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
   7360                 getCompilerFilterForReason(compileReason), force);
   7361         return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
   7362     }
   7363 
   7364     @Override
   7365     public boolean performDexOptMode(String packageName,
   7366             boolean checkProfiles, String targetCompilerFilter, boolean force) {
   7367         int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
   7368                 targetCompilerFilter, force);
   7369         return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
   7370     }
   7371 
   7372     private int performDexOptTraced(String packageName,
   7373                 boolean checkProfiles, String targetCompilerFilter, boolean force) {
   7374         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
   7375         try {
   7376             return performDexOptInternal(packageName, checkProfiles,
   7377                     targetCompilerFilter, force);
   7378         } finally {
   7379             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
   7380         }
   7381     }
   7382 
   7383     // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
   7384     // if the package can now be considered up to date for the given filter.
   7385     private int performDexOptInternal(String packageName,
   7386                 boolean checkProfiles, String targetCompilerFilter, boolean force) {
   7387         PackageParser.Package p;
   7388         synchronized (mPackages) {
   7389             p = mPackages.get(packageName);
   7390             if (p == null) {
   7391                 // Package could not be found. Report failure.
   7392                 return PackageDexOptimizer.DEX_OPT_FAILED;
   7393             }
   7394             mPackageUsage.maybeWriteAsync(mPackages);
   7395             mCompilerStats.maybeWriteAsync();
   7396         }
   7397         long callingId = Binder.clearCallingIdentity();
   7398         try {
   7399             synchronized (mInstallLock) {
   7400                 return performDexOptInternalWithDependenciesLI(p, checkProfiles,
   7401                         targetCompilerFilter, force);
   7402             }
   7403         } finally {
   7404             Binder.restoreCallingIdentity(callingId);
   7405         }
   7406     }
   7407 
   7408     public ArraySet<String> getOptimizablePackages() {
   7409         ArraySet<String> pkgs = new ArraySet<String>();
   7410         synchronized (mPackages) {
   7411             for (PackageParser.Package p : mPackages.values()) {
   7412                 if (PackageDexOptimizer.canOptimizePackage(p)) {
   7413                     pkgs.add(p.packageName);
   7414                 }
   7415             }
   7416         }
   7417         return pkgs;
   7418     }
   7419 
   7420     private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
   7421             boolean checkProfiles, String targetCompilerFilter,
   7422             boolean force) {
   7423         // Select the dex optimizer based on the force parameter.
   7424         // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
   7425         //       allocate an object here.
   7426         PackageDexOptimizer pdo = force
   7427                 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
   7428                 : mPackageDexOptimizer;
   7429 
   7430         // Optimize all dependencies first. Note: we ignore the return value and march on
   7431         // on errors.
   7432         Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
   7433         final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
   7434         if (!deps.isEmpty()) {
   7435             for (PackageParser.Package depPackage : deps) {
   7436                 // TODO: Analyze and investigate if we (should) profile libraries.
   7437                 // Currently this will do a full compilation of the library by default.
   7438                 pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
   7439                         false /* checkProfiles */,
   7440                         getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY),
   7441                         getOrCreateCompilerPackageStats(depPackage));
   7442             }
   7443         }
   7444         return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles,
   7445                 targetCompilerFilter, getOrCreateCompilerPackageStats(p));
   7446     }
   7447 
   7448     Collection<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
   7449         if (p.usesLibraries != null || p.usesOptionalLibraries != null) {
   7450             ArrayList<PackageParser.Package> retValue = new ArrayList<>();
   7451             Set<String> collectedNames = new HashSet<>();
   7452             findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
   7453 
   7454             retValue.remove(p);
   7455 
   7456             return retValue;
   7457         } else {
   7458             return Collections.emptyList();
   7459         }
   7460     }
   7461 
   7462     private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
   7463             Collection<PackageParser.Package> collected, Set<String> collectedNames) {
   7464         if (!collectedNames.contains(p.packageName)) {
   7465             collectedNames.add(p.packageName);
   7466             collected.add(p);
   7467 
   7468             if (p.usesLibraries != null) {
   7469                 findSharedNonSystemLibrariesRecursive(p.usesLibraries, collected, collectedNames);
   7470             }
   7471             if (p.usesOptionalLibraries != null) {
   7472                 findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries, collected,
   7473                         collectedNames);
   7474             }
   7475         }
   7476     }
   7477 
   7478     private void findSharedNonSystemLibrariesRecursive(Collection<String> libs,
   7479             Collection<PackageParser.Package> collected, Set<String> collectedNames) {
   7480         for (String libName : libs) {
   7481             PackageParser.Package libPkg = findSharedNonSystemLibrary(libName);
   7482             if (libPkg != null) {
   7483                 findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
   7484             }
   7485         }
   7486     }
   7487 
   7488     private PackageParser.Package findSharedNonSystemLibrary(String libName) {
   7489         synchronized (mPackages) {
   7490             PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName);
   7491             if (lib != null && lib.apk != null) {
   7492                 return mPackages.get(lib.apk);
   7493             }
   7494         }
   7495         return null;
   7496     }
   7497 
   7498     public void shutdown() {
   7499         mPackageUsage.writeNow(mPackages);
   7500         mCompilerStats.writeNow();
   7501     }
   7502 
   7503     @Override
   7504     public void dumpProfiles(String packageName) {
   7505         PackageParser.Package pkg;
   7506         synchronized (mPackages) {
   7507             pkg = mPackages.get(packageName);
   7508             if (pkg == null) {
   7509                 throw new IllegalArgumentException("Unknown package: " + packageName);
   7510             }
   7511         }
   7512         /* Only the shell, root, or the app user should be able to dump profiles. */
   7513         int callingUid = Binder.getCallingUid();
   7514         if (callingUid != Process.SHELL_UID &&
   7515             callingUid != Process.ROOT_UID &&
   7516             callingUid != pkg.applicationInfo.uid) {
   7517             throw new SecurityException("dumpProfiles");
   7518         }
   7519 
   7520         synchronized (mInstallLock) {
   7521             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
   7522             final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
   7523             try {
   7524                 List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
   7525                 String gid = Integer.toString(sharedGid);
   7526                 String codePaths = TextUtils.join(";", allCodePaths);
   7527                 mInstaller.dumpProfiles(gid, packageName, codePaths);
   7528             } catch (InstallerException e) {
   7529                 Slog.w(TAG, "Failed to dump profiles", e);
   7530             }
   7531             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
   7532         }
   7533     }
   7534 
   7535     @Override
   7536     public void forceDexOpt(String packageName) {
   7537         enforceSystemOrRoot("forceDexOpt");
   7538 
   7539         PackageParser.Package pkg;
   7540         synchronized (mPackages) {
   7541             pkg = mPackages.get(packageName);
   7542             if (pkg == null) {
   7543                 throw new IllegalArgumentException("Unknown package: " + packageName);
   7544             }
   7545         }
   7546 
   7547         synchronized (mInstallLock) {
   7548             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
   7549 
   7550             // Whoever is calling forceDexOpt wants a fully compiled package.
   7551             // Don't use profiles since that may cause compilation to be skipped.
   7552             final int res = performDexOptInternalWithDependenciesLI(pkg,
   7553                     false /* checkProfiles */, getCompilerFilterForReason(REASON_FORCED_DEXOPT),
   7554                     true /* force */);
   7555 
   7556             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
   7557             if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
   7558                 throw new IllegalStateException("Failed to dexopt: " + res);
   7559             }
   7560         }
   7561     }
   7562 
   7563     private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
   7564         if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
   7565             Slog.w(TAG, "Unable to update from " + oldPkg.name
   7566                     + " to " + newPkg.packageName
   7567                     + ": old package not in system partition");
   7568             return false;
   7569         } else if (mPackages.get(oldPkg.name) != null) {
   7570             Slog.w(TAG, "Unable to update from " + oldPkg.name
   7571                     + " to " + newPkg.packageName
   7572                     + ": old package still exists");
   7573             return false;
   7574         }
   7575         return true;
   7576     }
   7577 
   7578     void removeCodePathLI(File codePath) {
   7579         if (codePath.isDirectory()) {
   7580             try {
   7581                 mInstaller.rmPackageDir(codePath.getAbsolutePath());
   7582             } catch (InstallerException e) {
   7583                 Slog.w(TAG, "Failed to remove code path", e);
   7584             }
   7585         } else {
   7586             codePath.delete();
   7587         }
   7588     }
   7589 
   7590     private int[] resolveUserIds(int userId) {
   7591         return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
   7592     }
   7593 
   7594     private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
   7595         if (pkg == null) {
   7596             Slog.wtf(TAG, "Package was null!", new Throwable());
   7597             return;
   7598         }
   7599         clearAppDataLeafLIF(pkg, userId, flags);
   7600         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
   7601         for (int i = 0; i < childCount; i++) {
   7602             clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
   7603         }
   7604     }
   7605 
   7606     private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
   7607         final PackageSetting ps;
   7608         synchronized (mPackages) {
   7609             ps = mSettings.mPackages.get(pkg.packageName);
   7610         }
   7611         for (int realUserId : resolveUserIds(userId)) {
   7612             final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
   7613             try {
   7614                 mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
   7615                         ceDataInode);
   7616             } catch (InstallerException e) {
   7617                 Slog.w(TAG, String.valueOf(e));
   7618             }
   7619         }
   7620     }
   7621 
   7622     private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
   7623         if (pkg == null) {
   7624             Slog.wtf(TAG, "Package was null!", new Throwable());
   7625             return;
   7626         }
   7627         destroyAppDataLeafLIF(pkg, userId, flags);
   7628         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
   7629         for (int i = 0; i < childCount; i++) {
   7630             destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
   7631         }
   7632     }
   7633 
   7634     private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
   7635         final PackageSetting ps;
   7636         synchronized (mPackages) {
   7637             ps = mSettings.mPackages.get(pkg.packageName);
   7638         }
   7639         for (int realUserId : resolveUserIds(userId)) {
   7640             final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
   7641             try {
   7642                 mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
   7643                         ceDataInode);
   7644             } catch (InstallerException e) {
   7645                 Slog.w(TAG, String.valueOf(e));
   7646             }
   7647         }
   7648     }
   7649 
   7650     private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
   7651         if (pkg == null) {
   7652             Slog.wtf(TAG, "Package was null!", new Throwable());
   7653             return;
   7654         }
   7655         destroyAppProfilesLeafLIF(pkg);
   7656         destroyAppReferenceProfileLeafLIF(pkg, userId, true /* removeBaseMarker */);
   7657         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
   7658         for (int i = 0; i < childCount; i++) {
   7659             destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
   7660             destroyAppReferenceProfileLeafLIF(pkg.childPackages.get(i), userId,
   7661                     true /* removeBaseMarker */);
   7662         }
   7663     }
   7664 
   7665     private void destroyAppReferenceProfileLeafLIF(PackageParser.Package pkg, int userId,
   7666             boolean removeBaseMarker) {
   7667         if (pkg.isForwardLocked()) {
   7668             return;
   7669         }
   7670 
   7671         for (String path : pkg.getAllCodePathsExcludingResourceOnly()) {
   7672             try {
   7673                 path = PackageManagerServiceUtils.realpath(new File(path));
   7674             } catch (IOException e) {
   7675                 // TODO: Should we return early here ?
   7676                 Slog.w(TAG, "Failed to get canonical path", e);
   7677                 continue;
   7678             }
   7679 
   7680             final String useMarker = path.replace('/', '@');
   7681             for (int realUserId : resolveUserIds(userId)) {
   7682                 File profileDir = Environment.getDataProfilesDeForeignDexDirectory(realUserId);
   7683                 if (removeBaseMarker) {
   7684                     File foreignUseMark = new File(profileDir, useMarker);
   7685                     if (foreignUseMark.exists()) {
   7686                         if (!foreignUseMark.delete()) {
   7687                             Slog.w(TAG, "Unable to delete foreign user mark for package: "
   7688                                     + pkg.packageName);
   7689                         }
   7690                     }
   7691                 }
   7692 
   7693                 File[] markers = profileDir.listFiles();
   7694                 if (markers != null) {
   7695                     final String searchString = "@" + pkg.packageName + "@";
   7696                     // We also delete all markers that contain the package name we're
   7697                     // uninstalling. These are associated with secondary dex-files belonging
   7698                     // to the package. Reconstructing the path of these dex files is messy
   7699                     // in general.
   7700                     for (File marker : markers) {
   7701                         if (marker.getName().indexOf(searchString) > 0) {
   7702                             if (!marker.delete()) {
   7703                                 Slog.w(TAG, "Unable to delete foreign user mark for package: "
   7704                                     + pkg.packageName);
   7705                             }
   7706                         }
   7707                     }
   7708                 }
   7709             }
   7710         }
   7711     }
   7712 
   7713     private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
   7714         try {
   7715             mInstaller.destroyAppProfiles(pkg.packageName);
   7716         } catch (InstallerException e) {
   7717             Slog.w(TAG, String.valueOf(e));
   7718         }
   7719     }
   7720 
   7721     private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
   7722         if (pkg == null) {
   7723             Slog.wtf(TAG, "Package was null!", new Throwable());
   7724             return;
   7725         }
   7726         clearAppProfilesLeafLIF(pkg);
   7727         // We don't remove the base foreign use marker when clearing profiles because
   7728         // we will rename it when the app is updated. Unlike the actual profile contents,
   7729         // the foreign use marker is good across installs.
   7730         destroyAppReferenceProfileLeafLIF(pkg, userId, false /* removeBaseMarker */);
   7731         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
   7732         for (int i = 0; i < childCount; i++) {
   7733             clearAppProfilesLeafLIF(pkg.childPackages.get(i));
   7734         }
   7735     }
   7736 
   7737     private void clearAppProfilesLeafLIF(PackageParser.Package pkg) {
   7738         try {
   7739             mInstaller.clearAppProfiles(pkg.packageName);
   7740         } catch (InstallerException e) {
   7741             Slog.w(TAG, String.valueOf(e));
   7742         }
   7743     }
   7744 
   7745     private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
   7746             long lastUpdateTime) {
   7747         // Set parent install/update time
   7748         PackageSetting ps = (PackageSetting) pkg.mExtras;
   7749         if (ps != null) {
   7750             ps.firstInstallTime = firstInstallTime;
   7751             ps.lastUpdateTime = lastUpdateTime;
   7752         }
   7753         // Set children install/update time
   7754         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
   7755         for (int i = 0; i < childCount; i++) {
   7756             PackageParser.Package childPkg = pkg.childPackages.get(i);
   7757             ps = (PackageSetting) childPkg.mExtras;
   7758             if (ps != null) {
   7759                 ps.firstInstallTime = firstInstallTime;
   7760                 ps.lastUpdateTime = lastUpdateTime;
   7761             }
   7762         }
   7763     }
   7764 
   7765     private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
   7766             PackageParser.Package changingLib) {
   7767         if (file.path != null) {
   7768             usesLibraryFiles.add(file.path);
   7769             return;
   7770         }
   7771         PackageParser.Package p = mPackages.get(file.apk);
   7772         if (changingLib != null && changingLib.packageName.equals(file.apk)) {
   7773             // If we are doing this while in the middle of updating a library apk,
   7774             // then we need to make sure to use that new apk for determining the
   7775             // dependencies here.  (We haven't yet finished committing the new apk
   7776             // to the package manager state.)
   7777             if (p == null || p.packageName.equals(changingLib.packageName)) {
   7778                 p = changingLib;
   7779             }
   7780         }
   7781         if (p != null) {
   7782             usesLibraryFiles.addAll(p.getAllCodePaths());
   7783         }
   7784     }
   7785 
   7786     private void updateSharedLibrariesLPw(PackageParser.Package pkg,
   7787             PackageParser.Package changingLib) throws PackageManagerException {
   7788         if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
   7789             final ArraySet<String> usesLibraryFiles = new ArraySet<>();
   7790             int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
   7791             for (int i=0; i<N; i++) {
   7792                 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i));
   7793                 if (file == null) {
   7794                     throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
   7795                             "Package " + pkg.packageName + " requires unavailable shared library "
   7796                             + pkg.usesLibraries.get(i) + "; failing!");
   7797                 }
   7798                 addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
   7799             }
   7800             N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
   7801             for (int i=0; i<N; i++) {
   7802                 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
   7803                 if (file == null) {
   7804                     Slog.w(TAG, "Package " + pkg.packageName
   7805                             + " desires unavailable shared library "
   7806                             + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
   7807                 } else {
   7808                     addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
   7809                 }
   7810             }
   7811             N = usesLibraryFiles.size();
   7812             if (N > 0) {
   7813                 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]);
   7814             } else {
   7815                 pkg.usesLibraryFiles = null;
   7816             }
   7817         }
   7818     }
   7819 
   7820     private static boolean hasString(List<String> list, List<String> which) {
   7821         if (list == null) {
   7822             return false;
   7823         }
   7824         for (int i=list.size()-1; i>=0; i--) {
   7825             for (int j=which.size()-1; j>=0; j--) {
   7826                 if (which.get(j).equals(list.get(i))) {
   7827                     return true;
   7828                 }
   7829             }
   7830         }
   7831         return false;
   7832     }
   7833 
   7834     private void updateAllSharedLibrariesLPw() {
   7835         for (PackageParser.Package pkg : mPackages.values()) {
   7836             try {
   7837                 updateSharedLibrariesLPw(pkg, null);
   7838             } catch (PackageManagerException e) {
   7839                 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
   7840             }
   7841         }
   7842     }
   7843 
   7844     private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
   7845             PackageParser.Package changingPkg) {
   7846         ArrayList<PackageParser.Package> res = null;
   7847         for (PackageParser.Package pkg : mPackages.values()) {
   7848             if (hasString(pkg.usesLibraries, changingPkg.libraryNames)
   7849                     || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) {
   7850                 if (res == null) {
   7851                     res = new ArrayList<PackageParser.Package>();
   7852                 }
   7853                 res.add(pkg);
   7854                 try {
   7855                     updateSharedLibrariesLPw(pkg, changingPkg);
   7856                 } catch (PackageManagerException e) {
   7857                     Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
   7858                 }
   7859             }
   7860         }
   7861         return res;
   7862     }
   7863 
   7864     /**
   7865      * Derive the value of the {@code cpuAbiOverride} based on the provided
   7866      * value and an optional stored value from the package settings.
   7867      */
   7868     private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
   7869         String cpuAbiOverride = null;
   7870 
   7871         if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
   7872             cpuAbiOverride = null;
   7873         } else if (abiOverride != null) {
   7874             cpuAbiOverride = abiOverride;
   7875         } else if (settings != null) {
   7876             cpuAbiOverride = settings.cpuAbiOverrideString;
   7877         }
   7878 
   7879         return cpuAbiOverride;
   7880     }
   7881 
   7882     private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
   7883             final int policyFlags, int scanFlags, long currentTime, UserHandle user)
   7884                     throws PackageManagerException {
   7885         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
   7886         // If the package has children and this is the first dive in the function
   7887         // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
   7888         // whether all packages (parent and children) would be successfully scanned
   7889         // before the actual scan since scanning mutates internal state and we want
   7890         // to atomically install the package and its children.
   7891         if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
   7892             if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
   7893                 scanFlags |= SCAN_CHECK_ONLY;
   7894             }
   7895         } else {
   7896             scanFlags &= ~SCAN_CHECK_ONLY;
   7897         }
   7898 
   7899         final PackageParser.Package scannedPkg;
   7900         try {
   7901             // Scan the parent
   7902             scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user);
   7903             // Scan the children
   7904             final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
   7905             for (int i = 0; i < childCount; i++) {
   7906                 PackageParser.Package childPkg = pkg.childPackages.get(i);
   7907                 scanPackageLI(childPkg, policyFlags,
   7908                         scanFlags, currentTime, user);
   7909             }
   7910         } finally {
   7911             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
   7912         }
   7913 
   7914         if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
   7915             return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user);
   7916         }
   7917 
   7918         return scannedPkg;
   7919     }
   7920 
   7921     private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags,
   7922             int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
   7923         boolean success = false;
   7924         try {
   7925             final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags,
   7926                     currentTime, user);
   7927             success = true;
   7928             return res;
   7929         } finally {
   7930             if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
   7931                 // DELETE_DATA_ON_FAILURES is only used by frozen paths
   7932                 destroyAppDataLIF(pkg, UserHandle.USER_ALL,
   7933                         StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
   7934                 destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
   7935             }
   7936         }
   7937     }
   7938 
   7939     /**
   7940      * Returns {@code true} if the given file contains code. Otherwise {@code false}.
   7941      */
   7942     private static boolean apkHasCode(String fileName) {
   7943         StrictJarFile jarFile = null;
   7944         try {
   7945             jarFile = new StrictJarFile(fileName,
   7946                     false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
   7947             return jarFile.findEntry("classes.dex") != null;
   7948         } catch (IOException ignore) {
   7949         } finally {
   7950             try {
   7951                 if (jarFile != null) {
   7952                     jarFile.close();
   7953                 }
   7954             } catch (IOException ignore) {}
   7955         }
   7956         return false;
   7957     }
   7958 
   7959     /**
   7960      * Enforces code policy for the package. This ensures that if an APK has
   7961      * declared hasCode="true" in its manifest that the APK actually contains
   7962      * code.
   7963      *
   7964      * @throws PackageManagerException If bytecode could not be found when it should exist
   7965      */
   7966     private static void enforceCodePolicy(PackageParser.Package pkg)
   7967             throws PackageManagerException {
   7968         final boolean shouldHaveCode =
   7969                 (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
   7970         if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
   7971             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
   7972                     "Package " + pkg.baseCodePath + " code is missing");
   7973         }
   7974 
   7975         if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
   7976             for (int i = 0; i < pkg.splitCodePaths.length; i++) {
   7977                 final boolean splitShouldHaveCode =
   7978                         (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
   7979                 if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
   7980                     throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
   7981                             "Package " + pkg.splitCodePaths[i] + " code is missing");
   7982                 }
   7983             }
   7984         }
   7985     }
   7986 
   7987     private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,
   7988             final int policyFlags, final int scanFlags, long currentTime, UserHandle user)
   7989             throws PackageManagerException {
   7990         final File scanFile = new File(pkg.codePath);
   7991         if (pkg.applicationInfo.getCodePath() == null ||
   7992                 pkg.applicationInfo.getResourcePath() == null) {
   7993             // Bail out. The resource and code paths haven't been set.
   7994             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
   7995                     "Code and resource paths haven't been set correctly");
   7996         }
   7997 
   7998         // Apply policy
   7999         if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
   8000             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
   8001             if (pkg.applicationInfo.isDirectBootAware()) {
   8002                 // we're direct boot aware; set for all components
   8003                 for (PackageParser.Service s : pkg.services) {
   8004                     s.info.encryptionAware = s.info.directBootAware = true;
   8005                 }
   8006                 for (PackageParser.Provider p : pkg.providers) {
   8007                     p.info.encryptionAware = p.info.directBootAware = true;
   8008                 }
   8009                 for (PackageParser.Activity a : pkg.activities) {
   8010                     a.info.encryptionAware = a.info.directBootAware = true;
   8011                 }
   8012                 for (PackageParser.Activity r : pkg.receivers) {
   8013                     r.info.encryptionAware = r.info.directBootAware = true;
   8014                 }
   8015             }
   8016         } else {
   8017             // Only allow system apps to be flagged as core apps.
   8018             pkg.coreApp = false;
   8019             // clear flags not applicable to regular apps
   8020             pkg.applicationInfo.privateFlags &=
   8021                     ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
   8022             pkg.applicationInfo.privateFlags &=
   8023                     ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
   8024         }
   8025         pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0;
   8026 
   8027         if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
   8028             pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
   8029         }
   8030 
   8031         if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
   8032             enforceCodePolicy(pkg);
   8033         }
   8034 
   8035         if (mCustomResolverComponentName != null &&
   8036                 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
   8037             setUpCustomResolverActivity(pkg);
   8038         }
   8039 
   8040         if (pkg.packageName.equals("android")) {
   8041             synchronized (mPackages) {
   8042                 if (mAndroidApplication != null) {
   8043                     Slog.w(TAG, "*************************************************");
   8044                     Slog.w(TAG, "Core android package being redefined.  Skipping.");
   8045                     Slog.w(TAG, " file=" + scanFile);
   8046                     Slog.w(TAG, "*************************************************");
   8047                     throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
   8048                             "Core android package being redefined.  Skipping.");
   8049                 }
   8050 
   8051                 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
   8052                     // Set up information for our fall-back user intent resolution activity.
   8053                     mPlatformPackage = pkg;
   8054                     pkg.mVersionCode = mSdkVersion;
   8055                     mAndroidApplication = pkg.applicationInfo;
   8056 
   8057                     if (!mResolverReplaced) {
   8058                         mResolveActivity.applicationInfo = mAndroidApplication;
   8059                         mResolveActivity.name = ResolverActivity.class.getName();
   8060                         mResolveActivity.packageName = mAndroidApplication.packageName;
   8061                         mResolveActivity.processName = "system:ui";
   8062                         mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
   8063                         mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
   8064                         mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
   8065                         mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
   8066                         mResolveActivity.exported = true;
   8067                         mResolveActivity.enabled = true;
   8068                         mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
   8069                         mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
   8070                                 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
   8071                                 | ActivityInfo.CONFIG_SCREEN_LAYOUT
   8072                                 | ActivityInfo.CONFIG_ORIENTATION
   8073                                 | ActivityInfo.CONFIG_KEYBOARD
   8074                                 | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
   8075                         mResolveInfo.activityInfo = mResolveActivity;
   8076                         mResolveInfo.priority = 0;
   8077                         mResolveInfo.preferredOrder = 0;
   8078                         mResolveInfo.match = 0;
   8079                         mResolveComponentName = new ComponentName(
   8080                                 mAndroidApplication.packageName, mResolveActivity.name);
   8081                     }
   8082                 }
   8083             }
   8084         }
   8085 
   8086         if (DEBUG_PACKAGE_SCANNING) {
   8087             if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
   8088                 Log.d(TAG, "Scanning package " + pkg.packageName);
   8089         }
   8090 
   8091         synchronized (mPackages) {
   8092             if (mPackages.containsKey(pkg.packageName)
   8093                     || mSharedLibraries.containsKey(pkg.packageName)) {
   8094                 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
   8095                         "Application package " + pkg.packageName
   8096                                 + " already installed.  Skipping duplicate.");
   8097             }
   8098 
   8099             // If we're only installing presumed-existing packages, require that the
   8100             // scanned APK is both already known and at the path previously established
   8101             // for it.  Previously unknown packages we pick up normally, but if we have an
   8102             // a priori expectation about this package's install presence, enforce it.
   8103             // With a singular exception for new system packages. When an OTA contains
   8104             // a new system package, we allow the codepath to change from a system location
   8105             // to the user-installed location. If we don't allow this change, any newer,
   8106             // user-installed version of the application will be ignored.
   8107             if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
   8108                 if (mExpectingBetter.containsKey(pkg.packageName)) {
   8109                     logCriticalInfo(Log.WARN,
   8110                             "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
   8111                 } else {
   8112                     PackageSetting known = mSettings.peekPackageLPr(pkg.packageName);
   8113                     if (known != null) {
   8114                         if (DEBUG_PACKAGE_SCANNING) {
   8115                             Log.d(TAG, "Examining " + pkg.codePath
   8116                                     + " and requiring known paths " + known.codePathString
   8117                                     + " & " + known.resourcePathString);
   8118                         }
   8119                         if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
   8120                                 || !pkg.applicationInfo.getResourcePath().equals(
   8121                                 known.resourcePathString)) {
   8122                             throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
   8123                                     "Application package " + pkg.packageName
   8124                                             + " found at " + pkg.applicationInfo.getCodePath()
   8125                                             + " but expected at " + known.codePathString
   8126                                             + "; ignoring.");
   8127                         }
   8128                     }
   8129                 }
   8130             }
   8131         }
   8132 
   8133         // Initialize package source and resource directories
   8134         File destCodeFile = new File(pkg.applicationInfo.getCodePath());
   8135         File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
   8136 
   8137         SharedUserSetting suid = null;
   8138         PackageSetting pkgSetting = null;
   8139 
   8140         if (!isSystemApp(pkg)) {
   8141             // Only system apps can use these features.
   8142             pkg.mOriginalPackages = null;
   8143             pkg.mRealPackage = null;
   8144             pkg.mAdoptPermissions = null;
   8145         }
   8146 
   8147         // Getting the package setting may have a side-effect, so if we
   8148         // are only checking if scan would succeed, stash a copy of the
   8149         // old setting to restore at the end.
   8150         PackageSetting nonMutatedPs = null;
   8151 
   8152         // writer
   8153         synchronized (mPackages) {
   8154             if (pkg.mSharedUserId != null) {
   8155                 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true);
   8156                 if (suid == null) {
   8157                     throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
   8158                             "Creating application package " + pkg.packageName
   8159                             + " for shared user failed");
   8160                 }
   8161                 if (DEBUG_PACKAGE_SCANNING) {
   8162                     if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
   8163                         Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
   8164                                 + "): packages=" + suid.packages);
   8165                 }
   8166             }
   8167 
   8168             // Check if we are renaming from an original package name.
   8169             PackageSetting origPackage = null;
   8170             String realName = null;
   8171             if (pkg.mOriginalPackages != null) {
   8172                 // This package may need to be renamed to a previously
   8173                 // installed name.  Let's check on that...
   8174                 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
   8175                 if (pkg.mOriginalPackages.contains(renamed)) {
   8176                     // This package had originally been installed as the
   8177                     // original name, and we have already taken care of
   8178                     // transitioning to the new one.  Just update the new
   8179                     // one to continue using the old name.
   8180                     realName = pkg.mRealPackage;
   8181                     if (!pkg.packageName.equals(renamed)) {
   8182                         // Callers into this function may have already taken
   8183                         // care of renaming the package; only do it here if
   8184                         // it is not already done.
   8185                         pkg.setPackageName(renamed);
   8186                     }
   8187 
   8188                 } else {
   8189                     for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
   8190                         if ((origPackage = mSettings.peekPackageLPr(
   8191                                 pkg.mOriginalPackages.get(i))) != null) {
   8192                             // We do have the package already installed under its
   8193                             // original name...  should we use it?
   8194                             if (!verifyPackageUpdateLPr(origPackage, pkg)) {
   8195                                 // New package is not compatible with original.
   8196                                 origPackage = null;
   8197                                 continue;
   8198                             } else if (origPackage.sharedUser != null) {
   8199                                 // Make sure uid is compatible between packages.
   8200                                 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
   8201                                     Slog.w(TAG, "Unable to migrate data from " + origPackage.name
   8202                                             + " to " + pkg.packageName + ": old uid "
   8203                                             + origPackage.sharedUser.name
   8204                                             + " differs from " + pkg.mSharedUserId);
   8205                                     origPackage = null;
   8206                                     continue;
   8207                                 }
   8208                                 // TODO: Add case when shared user id is added [b/28144775]
   8209                             } else {
   8210                                 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
   8211                                         + pkg.packageName + " to old name " + origPackage.name);
   8212                             }
   8213                             break;
   8214                         }
   8215                     }
   8216                 }
   8217             }
   8218 
   8219             if (mTransferedPackages.contains(pkg.packageName)) {
   8220                 Slog.w(TAG, "Package " + pkg.packageName
   8221                         + " was transferred to another, but its .apk remains");
   8222             }
   8223 
   8224             // See comments in nonMutatedPs declaration
   8225             if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
   8226                 PackageSetting foundPs = mSettings.peekPackageLPr(pkg.packageName);
   8227                 if (foundPs != null) {
   8228                     nonMutatedPs = new PackageSetting(foundPs);
   8229                 }
   8230             }
   8231 
   8232             // Just create the setting, don't add it yet. For already existing packages
   8233             // the PkgSetting exists already and doesn't have to be created.
   8234             pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
   8235                     destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
   8236                     pkg.applicationInfo.primaryCpuAbi,
   8237                     pkg.applicationInfo.secondaryCpuAbi,
   8238                     pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
   8239                     user, false);
   8240             if (pkgSetting == null) {
   8241                 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
   8242                         "Creating application package " + pkg.packageName + " failed");
   8243             }
   8244 
   8245             if (pkgSetting.origPackage != null) {
   8246                 // If we are first transitioning from an original package,
   8247                 // fix up the new package's name now.  We need to do this after
   8248                 // looking up the package under its new name, so getPackageLP
   8249                 // can take care of fiddling things correctly.
   8250                 pkg.setPackageName(origPackage.name);
   8251 
   8252                 // File a report about this.
   8253                 String msg = "New package " + pkgSetting.realName
   8254                         + " renamed to replace old package " + pkgSetting.name;
   8255                 reportSettingsProblem(Log.WARN, msg);
   8256 
   8257                 // Make a note of it.
   8258                 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
   8259                     mTransferedPackages.add(origPackage.name);
   8260                 }
   8261 
   8262                 // No longer need to retain this.
   8263                 pkgSetting.origPackage = null;
   8264             }
   8265 
   8266             if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) {
   8267                 // Make a note of it.
   8268                 mTransferedPackages.add(pkg.packageName);
   8269             }
   8270 
   8271             if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
   8272                 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
   8273             }
   8274 
   8275             if ((policyFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
   8276                 // Check all shared libraries and map to their actual file path.
   8277                 // We only do this here for apps not on a system dir, because those
   8278                 // are the only ones that can fail an install due to this.  We
   8279                 // will take care of the system apps by updating all of their
   8280                 // library paths after the scan is done.
   8281                 updateSharedLibrariesLPw(pkg, null);
   8282             }
   8283 
   8284             if (mFoundPolicyFile) {
   8285                 SELinuxMMAC.assignSeinfoValue(pkg);
   8286             }
   8287 
   8288             pkg.applicationInfo.uid = pkgSetting.appId;
   8289             pkg.mExtras = pkgSetting;
   8290             if (shouldCheckUpgradeKeySetLP(pkgSetting, scanFlags)) {
   8291                 if (checkUpgradeKeySetLP(pkgSetting, pkg)) {
   8292                     // We just determined the app is signed correctly, so bring
   8293                     // over the latest parsed certs.
   8294                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
   8295                 } else {
   8296                     if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
   8297                         throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
   8298                                 "Package " + pkg.packageName + " upgrade keys do not match the "
   8299                                 + "previously installed version");
   8300                     } else {
   8301                         pkgSetting.signatures.mSignatures = pkg.mSignatures;
   8302                         String msg = "System package " + pkg.packageName
   8303                             + " signature changed; retaining data.";
   8304                         reportSettingsProblem(Log.WARN, msg);
   8305                     }
   8306                 }
   8307             } else {
   8308                 try {
   8309                     verifySignaturesLP(pkgSetting, pkg);
   8310                     // We just determined the app is signed correctly, so bring
   8311                     // over the latest parsed certs.
   8312                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
   8313                 } catch (PackageManagerException e) {
   8314                     if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
   8315                         throw e;
   8316                     }
   8317                     // The signature has changed, but this package is in the system
   8318                     // image...  let's recover!
   8319                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
   8320                     // However...  if this package is part of a shared user, but it
   8321                     // doesn't match the signature of the shared user, let's fail.
   8322                     // What this means is that you can't change the signatures
   8323                     // associated with an overall shared user, which doesn't seem all
   8324                     // that unreasonable.
   8325                     if (pkgSetting.sharedUser != null) {
   8326                         if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
   8327                                               pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
   8328                             throw new PackageManagerException(
   8329                                     INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
   8330                                             "Signature mismatch for shared user: "
   8331                                             + pkgSetting.sharedUser);
   8332                         }
   8333                     }
   8334                     // File a report about this.
   8335                     String msg = "System package " + pkg.packageName
   8336                         + " signature changed; retaining data.";
   8337                     reportSettingsProblem(Log.WARN, msg);
   8338                 }
   8339             }
   8340             // Verify that this new package doesn't have any content providers
   8341             // that conflict with existing packages.  Only do this if the
   8342             // package isn't already installed, since we don't want to break
   8343             // things that are installed.
   8344             if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
   8345                 final int N = pkg.providers.size();
   8346                 int i;
   8347                 for (i=0; i<N; i++) {
   8348                     PackageParser.Provider p = pkg.providers.get(i);
   8349                     if (p.info.authority != null) {
   8350                         String names[] = p.info.authority.split(";");
   8351                         for (int j = 0; j < names.length; j++) {
   8352                             if (mProvidersByAuthority.containsKey(names[j])) {
   8353                                 PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
   8354                                 final String otherPackageName =
   8355                                         ((other != null && other.getComponentName() != null) ?
   8356                                                 other.getComponentName().getPackageName() : "?");
   8357                                 throw new PackageManagerException(
   8358                                         INSTALL_FAILED_CONFLICTING_PROVIDER,
   8359                                                 "Can't install because provider name " + names[j]
   8360                                                 + " (in package " + pkg.applicationInfo.packageName
   8361                                                 + ") is already used by " + otherPackageName);
   8362                             }
   8363                         }
   8364                     }
   8365                 }
   8366             }
   8367 
   8368             if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
   8369                 // This package wants to adopt ownership of permissions from
   8370                 // another package.
   8371                 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
   8372                     final String origName = pkg.mAdoptPermissions.get(i);
   8373                     final PackageSetting orig = mSettings.peekPackageLPr(origName);
   8374                     if (orig != null) {
   8375                         if (verifyPackageUpdateLPr(orig, pkg)) {
   8376                             Slog.i(TAG, "Adopting permissions from " + origName + " to "
   8377                                     + pkg.packageName);
   8378                             mSettings.transferPermissionsLPw(origName, pkg.packageName);
   8379                         }
   8380                     }
   8381                 }
   8382             }
   8383         }
   8384 
   8385         final String pkgName = pkg.packageName;
   8386 
   8387         final long scanFileTime = getLastModifiedTime(pkg, scanFile);
   8388         final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0;
   8389         pkg.applicationInfo.processName = fixProcessName(
   8390                 pkg.applicationInfo.packageName,
   8391                 pkg.applicationInfo.processName,
   8392                 pkg.applicationInfo.uid);
   8393 
   8394         if (pkg != mPlatformPackage) {
   8395             // Get all of our default paths setup
   8396             pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
   8397         }
   8398 
   8399         final String path = scanFile.getPath();
   8400         final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
   8401 
   8402         if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
   8403             derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */);
   8404 
   8405             // Some system apps still use directory structure for native libraries
   8406             // in which case we might end up not detecting abi solely based on apk
   8407             // structure. Try to detect abi based on directory structure.
   8408             if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
   8409                     pkg.applicationInfo.primaryCpuAbi == null) {
   8410                 setBundledAppAbisAndRoots(pkg, pkgSetting);
   8411                 setNativeLibraryPaths(pkg);
   8412             }
   8413 
   8414         } else {
   8415             if ((scanFlags & SCAN_MOVE) != 0) {
   8416                 // We haven't run dex-opt for this move (since we've moved the compiled output too)
   8417                 // but we already have this packages package info in the PackageSetting. We just
   8418                 // use that and derive the native library path based on the new codepath.
   8419                 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
   8420                 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
   8421             }
   8422 
   8423             // Set native library paths again. For moves, the path will be updated based on the
   8424             // ABIs we've determined above. For non-moves, the path will be updated based on the
   8425             // ABIs we determined during compilation, but the path will depend on the final
   8426             // package path (after the rename away from the stage path).
   8427             setNativeLibraryPaths(pkg);
   8428         }
   8429 
   8430         // This is a special case for the "system" package, where the ABI is
   8431         // dictated by the zygote configuration (and init.rc). We should keep track
   8432         // of this ABI so that we can deal with "normal" applications that run under
   8433         // the same UID correctly.
   8434         if (mPlatformPackage == pkg) {
   8435             pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
   8436                     Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
   8437         }
   8438 
   8439         // If there's a mismatch between the abi-override in the package setting
   8440         // and the abiOverride specified for the install. Warn about this because we
   8441         // would've already compiled the app without taking the package setting into
   8442         // account.
   8443         if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
   8444             if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
   8445                 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
   8446                         " for package " + pkg.packageName);
   8447             }
   8448         }
   8449 
   8450         pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
   8451         pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
   8452         pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
   8453 
   8454         // Copy the derived override back to the parsed package, so that we can
   8455         // update the package settings accordingly.
   8456         pkg.cpuAbiOverride = cpuAbiOverride;
   8457 
   8458         if (DEBUG_ABI_SELECTION) {
   8459             Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
   8460                     + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
   8461                     + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
   8462         }
   8463 
   8464         // Push the derived path down into PackageSettings so we know what to
   8465         // clean up at uninstall time.
   8466         pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
   8467 
   8468         if (DEBUG_ABI_SELECTION) {
   8469             Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
   8470                     " primary=" + pkg.applicationInfo.primaryCpuAbi +
   8471                     " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
   8472         }
   8473 
   8474         if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
   8475             // We don't do this here during boot because we can do it all
   8476             // at once after scanning all existing packages.
   8477             //
   8478             // We also do this *before* we perform dexopt on this package, so that
   8479             // we can avoid redundant dexopts, and also to make sure we've got the
   8480             // code and package path correct.
   8481             adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages,
   8482                     pkg, true /* boot complete */);
   8483         }
   8484 
   8485         if (mFactoryTest && pkg.requestedPermissions.contains(
   8486                 android.Manifest.permission.FACTORY_TEST)) {
   8487             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
   8488         }
   8489 
   8490         if (isSystemApp(pkg)) {
   8491             pkgSetting.isOrphaned = true;
   8492         }
   8493 
   8494         ArrayList<PackageParser.Package> clientLibPkgs = null;
   8495 
   8496         if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
   8497             if (nonMutatedPs != null) {
   8498                 synchronized (mPackages) {
   8499                     mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs);
   8500                 }
   8501             }
   8502             return pkg;
   8503         }
   8504 
   8505         // Only privileged apps and updated privileged apps can add child packages.
   8506         if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
   8507             if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) {
   8508                 throw new PackageManagerException("Only privileged apps and updated "
   8509                         + "privileged apps can add child packages. Ignoring package "
   8510                         + pkg.packageName);
   8511             }
   8512             final int childCount = pkg.childPackages.size();
   8513             for (int i = 0; i < childCount; i++) {
   8514                 PackageParser.Package childPkg = pkg.childPackages.get(i);
   8515                 if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
   8516                         childPkg.packageName)) {
   8517                     throw new PackageManagerException("Cannot override a child package of "
   8518                             + "another disabled system app. Ignoring package " + pkg.packageName);
   8519                 }
   8520             }
   8521         }
   8522 
   8523         // writer
   8524         synchronized (mPackages) {
   8525             if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
   8526                 // Only system apps can add new shared libraries.
   8527                 if (pkg.libraryNames != null) {
   8528                     for (int i=0; i<pkg.libraryNames.size(); i++) {
   8529                         String name = pkg.libraryNames.get(i);
   8530                         boolean allowed = false;
   8531                         if (pkg.isUpdatedSystemApp()) {
   8532                             // New library entries can only be added through the
   8533                             // system image.  This is important to get rid of a lot
   8534                             // of nasty edge cases: for example if we allowed a non-
   8535                             // system update of the app to add a library, then uninstalling
   8536                             // the update would make the library go away, and assumptions
   8537                             // we made such as through app install filtering would now
   8538                             // have allowed apps on the device which aren't compatible
   8539                             // with it.  Better to just have the restriction here, be
   8540                             // conservative, and create many fewer cases that can negatively
   8541                             // impact the user experience.
   8542                             final PackageSetting sysPs = mSettings
   8543                                     .getDisabledSystemPkgLPr(pkg.packageName);
   8544                             if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
   8545                                 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) {
   8546                                     if (name.equals(sysPs.pkg.libraryNames.get(j))) {
   8547                                         allowed = true;
   8548                                         break;
   8549                                     }
   8550                                 }
   8551                             }
   8552                         } else {
   8553                             allowed = true;
   8554                         }
   8555                         if (allowed) {
   8556                             if (!mSharedLibraries.containsKey(name)) {
   8557                                 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName));
   8558                             } else if (!name.equals(pkg.packageName)) {
   8559                                 Slog.w(TAG, "Package " + pkg.packageName + " library "
   8560                                         + name + " already exists; skipping");
   8561                             }
   8562                         } else {
   8563                             Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
   8564                                     + name + " that is not declared on system image; skipping");
   8565                         }
   8566                     }
   8567                     if ((scanFlags & SCAN_BOOTING) == 0) {
   8568                         // If we are not booting, we need to update any applications
   8569                         // that are clients of our shared library.  If we are booting,
   8570                         // this will all be done once the scan is complete.
   8571                         clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
   8572                     }
   8573                 }
   8574             }
   8575         }
   8576 
   8577         if ((scanFlags & SCAN_BOOTING) != 0) {
   8578             // No apps can run during boot scan, so they don't need to be frozen
   8579         } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
   8580             // Caller asked to not kill app, so it's probably not frozen
   8581         } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
   8582             // Caller asked us to ignore frozen check for some reason; they
   8583             // probably didn't know the package name
   8584         } else {
   8585             // We're doing major surgery on this package, so it better be frozen
   8586             // right now to keep it from launching
   8587             checkPackageFrozen(pkgName);
   8588         }
   8589 
   8590         // Also need to kill any apps that are dependent on the library.
   8591         if (clientLibPkgs != null) {
   8592             for (int i=0; i<clientLibPkgs.size(); i++) {
   8593                 PackageParser.Package clientPkg = clientLibPkgs.get(i);
   8594                 killApplication(clientPkg.applicationInfo.packageName,
   8595                         clientPkg.applicationInfo.uid, "update lib");
   8596             }
   8597         }
   8598 
   8599         // Make sure we're not adding any bogus keyset info
   8600         KeySetManagerService ksms = mSettings.mKeySetManagerService;
   8601         ksms.assertScannedPackageValid(pkg);
   8602 
   8603         // writer
   8604         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
   8605 
   8606         boolean createIdmapFailed = false;
   8607         synchronized (mPackages) {
   8608             // We don't expect installation to fail beyond this point
   8609 
   8610             if (pkgSetting.pkg != null) {
   8611                 // Note that |user| might be null during the initial boot scan. If a codePath
   8612                 // for an app has changed during a boot scan, it's due to an app update that's
   8613                 // part of the system partition and marker changes must be applied to all users.
   8614                 maybeRenameForeignDexMarkers(pkgSetting.pkg, pkg,
   8615                     (user != null) ? user : UserHandle.ALL);
   8616             }
   8617 
   8618             // Add the new setting to mSettings
   8619             mSettings.insertPackageSettingLPw(pkgSetting, pkg);
   8620             // Add the new setting to mPackages
   8621             mPackages.put(pkg.applicationInfo.packageName, pkg);
   8622             // Make sure we don't accidentally delete its data.
   8623             final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
   8624             while (iter.hasNext()) {
   8625                 PackageCleanItem item = iter.next();
   8626                 if (pkgName.equals(item.packageName)) {
   8627                     iter.remove();
   8628                 }
   8629             }
   8630 
   8631             // Take care of first install / last update times.
   8632             if (currentTime != 0) {
   8633                 if (pkgSetting.firstInstallTime == 0) {
   8634                     pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
   8635                 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) {
   8636                     pkgSetting.lastUpdateTime = currentTime;
   8637                 }
   8638             } else if (pkgSetting.firstInstallTime == 0) {
   8639                 // We need *something*.  Take time time stamp of the file.
   8640                 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
   8641             } else if ((policyFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
   8642                 if (scanFileTime != pkgSetting.timeStamp) {
   8643                     // A package on the system image has changed; consider this
   8644                     // to be an update.
   8645                     pkgSetting.lastUpdateTime = scanFileTime;
   8646                 }
   8647             }
   8648 
   8649             // Add the package's KeySets to the global KeySetManagerService
   8650             ksms.addScannedPackageLPw(pkg);
   8651 
   8652             int N = pkg.providers.size();
   8653             StringBuilder r = null;
   8654             int i;
   8655             for (i=0; i<N; i++) {
   8656                 PackageParser.Provider p = pkg.providers.get(i);
   8657                 p.info.processName = fixProcessName(pkg.applicationInfo.processName,
   8658                         p.info.processName, pkg.applicationInfo.uid);
   8659                 mProviders.addProvider(p);
   8660                 p.syncable = p.info.isSyncable;
   8661                 if (p.info.authority != null) {
   8662                     String names[] = p.info.authority.split(";");
   8663                     p.info.authority = null;
   8664                     for (int j = 0; j < names.length; j++) {
   8665                         if (j == 1 && p.syncable) {
   8666                             // We only want the first authority for a provider to possibly be
   8667                             // syncable, so if we already added this provider using a different
   8668                             // authority clear the syncable flag. We copy the provider before
   8669                             // changing it because the mProviders object contains a reference
   8670                             // to a provider that we don't want to change.
   8671                             // Only do this for the second authority since the resulting provider
   8672                             // object can be the same for all future authorities for this provider.
   8673                             p = new PackageParser.Provider(p);
   8674                             p.syncable = false;
   8675                         }
   8676                         if (!mProvidersByAuthority.containsKey(names[j])) {
   8677                             mProvidersByAuthority.put(names[j], p);
   8678                             if (p.info.authority == null) {
   8679                                 p.info.authority = names[j];
   8680                             } else {
   8681                                 p.info.authority = p.info.authority + ";" + names[j];
   8682                             }
   8683                             if (DEBUG_PACKAGE_SCANNING) {
   8684                                 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
   8685                                     Log.d(TAG, "Registered content provider: " + names[j]
   8686                                             + ", className = " + p.info.name + ", isSyncable = "
   8687                                             + p.info.isSyncable);
   8688                             }
   8689                         } else {
   8690                             PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
   8691                             Slog.w(TAG, "Skipping provider name " + names[j] +
   8692                                     " (in package " + pkg.applicationInfo.packageName +
   8693                                     "): name already used by "
   8694                                     + ((other != null && other.getComponentName() != null)
   8695                                             ? other.getComponentName().getPackageName() : "?"));
   8696                         }
   8697                     }
   8698                 }
   8699                 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
   8700                     if (r == null) {
   8701                         r = new StringBuilder(256);
   8702                     } else {
   8703                         r.append(' ');
   8704                     }
   8705                     r.append(p.info.name);
   8706                 }
   8707             }
   8708             if (r != null) {
   8709                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
   8710             }
   8711 
   8712             N = pkg.services.size();
   8713             r = null;
   8714             for (i=0; i<N; i++) {
   8715                 PackageParser.Service s = pkg.services.get(i);
   8716                 s.info.processName = fixProcessName(pkg.applicationInfo.processName,
   8717                         s.info.processName, pkg.applicationInfo.uid);
   8718                 mServices.addService(s);
   8719                 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
   8720                     if (r == null) {
   8721                         r = new StringBuilder(256);
   8722                     } else {
   8723                         r.append(' ');
   8724                     }
   8725                     r.append(s.info.name);
   8726                 }
   8727             }
   8728             if (r != null) {
   8729                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
   8730             }
   8731 
   8732             N = pkg.receivers.size();
   8733             r = null;
   8734             for (i=0; i<N; i++) {
   8735                 PackageParser.Activity a = pkg.receivers.get(i);
   8736                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
   8737                         a.info.processName, pkg.applicationInfo.uid);
   8738                 mReceivers.addActivity(a, "receiver");
   8739                 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
   8740                     if (r == null) {
   8741                         r = new StringBuilder(256);
   8742                     } else {
   8743                         r.append(' ');
   8744                     }
   8745                     r.append(a.info.name);
   8746                 }
   8747             }
   8748             if (r != null) {
   8749                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
   8750             }
   8751 
   8752             N = pkg.activities.size();
   8753             r = null;
   8754             for (i=0; i<N; i++) {
   8755                 PackageParser.Activity a = pkg.activities.get(i);
   8756                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
   8757                         a.info.processName, pkg.applicationInfo.uid);
   8758                 mActivities.addActivity(a, "activity");
   8759                 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
   8760                     if (r == null) {
   8761                         r = new StringBuilder(256);
   8762                     } else {
   8763                         r.append(' ');
   8764                     }
   8765                     r.append(a.info.name);
   8766                 }
   8767             }
   8768             if (r != null) {
   8769                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
   8770             }
   8771 
   8772             N = pkg.permissionGroups.size();
   8773             r = null;
   8774             for (i=0; i<N; i++) {
   8775                 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
   8776                 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
   8777                 final String curPackageName = cur == null ? null : cur.info.packageName;
   8778                 final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
   8779                 if (cur == null || isPackageUpdate) {
   8780                     mPermissionGroups.put(pg.info.name, pg);
   8781                     if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
   8782                         if (r == null) {
   8783                             r = new StringBuilder(256);
   8784                         } else {
   8785                             r.append(' ');
   8786                         }
   8787                         if (isPackageUpdate) {
   8788                             r.append("UPD:");
   8789                         }
   8790                         r.append(pg.info.name);
   8791                     }
   8792                 } else {
   8793                     Slog.w(TAG, "Permission group " + pg.info.name + " from package "
   8794                             + pg.info.packageName + " ignored: original from "
   8795                             + cur.info.packageName);
   8796                     if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
   8797                         if (r == null) {
   8798                             r = new StringBuilder(256);
   8799                         } else {
   8800                             r.append(' ');
   8801                         }
   8802                         r.append("DUP:");
   8803                         r.append(pg.info.name);
   8804                     }
   8805                 }
   8806             }
   8807             if (r != null) {
   8808                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
   8809             }
   8810 
   8811             N = pkg.permissions.size();
   8812             r = null;
   8813             for (i=0; i<N; i++) {
   8814                 PackageParser.Permission p = pkg.permissions.get(i);
   8815 
   8816                 // Assume by default that we did not install this permission into the system.
   8817                 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
   8818 
   8819                 // Now that permission groups have a special meaning, we ignore permission
   8820                 // groups for legacy apps to prevent unexpected behavior. In particular,
   8821                 // permissions for one app being granted to someone just becase they happen
   8822                 // to be in a group defined by another app (before this had no implications).
   8823                 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
   8824                     p.group = mPermissionGroups.get(p.info.group);
   8825                     // Warn for a permission in an unknown group.
   8826                     if (p.info.group != null && p.group == null) {
   8827                         Slog.w(TAG, "Permission " + p.info.name + " from package "
   8828                                 + p.info.packageName + " in an unknown group " + p.info.group);
   8829                     }
   8830                 }
   8831 
   8832                 ArrayMap<String, BasePermission> permissionMap =
   8833                         p.tree ? mSettings.mPermissionTrees
   8834                                 : mSettings.mPermissions;
   8835                 BasePermission bp = permissionMap.get(p.info.name);
   8836 
   8837                 // Allow system apps to redefine non-system permissions
   8838                 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
   8839                     final boolean currentOwnerIsSystem = (bp.perm != null
   8840                             && isSystemApp(bp.perm.owner));
   8841                     if (isSystemApp(p.owner)) {
   8842                         if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
   8843                             // It's a built-in permission and no owner, take ownership now
   8844                             bp.packageSetting = pkgSetting;
   8845                             bp.perm = p;
   8846                             bp.uid = pkg.applicationInfo.uid;
   8847                             bp.sourcePackage = p.info.packageName;
   8848                             p.info.flags |= PermissionInfo.FLAG_INSTALLED;
   8849                         } else if (!currentOwnerIsSystem) {
   8850                             String msg = "New decl " + p.owner + " of permission  "
   8851                                     + p.info.name + " is system; overriding " + bp.sourcePackage;
   8852                             reportSettingsProblem(Log.WARN, msg);
   8853                             bp = null;
   8854                         }
   8855                     }
   8856                 }
   8857 
   8858                 if (bp == null) {
   8859                     bp = new BasePermission(p.info.name, p.info.packageName,
   8860                             BasePermission.TYPE_NORMAL);
   8861                     permissionMap.put(p.info.name, bp);
   8862                 }
   8863 
   8864                 if (bp.perm == null) {
   8865                     if (bp.sourcePackage == null
   8866                             || bp.sourcePackage.equals(p.info.packageName)) {
   8867                         BasePermission tree = findPermissionTreeLP(p.info.name);
   8868                         if (tree == null
   8869                                 || tree.sourcePackage.equals(p.info.packageName)) {
   8870                             bp.packageSetting = pkgSetting;
   8871                             bp.perm = p;
   8872                             bp.uid = pkg.applicationInfo.uid;
   8873                             bp.sourcePackage = p.info.packageName;
   8874                             p.info.flags |= PermissionInfo.FLAG_INSTALLED;
   8875                             if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
   8876                                 if (r == null) {
   8877                                     r = new StringBuilder(256);
   8878                                 } else {
   8879                                     r.append(' ');
   8880                                 }
   8881                                 r.append(p.info.name);
   8882                             }
   8883                         } else {
   8884                             Slog.w(TAG, "Permission " + p.info.name + " from package "
   8885                                     + p.info.packageName + " ignored: base tree "
   8886                                     + tree.name + " is from package "
   8887                                     + tree.sourcePackage);
   8888                         }
   8889                     } else {
   8890                         Slog.w(TAG, "Permission " + p.info.name + " from package "
   8891                                 + p.info.packageName + " ignored: original from "
   8892                                 + bp.sourcePackage);
   8893                     }
   8894                 } else if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
   8895                     if (r == null) {
   8896                         r = new StringBuilder(256);
   8897                     } else {
   8898                         r.append(' ');
   8899                     }
   8900                     r.append("DUP:");
   8901                     r.append(p.info.name);
   8902                 }
   8903                 if (bp.perm == p) {
   8904                     bp.protectionLevel = p.info.protectionLevel;
   8905                 }
   8906             }
   8907 
   8908             if (r != null) {
   8909                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
   8910             }
   8911 
   8912             N = pkg.instrumentation.size();
   8913             r = null;
   8914             for (i=0; i<N; i++) {
   8915                 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
   8916                 a.info.packageName = pkg.applicationInfo.packageName;
   8917                 a.info.sourceDir = pkg.applicationInfo.sourceDir;
   8918                 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
   8919                 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
   8920                 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
   8921                 a.info.dataDir = pkg.applicationInfo.dataDir;
   8922                 a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
   8923                 a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
   8924 
   8925                 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
   8926                 a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
   8927                 mInstrumentation.put(a.getComponentName(), a);
   8928                 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
   8929                     if (r == null) {
   8930                         r = new StringBuilder(256);
   8931                     } else {
   8932                         r.append(' ');
   8933                     }
   8934                     r.append(a.info.name);
   8935                 }
   8936             }
   8937             if (r != null) {
   8938                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
   8939             }
   8940 
   8941             if (pkg.protectedBroadcasts != null) {
   8942                 N = pkg.protectedBroadcasts.size();
   8943                 for (i=0; i<N; i++) {
   8944                     mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
   8945                 }
   8946             }
   8947 
   8948             pkgSetting.setTimeStamp(scanFileTime);
   8949 
   8950             // Create idmap files for pairs of (packages, overlay packages).
   8951             // Note: "android", ie framework-res.apk, is handled by native layers.
   8952             if (pkg.mOverlayTarget != null) {
   8953                 // This is an overlay package.
   8954                 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) {
   8955                     if (!mOverlays.containsKey(pkg.mOverlayTarget)) {
   8956                         mOverlays.put(pkg.mOverlayTarget,
   8957                                 new ArrayMap<String, PackageParser.Package>());
   8958                     }
   8959                     ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget);
   8960                     map.put(pkg.packageName, pkg);
   8961                     PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget);
   8962                     if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) {
   8963                         createIdmapFailed = true;
   8964                     }
   8965                 }
   8966             } else if (mOverlays.containsKey(pkg.packageName) &&
   8967                     !pkg.packageName.equals("android")) {
   8968                 // This is a regular package, with one or more known overlay packages.
   8969                 createIdmapsForPackageLI(pkg);
   8970             }
   8971         }
   8972 
   8973         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
   8974 
   8975         if (createIdmapFailed) {
   8976             throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
   8977                     "scanPackageLI failed to createIdmap");
   8978         }
   8979         return pkg;
   8980     }
   8981 
   8982     private void maybeRenameForeignDexMarkers(PackageParser.Package existing,
   8983             PackageParser.Package update, UserHandle user) {
   8984         if (existing.applicationInfo == null || update.applicationInfo == null) {
   8985             // This isn't due to an app installation.
   8986             return;
   8987         }
   8988 
   8989         final File oldCodePath = new File(existing.applicationInfo.getCodePath());
   8990         final File newCodePath = new File(update.applicationInfo.getCodePath());
   8991 
   8992         // The codePath hasn't changed, so there's nothing for us to do.
   8993         if (Objects.equals(oldCodePath, newCodePath)) {
   8994             return;
   8995         }
   8996 
   8997         File canonicalNewCodePath;
   8998         try {
   8999             canonicalNewCodePath = new File(PackageManagerServiceUtils.realpath(newCodePath));
   9000         } catch (IOException e) {
   9001             Slog.w(TAG, "Failed to get canonical path.", e);
   9002             return;
   9003         }
   9004 
   9005         // This is a bit of a hack. The oldCodePath doesn't exist at this point (because
   9006         // we've already renamed / deleted it) so we cannot call realpath on it. Here we assume
   9007         // that the last component of the path (i.e, the name) doesn't need canonicalization
   9008         // (i.e, that it isn't ".", ".." or a symbolic link). This is a valid assumption for now
   9009         // but may change in the future. Hopefully this function won't exist at that point.
   9010         final File canonicalOldCodePath = new File(canonicalNewCodePath.getParentFile(),
   9011                 oldCodePath.getName());
   9012 
   9013         // Calculate the prefixes of the markers. These are just the paths with "/" replaced
   9014         // with "@".
   9015         String oldMarkerPrefix = canonicalOldCodePath.getAbsolutePath().replace('/', '@');
   9016         if (!oldMarkerPrefix.endsWith("@")) {
   9017             oldMarkerPrefix += "@";
   9018         }
   9019         String newMarkerPrefix = canonicalNewCodePath.getAbsolutePath().replace('/', '@');
   9020         if (!newMarkerPrefix.endsWith("@")) {
   9021             newMarkerPrefix += "@";
   9022         }
   9023 
   9024         List<String> updatedPaths = update.getAllCodePathsExcludingResourceOnly();
   9025         List<String> markerSuffixes = new ArrayList<String>(updatedPaths.size());
   9026         for (String updatedPath : updatedPaths) {
   9027             String updatedPathName = new File(updatedPath).getName();
   9028             markerSuffixes.add(updatedPathName.replace('/', '@'));
   9029         }
   9030 
   9031         for (int userId : resolveUserIds(user.getIdentifier())) {
   9032             File profileDir = Environment.getDataProfilesDeForeignDexDirectory(userId);
   9033 
   9034             for (String markerSuffix : markerSuffixes) {
   9035                 File oldForeignUseMark = new File(profileDir, oldMarkerPrefix + markerSuffix);
   9036                 File newForeignUseMark = new File(profileDir, newMarkerPrefix + markerSuffix);
   9037                 if (oldForeignUseMark.exists()) {
   9038                     try {
   9039                         Os.rename(oldForeignUseMark.getAbsolutePath(),
   9040                                 newForeignUseMark.getAbsolutePath());
   9041                     } catch (ErrnoException e) {
   9042                         Slog.w(TAG, "Failed to rename foreign use marker", e);
   9043                         oldForeignUseMark.delete();
   9044                     }
   9045                 }
   9046             }
   9047         }
   9048     }
   9049 
   9050     /**
   9051      * Derive the ABI of a non-system package located at {@code scanFile}. This information
   9052      * is derived purely on the basis of the contents of {@code scanFile} and
   9053      * {@code cpuAbiOverride}.
   9054      *
   9055      * If {@code extractLibs} is true, native libraries are extracted from the app if required.
   9056      */
   9057     private void derivePackageAbi(PackageParser.Package pkg, File scanFile,
   9058                                  String cpuAbiOverride, boolean extractLibs)
   9059             throws PackageManagerException {
   9060         // TODO: We can probably be smarter about this stuff. For installed apps,
   9061         // we can calculate this information at install time once and for all. For
   9062         // system apps, we can probably assume that this information doesn't change
   9063         // after the first boot scan. As things stand, we do lots of unnecessary work.
   9064 
   9065         // Give ourselves some initial paths; we'll come back for another
   9066         // pass once we've determined ABI below.
   9067         setNativeLibraryPaths(pkg);
   9068 
   9069         // We would never need to extract libs for forward-locked and external packages,
   9070         // since the container service will do it for us. We shouldn't attempt to
   9071         // extract libs from system app when it was not updated.
   9072         if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
   9073                 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
   9074             extractLibs = false;
   9075         }
   9076 
   9077         final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
   9078         final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
   9079 
   9080         NativeLibraryHelper.Handle handle = null;
   9081         try {
   9082             handle = NativeLibraryHelper.Handle.create(pkg);
   9083             // TODO(multiArch): This can be null for apps that didn't go through the
   9084             // usual installation process. We can calculate it again, like we
   9085             // do during install time.
   9086             //
   9087             // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
   9088             // unnecessary.
   9089             final File nativeLibraryRoot = new File(nativeLibraryRootStr);
   9090 
   9091             // Null out the abis so that they can be recalculated.
   9092             pkg.applicationInfo.primaryCpuAbi = null;
   9093             pkg.applicationInfo.secondaryCpuAbi = null;
   9094             if (isMultiArch(pkg.applicationInfo)) {
   9095                 // Warn if we've set an abiOverride for multi-lib packages..
   9096                 // By definition, we need to copy both 32 and 64 bit libraries for
   9097                 // such packages.
   9098                 if (pkg.cpuAbiOverride != null
   9099                         && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
   9100                     Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
   9101                 }
   9102 
   9103                 int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
   9104                 int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
   9105                 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
   9106                     if (extractLibs) {
   9107                         abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
   9108                                 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
   9109                                 useIsaSpecificSubdirs);
   9110                     } else {
   9111                         abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
   9112                     }
   9113                 }
   9114 
   9115                 maybeThrowExceptionForMultiArchCopy(
   9116                         "Error unpackaging 32 bit native libs for multiarch app.", abi32);
   9117 
   9118                 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
   9119                     if (extractLibs) {
   9120                         abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
   9121                                 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
   9122                                 useIsaSpecificSubdirs);
   9123                     } else {
   9124                         abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
   9125                     }
   9126                 }
   9127 
   9128                 maybeThrowExceptionForMultiArchCopy(
   9129                         "Error unpackaging 64 bit native libs for multiarch app.", abi64);
   9130 
   9131                 if (abi64 >= 0) {
   9132                     pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
   9133                 }
   9134 
   9135                 if (abi32 >= 0) {
   9136                     final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
   9137                     if (abi64 >= 0) {
   9138                         if (pkg.use32bitAbi) {
   9139                             pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
   9140                             pkg.applicationInfo.primaryCpuAbi = abi;
   9141                         } else {
   9142                             pkg.applicationInfo.secondaryCpuAbi = abi;
   9143                         }
   9144                     } else {
   9145                         pkg.applicationInfo.primaryCpuAbi = abi;
   9146                     }
   9147                 }
   9148 
   9149             } else {
   9150                 String[] abiList = (cpuAbiOverride != null) ?
   9151                         new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
   9152 
   9153                 // Enable gross and lame hacks for apps that are built with old
   9154                 // SDK tools. We must scan their APKs for renderscript bitcode and
   9155                 // not launch them if it's present. Don't bother checking on devices
   9156                 // that don't have 64 bit support.
   9157                 boolean needsRenderScriptOverride = false;
   9158                 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
   9159                         NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
   9160                     abiList = Build.SUPPORTED_32_BIT_ABIS;
   9161                     needsRenderScriptOverride = true;
   9162                 }
   9163 
   9164                 final int copyRet;
   9165                 if (extractLibs) {
   9166                     copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
   9167                             nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
   9168                 } else {
   9169                     copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
   9170                 }
   9171 
   9172                 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
   9173                     throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
   9174                             "Error unpackaging native libs for app, errorCode=" + copyRet);
   9175                 }
   9176 
   9177                 if (copyRet >= 0) {
   9178                     pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
   9179                 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
   9180                     pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
   9181                 } else if (needsRenderScriptOverride) {
   9182                     pkg.applicationInfo.primaryCpuAbi = abiList[0];
   9183                 }
   9184             }
   9185         } catch (IOException ioe) {
   9186             Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
   9187         } finally {
   9188             IoUtils.closeQuietly(handle);
   9189         }
   9190 
   9191         // Now that we've calculated the ABIs and determined if it's an internal app,
   9192         // we will go ahead and populate the nativeLibraryPath.
   9193         setNativeLibraryPaths(pkg);
   9194     }
   9195 
   9196     /**
   9197      * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
   9198      * i.e, so that all packages can be run inside a single process if required.
   9199      *
   9200      * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
   9201      * this function will either try and make the ABI for all packages in {@code packagesForUser}
   9202      * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
   9203      * the ABI selected for {@code packagesForUser}. This variant is used when installing or
   9204      * updating a package that belongs to a shared user.
   9205      *
   9206      * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
   9207      * adds unnecessary complexity.
   9208      */
   9209     private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
   9210             PackageParser.Package scannedPackage, boolean bootComplete) {
   9211         String requiredInstructionSet = null;
   9212         if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
   9213             requiredInstructionSet = VMRuntime.getInstructionSet(
   9214                      scannedPackage.applicationInfo.primaryCpuAbi);
   9215         }
   9216 
   9217         PackageSetting requirer = null;
   9218         for (PackageSetting ps : packagesForUser) {
   9219             // If packagesForUser contains scannedPackage, we skip it. This will happen
   9220             // when scannedPackage is an update of an existing package. Without this check,
   9221             // we will never be able to change the ABI of any package belonging to a shared
   9222             // user, even if it's compatible with other packages.
   9223             if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
   9224                 if (ps.primaryCpuAbiString == null) {
   9225                     continue;
   9226                 }
   9227 
   9228                 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
   9229                 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
   9230                     // We have a mismatch between instruction sets (say arm vs arm64) warn about
   9231                     // this but there's not much we can do.
   9232                     String errorMessage = "Instruction set mismatch, "
   9233                             + ((requirer == null) ? "[caller]" : requirer)
   9234                             + " requires " + requiredInstructionSet + " whereas " + ps
   9235                             + " requires " + instructionSet;
   9236                     Slog.w(TAG, errorMessage);
   9237                 }
   9238 
   9239                 if (requiredInstructionSet == null) {
   9240                     requiredInstructionSet = instructionSet;
   9241                     requirer = ps;
   9242                 }
   9243             }
   9244         }
   9245 
   9246         if (requiredInstructionSet != null) {
   9247             String adjustedAbi;
   9248             if (requirer != null) {
   9249                 // requirer != null implies that either scannedPackage was null or that scannedPackage
   9250                 // did not require an ABI, in which case we have to adjust scannedPackage to match
   9251                 // the ABI of the set (which is the same as requirer's ABI)
   9252                 adjustedAbi = requirer.primaryCpuAbiString;
   9253                 if (scannedPackage != null) {
   9254                     scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
   9255                 }
   9256             } else {
   9257                 // requirer == null implies that we're updating all ABIs in the set to
   9258                 // match scannedPackage.
   9259                 adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
   9260             }
   9261 
   9262             for (PackageSetting ps : packagesForUser) {
   9263                 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
   9264                     if (ps.primaryCpuAbiString != null) {
   9265                         continue;
   9266                     }
   9267 
   9268                     ps.primaryCpuAbiString = adjustedAbi;
   9269                     if (ps.pkg != null && ps.pkg.applicationInfo != null &&
   9270                             !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
   9271                         ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
   9272                         Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
   9273                                 + " (requirer="
   9274                                 + (requirer == null ? "null" : requirer.pkg.packageName)
   9275                                 + ", scannedPackage="
   9276                                 + (scannedPackage != null ? scannedPackage.packageName : "null")
   9277                                 + ")");
   9278                         try {
   9279                             mInstaller.rmdex(ps.codePathString,
   9280                                     getDexCodeInstructionSet(getPreferredInstructionSet()));
   9281                         } catch (InstallerException ignored) {
   9282                         }
   9283                     }
   9284                 }
   9285             }
   9286         }
   9287     }
   9288 
   9289     private void setUpCustomResolverActivity(PackageParser.Package pkg) {
   9290         synchronized (mPackages) {
   9291             mResolverReplaced = true;
   9292             // Set up information for custom user intent resolution activity.
   9293             mResolveActivity.applicationInfo = pkg.applicationInfo;
   9294             mResolveActivity.name = mCustomResolverComponentName.getClassName();
   9295             mResolveActivity.packageName = pkg.applicationInfo.packageName;
   9296             mResolveActivity.processName = pkg.applicationInfo.packageName;
   9297             mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
   9298             mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
   9299                     ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
   9300             mResolveActivity.theme = 0;
   9301             mResolveActivity.exported = true;
   9302             mResolveActivity.enabled = true;
   9303             mResolveInfo.activityInfo = mResolveActivity;
   9304             mResolveInfo.priority = 0;
   9305             mResolveInfo.preferredOrder = 0;
   9306             mResolveInfo.match = 0;
   9307             mResolveComponentName = mCustomResolverComponentName;
   9308             Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
   9309                     mResolveComponentName);
   9310         }
   9311     }
   9312 
   9313     private void setUpEphemeralInstallerActivityLP(ComponentName installerComponent) {
   9314         final PackageParser.Package pkg = mPackages.get(installerComponent.getPackageName());
   9315 
   9316         // Set up information for ephemeral installer activity
   9317         mEphemeralInstallerActivity.applicationInfo = pkg.applicationInfo;
   9318         mEphemeralInstallerActivity.name = mEphemeralInstallerComponent.getClassName();
   9319         mEphemeralInstallerActivity.packageName = pkg.applicationInfo.packageName;
   9320         mEphemeralInstallerActivity.processName = pkg.applicationInfo.packageName;
   9321         mEphemeralInstallerActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
   9322         mEphemeralInstallerActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
   9323                 | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
   9324         mEphemeralInstallerActivity.theme = 0;
   9325         mEphemeralInstallerActivity.exported = true;
   9326         mEphemeralInstallerActivity.enabled = true;
   9327         mEphemeralInstallerInfo.activityInfo = mEphemeralInstallerActivity;
   9328         mEphemeralInstallerInfo.priority = 0;
   9329         mEphemeralInstallerInfo.preferredOrder = 1;
   9330         mEphemeralInstallerInfo.isDefault = true;
   9331         mEphemeralInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
   9332                 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
   9333 
   9334         if (DEBUG_EPHEMERAL) {
   9335             Slog.d(TAG, "Set ephemeral installer activity: " + mEphemeralInstallerComponent);
   9336         }
   9337     }
   9338 
   9339     private static String calculateBundledApkRoot(final String codePathString) {
   9340         final File codePath = new File(codePathString);
   9341         final File codeRoot;
   9342         if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
   9343             codeRoot = Environment.getRootDirectory();
   9344         } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
   9345             codeRoot = Environment.getOemDirectory();
   9346         } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
   9347             codeRoot = Environment.getVendorDirectory();
   9348         } else {
   9349             // Unrecognized code path; take its top real segment as the apk root:
   9350             // e.g. /something/app/blah.apk => /something
   9351             try {
   9352                 File f = codePath.getCanonicalFile();
   9353                 File parent = f.getParentFile();    // non-null because codePath is a file
   9354                 File tmp;
   9355                 while ((tmp = parent.getParentFile()) != null) {
   9356                     f = parent;
   9357                     parent = tmp;
   9358                 }
   9359                 codeRoot = f;
   9360                 Slog.w(TAG, "Unrecognized code path "
   9361                         + codePath + " - using " + codeRoot);
   9362             } catch (IOException e) {
   9363                 // Can't canonicalize the code path -- shenanigans?
   9364                 Slog.w(TAG, "Can't canonicalize code path " + codePath);
   9365                 return Environment.getRootDirectory().getPath();
   9366             }
   9367         }
   9368         return codeRoot.getPath();
   9369     }
   9370 
   9371     /**
   9372      * Derive and set the location of native libraries for the given package,
   9373      * which varies depending on where and how the package was installed.
   9374      */
   9375     private void setNativeLibraryPaths(PackageParser.Package pkg) {
   9376         final ApplicationInfo info = pkg.applicationInfo;
   9377         final String codePath = pkg.codePath;
   9378         final File codeFile = new File(codePath);
   9379         final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
   9380         final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
   9381 
   9382         info.nativeLibraryRootDir = null;
   9383         info.nativeLibraryRootRequiresIsa = false;
   9384         info.nativeLibraryDir = null;
   9385         info.secondaryNativeLibraryDir = null;
   9386 
   9387         if (isApkFile(codeFile)) {
   9388             // Monolithic install
   9389             if (bundledApp) {
   9390                 // If "/system/lib64/apkname" exists, assume that is the per-package
   9391                 // native library directory to use; otherwise use "/system/lib/apkname".
   9392                 final String apkRoot = calculateBundledApkRoot(info.sourceDir);
   9393                 final boolean is64Bit = VMRuntime.is64BitInstructionSet(
   9394                         getPrimaryInstructionSet(info));
   9395 
   9396                 // This is a bundled system app so choose the path based on the ABI.
   9397                 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
   9398                 // is just the default path.
   9399                 final String apkName = deriveCodePathName(codePath);
   9400                 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
   9401                 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
   9402                         apkName).getAbsolutePath();
   9403 
   9404                 if (info.secondaryCpuAbi != null) {
   9405                     final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
   9406                     info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
   9407                             secondaryLibDir, apkName).getAbsolutePath();
   9408                 }
   9409             } else if (asecApp) {
   9410                 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
   9411                         .getAbsolutePath();
   9412             } else {
   9413                 final String apkName = deriveCodePathName(codePath);
   9414                 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName)
   9415                         .getAbsolutePath();
   9416             }
   9417 
   9418             info.nativeLibraryRootRequiresIsa = false;
   9419             info.nativeLibraryDir = info.nativeLibraryRootDir;
   9420         } else {
   9421             // Cluster install
   9422             info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
   9423             info.nativeLibraryRootRequiresIsa = true;
   9424 
   9425             info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
   9426                     getPrimaryInstructionSet(info)).getAbsolutePath();
   9427 
   9428             if (info.secondaryCpuAbi != null) {
   9429                 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
   9430                         VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
   9431             }
   9432         }
   9433     }
   9434 
   9435     /**
   9436      * Calculate the abis and roots for a bundled app. These can uniquely
   9437      * be determined from the contents of the system partition, i.e whether
   9438      * it contains 64 or 32 bit shared libraries etc. We do not validate any
   9439      * of this information, and instead assume that the system was built
   9440      * sensibly.
   9441      */
   9442     private void setBundledAppAbisAndRoots(PackageParser.Package pkg,
   9443                                            PackageSetting pkgSetting) {
   9444         final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
   9445 
   9446         // If "/system/lib64/apkname" exists, assume that is the per-package
   9447         // native library directory to use; otherwise use "/system/lib/apkname".
   9448         final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
   9449         setBundledAppAbi(pkg, apkRoot, apkName);
   9450         // pkgSetting might be null during rescan following uninstall of updates
   9451         // to a bundled app, so accommodate that possibility.  The settings in
   9452         // that case will be established later from the parsed package.
   9453         //
   9454         // If the settings aren't null, sync them up with what we've just derived.
   9455         // note that apkRoot isn't stored in the package settings.
   9456         if (pkgSetting != null) {
   9457             pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
   9458             pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
   9459         }
   9460     }
   9461 
   9462     /**
   9463      * Deduces the ABI of a bundled app and sets the relevant fields on the
   9464      * parsed pkg object.
   9465      *
   9466      * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
   9467      *        under which system libraries are installed.
   9468      * @param apkName the name of the installed package.
   9469      */
   9470     private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
   9471         final File codeFile = new File(pkg.codePath);
   9472 
   9473         final boolean has64BitLibs;
   9474         final boolean has32BitLibs;
   9475         if (isApkFile(codeFile)) {
   9476             // Monolithic install
   9477             has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
   9478             has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
   9479         } else {
   9480             // Cluster install
   9481             final File rootDir = new File(codeFile, LIB_DIR_NAME);
   9482             if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
   9483                     && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
   9484                 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
   9485                 has64BitLibs = (new File(rootDir, isa)).exists();
   9486             } else {
   9487                 has64BitLibs = false;
   9488             }
   9489             if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
   9490                     && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
   9491                 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
   9492                 has32BitLibs = (new File(rootDir, isa)).exists();
   9493             } else {
   9494                 has32BitLibs = false;
   9495             }
   9496         }
   9497 
   9498         if (has64BitLibs && !has32BitLibs) {
   9499             // The package has 64 bit libs, but not 32 bit libs. Its primary
   9500             // ABI should be 64 bit. We can safely assume here that the bundled
   9501             // native libraries correspond to the most preferred ABI in the list.
   9502 
   9503             pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
   9504             pkg.applicationInfo.secondaryCpuAbi = null;
   9505         } else if (has32BitLibs && !has64BitLibs) {
   9506             // The package has 32 bit libs but not 64 bit libs. Its primary
   9507             // ABI should be 32 bit.
   9508 
   9509             pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
   9510             pkg.applicationInfo.secondaryCpuAbi = null;
   9511         } else if (has32BitLibs && has64BitLibs) {
   9512             // The application has both 64 and 32 bit bundled libraries. We check
   9513             // here that the app declares multiArch support, and warn if it doesn't.
   9514             //
   9515             // We will be lenient here and record both ABIs. The primary will be the
   9516             // ABI that's higher on the list, i.e, a device that's configured to prefer
   9517             // 64 bit apps will see a 64 bit primary ABI,
   9518 
   9519             if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
   9520                 Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
   9521             }
   9522 
   9523             if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
   9524                 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
   9525                 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
   9526             } else {
   9527                 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
   9528                 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
   9529             }
   9530         } else {
   9531             pkg.applicationInfo.primaryCpuAbi = null;
   9532             pkg.applicationInfo.secondaryCpuAbi = null;
   9533         }
   9534     }
   9535 
   9536     private void killApplication(String pkgName, int appId, String reason) {
   9537         killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
   9538     }
   9539 
   9540     private void killApplication(String pkgName, int appId, int userId, String reason) {
   9541         // Request the ActivityManager to kill the process(only for existing packages)
   9542         // so that we do not end up in a confused state while the user is still using the older
   9543         // version of the application while the new one gets installed.
   9544         final long token = Binder.clearCallingIdentity();
   9545         try {
   9546             IActivityManager am = ActivityManagerNative.getDefault();
   9547             if (am != null) {
   9548                 try {
   9549                     am.killApplication(pkgName, appId, userId, reason);
   9550                 } catch (RemoteException e) {
   9551                 }
   9552             }
   9553         } finally {
   9554             Binder.restoreCallingIdentity(token);
   9555         }
   9556     }
   9557 
   9558     private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
   9559         // Remove the parent package setting
   9560         PackageSetting ps = (PackageSetting) pkg.mExtras;
   9561         if (ps != null) {
   9562             removePackageLI(ps, chatty);
   9563         }
   9564         // Remove the child package setting
   9565         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
   9566         for (int i = 0; i < childCount; i++) {
   9567             PackageParser.Package childPkg = pkg.childPackages.get(i);
   9568             ps = (PackageSetting) childPkg.mExtras;
   9569             if (ps != null) {
   9570                 removePackageLI(ps, chatty);
   9571             }
   9572         }
   9573     }
   9574 
   9575     void removePackageLI(PackageSetting ps, boolean chatty) {
   9576         if (DEBUG_INSTALL) {
   9577             if (chatty)
   9578                 Log.d(TAG, "Removing package " + ps.name);
   9579         }
   9580 
   9581         // writer
   9582         synchronized (mPackages) {
   9583             mPackages.remove(ps.name);
   9584             final PackageParser.Package pkg = ps.pkg;
   9585             if (pkg != null) {
   9586                 cleanPackageDataStructuresLILPw(pkg, chatty);
   9587             }
   9588         }
   9589     }
   9590 
   9591     void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
   9592         if (DEBUG_INSTALL) {
   9593             if (chatty)
   9594                 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
   9595         }
   9596 
   9597         // writer
   9598         synchronized (mPackages) {
   9599             // Remove the parent package
   9600             mPackages.remove(pkg.applicationInfo.packageName);
   9601             cleanPackageDataStructuresLILPw(pkg, chatty);
   9602 
   9603             // Remove the child packages
   9604             final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
   9605             for (int i = 0; i < childCount; i++) {
   9606                 PackageParser.Package childPkg = pkg.childPackages.get(i);
   9607                 mPackages.remove(childPkg.applicationInfo.packageName);
   9608                 cleanPackageDataStructuresLILPw(childPkg, chatty);
   9609             }
   9610         }
   9611     }
   9612 
   9613     void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
   9614         int N = pkg.providers.size();
   9615         StringBuilder r = null;
   9616         int i;
   9617         for (i=0; i<N; i++) {
   9618             PackageParser.Provider p = pkg.providers.get(i);
   9619             mProviders.removeProvider(p);
   9620             if (p.info.authority == null) {
   9621 
   9622                 /* There was another ContentProvider with this authority when
   9623                  * this app was installed so this authority is null,
   9624                  * Ignore it as we don't have to unregister the provider.
   9625                  */
   9626                 continue;
   9627             }
   9628             String names[] = p.info.authority.split(";");
   9629             for (int j = 0; j < names.length; j++) {
   9630                 if (mProvidersByAuthority.get(names[j]) == p) {
   9631                     mProvidersByAuthority.remove(names[j]);
   9632                     if (DEBUG_REMOVE) {
   9633                         if (chatty)
   9634                             Log.d(TAG, "Unregistered content provider: " + names[j]
   9635                                     + ", className = " + p.info.name + ", isSyncable = "
   9636                                     + p.info.isSyncable);
   9637                     }
   9638                 }
   9639             }
   9640             if (DEBUG_REMOVE && chatty) {
   9641                 if (r == null) {
   9642                     r = new StringBuilder(256);
   9643                 } else {
   9644                     r.append(' ');
   9645                 }
   9646                 r.append(p.info.name);
   9647             }
   9648         }
   9649         if (r != null) {
   9650             if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
   9651         }
   9652 
   9653         N = pkg.services.size();
   9654         r = null;
   9655         for (i=0; i<N; i++) {
   9656             PackageParser.Service s = pkg.services.get(i);
   9657             mServices.removeService(s);
   9658             if (chatty) {
   9659                 if (r == null) {
   9660                     r = new StringBuilder(256);
   9661                 } else {
   9662                     r.append(' ');
   9663                 }
   9664                 r.append(s.info.name);
   9665             }
   9666         }
   9667         if (r != null) {
   9668             if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
   9669         }
   9670 
   9671         N = pkg.receivers.size();
   9672         r = null;
   9673         for (i=0; i<N; i++) {
   9674             PackageParser.Activity a = pkg.receivers.get(i);
   9675             mReceivers.removeActivity(a, "receiver");
   9676             if (DEBUG_REMOVE && chatty) {
   9677                 if (r == null) {
   9678                     r = new StringBuilder(256);
   9679                 } else {
   9680                     r.append(' ');
   9681                 }
   9682                 r.append(a.info.name);
   9683             }
   9684         }
   9685         if (r != null) {
   9686             if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
   9687         }
   9688 
   9689         N = pkg.activities.size();
   9690         r = null;
   9691         for (i=0; i<N; i++) {
   9692             PackageParser.Activity a = pkg.activities.get(i);
   9693             mActivities.removeActivity(a, "activity");
   9694             if (DEBUG_REMOVE && chatty) {
   9695                 if (r == null) {
   9696                     r = new StringBuilder(256);
   9697                 } else {
   9698                     r.append(' ');
   9699                 }
   9700                 r.append(a.info.name);
   9701             }
   9702         }
   9703         if (r != null) {
   9704             if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
   9705         }
   9706 
   9707         N = pkg.permissions.size();
   9708         r = null;
   9709         for (i=0; i<N; i++) {
   9710             PackageParser.Permission p = pkg.permissions.get(i);
   9711             BasePermission bp = mSettings.mPermissions.get(p.info.name);
   9712             if (bp == null) {
   9713                 bp = mSettings.mPermissionTrees.get(p.info.name);
   9714             }
   9715             if (bp != null && bp.perm == p) {
   9716                 bp.perm = null;
   9717                 if (DEBUG_REMOVE && chatty) {
   9718                     if (r == null) {
   9719                         r = new StringBuilder(256);
   9720                     } else {
   9721                         r.append(' ');
   9722                     }
   9723                     r.append(p.info.name);
   9724                 }
   9725             }
   9726             if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
   9727                 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name);
   9728                 if (appOpPkgs != null) {
   9729                     appOpPkgs.remove(pkg.packageName);
   9730                 }
   9731             }
   9732         }
   9733         if (r != null) {
   9734             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
   9735         }
   9736 
   9737         N = pkg.requestedPermissions.size();
   9738         r = null;
   9739         for (i=0; i<N; i++) {
   9740             String perm = pkg.requestedPermissions.get(i);
   9741             BasePermission bp = mSettings.mPermissions.get(perm);
   9742             if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
   9743                 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm);
   9744                 if (appOpPkgs != null) {
   9745                     appOpPkgs.remove(pkg.packageName);
   9746                     if (appOpPkgs.isEmpty()) {
   9747                         mAppOpPermissionPackages.remove(perm);
   9748                     }
   9749                 }
   9750             }
   9751         }
   9752         if (r != null) {
   9753             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
   9754         }
   9755 
   9756         N = pkg.instrumentation.size();
   9757         r = null;
   9758         for (i=0; i<N; i++) {
   9759             PackageParser.Instrumentation a = pkg.instrumentation.get(i);
   9760             mInstrumentation.remove(a.getComponentName());
   9761             if (DEBUG_REMOVE && chatty) {
   9762                 if (r == null) {
   9763                     r = new StringBuilder(256);
   9764                 } else {
   9765                     r.append(' ');
   9766                 }
   9767                 r.append(a.info.name);
   9768             }
   9769         }
   9770         if (r != null) {
   9771             if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
   9772         }
   9773 
   9774         r = null;
   9775         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
   9776             // Only system apps can hold shared libraries.
   9777             if (pkg.libraryNames != null) {
   9778                 for (i=0; i<pkg.libraryNames.size(); i++) {
   9779                     String name = pkg.libraryNames.get(i);
   9780                     SharedLibraryEntry cur = mSharedLibraries.get(name);
   9781                     if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) {
   9782                         mSharedLibraries.remove(name);
   9783                         if (DEBUG_REMOVE && chatty) {
   9784                             if (r == null) {
   9785                                 r = new StringBuilder(256);
   9786                             } else {
   9787                                 r.append(' ');
   9788                             }
   9789                             r.append(name);
   9790                         }
   9791                     }
   9792                 }
   9793             }
   9794         }
   9795         if (r != null) {
   9796             if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
   9797         }
   9798     }
   9799 
   9800     private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
   9801         for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
   9802             if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
   9803                 return true;
   9804             }
   9805         }
   9806         return false;
   9807     }
   9808 
   9809     static final int UPDATE_PERMISSIONS_ALL = 1<<0;
   9810     static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
   9811     static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
   9812 
   9813     private void updatePermissionsLPw(PackageParser.Package pkg, int flags) {
   9814         // Update the parent permissions
   9815         updatePermissionsLPw(pkg.packageName, pkg, flags);
   9816         // Update the child permissions
   9817         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
   9818         for (int i = 0; i < childCount; i++) {
   9819             PackageParser.Package childPkg = pkg.childPackages.get(i);
   9820             updatePermissionsLPw(childPkg.packageName, childPkg, flags);
   9821         }
   9822     }
   9823 
   9824     private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
   9825             int flags) {
   9826         final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
   9827         updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
   9828     }
   9829 
   9830     private void updatePermissionsLPw(String changingPkg,
   9831             PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
   9832         // Make sure there are no dangling permission trees.
   9833         Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
   9834         while (it.hasNext()) {
   9835             final BasePermission bp = it.next();
   9836             if (bp.packageSetting == null) {
   9837                 // We may not yet have parsed the package, so just see if
   9838                 // we still know about its settings.
   9839                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
   9840             }
   9841             if (bp.packageSetting == null) {
   9842                 Slog.w(TAG, "Removing dangling permission tree: " + bp.name
   9843                         + " from package " + bp.sourcePackage);
   9844                 it.remove();
   9845             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
   9846                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
   9847                     Slog.i(TAG, "Removing old permission tree: " + bp.name
   9848                             + " from package " + bp.sourcePackage);
   9849                     flags |= UPDATE_PERMISSIONS_ALL;
   9850                     it.remove();
   9851                 }
   9852             }
   9853         }
   9854 
   9855         // Make sure all dynamic permissions have been assigned to a package,
   9856         // and make sure there are no dangling permissions.
   9857         it = mSettings.mPermissions.values().iterator();
   9858         while (it.hasNext()) {
   9859             final BasePermission bp = it.next();
   9860             if (bp.type == BasePermission.TYPE_DYNAMIC) {
   9861                 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
   9862                         + bp.name + " pkg=" + bp.sourcePackage
   9863                         + " info=" + bp.pendingInfo);
   9864                 if (bp.packageSetting == null && bp.pendingInfo != null) {
   9865                     final BasePermission tree = findPermissionTreeLP(bp.name);
   9866                     if (tree != null && tree.perm != null) {
   9867                         bp.packageSetting = tree.packageSetting;
   9868                         bp.perm = new PackageParser.Permission(tree.perm.owner,
   9869                                 new PermissionInfo(bp.pendingInfo));
   9870                         bp.perm.info.packageName = tree.perm.info.packageName;
   9871                         bp.perm.info.name = bp.name;
   9872                         bp.uid = tree.uid;
   9873                     }
   9874                 }
   9875             }
   9876             if (bp.packageSetting == null) {
   9877                 // We may not yet have parsed the package, so just see if
   9878                 // we still know about its settings.
   9879                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
   9880             }
   9881             if (bp.packageSetting == null) {
   9882                 Slog.w(TAG, "Removing dangling permission: " + bp.name
   9883                         + " from package " + bp.sourcePackage);
   9884                 it.remove();
   9885             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
   9886                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
   9887                     Slog.i(TAG, "Removing old permission: " + bp.name
   9888                             + " from package " + bp.sourcePackage);
   9889                     flags |= UPDATE_PERMISSIONS_ALL;
   9890                     it.remove();
   9891                 }
   9892             }
   9893         }
   9894 
   9895         // Now update the permissions for all packages, in particular
   9896         // replace the granted permissions of the system packages.
   9897         if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
   9898             for (PackageParser.Package pkg : mPackages.values()) {
   9899                 if (pkg != pkgInfo) {
   9900                     // Only replace for packages on requested volume
   9901                     final String volumeUuid = getVolumeUuidForPackage(pkg);
   9902                     final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
   9903                             && Objects.equals(replaceVolumeUuid, volumeUuid);
   9904                     grantPermissionsLPw(pkg, replace, changingPkg);
   9905                 }
   9906             }
   9907         }
   9908 
   9909         if (pkgInfo != null) {
   9910             // Only replace for packages on requested volume
   9911             final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
   9912             final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
   9913                     && Objects.equals(replaceVolumeUuid, volumeUuid);
   9914             grantPermissionsLPw(pkgInfo, replace, changingPkg);
   9915         }
   9916     }
   9917 
   9918     private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
   9919             String packageOfInterest) {
   9920         // IMPORTANT: There are two types of permissions: install and runtime.
   9921         // Install time permissions are granted when the app is installed to
   9922         // all device users and users added in the future. Runtime permissions
   9923         // are granted at runtime explicitly to specific users. Normal and signature
   9924         // protected permissions are install time permissions. Dangerous permissions
   9925         // are install permissions if the app's target SDK is Lollipop MR1 or older,
   9926         // otherwise they are runtime permissions. This function does not manage
   9927         // runtime permissions except for the case an app targeting Lollipop MR1
   9928         // being upgraded to target a newer SDK, in which case dangerous permissions
   9929         // are transformed from install time to runtime ones.
   9930 
   9931         final PackageSetting ps = (PackageSetting) pkg.mExtras;
   9932         if (ps == null) {
   9933             return;
   9934         }
   9935 
   9936         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
   9937 
   9938         PermissionsState permissionsState = ps.getPermissionsState();
   9939         PermissionsState origPermissions = permissionsState;
   9940 
   9941         final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
   9942 
   9943         boolean runtimePermissionsRevoked = false;
   9944         int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
   9945 
   9946         boolean changedInstallPermission = false;
   9947 
   9948         if (replace) {
   9949             ps.installPermissionsFixed = false;
   9950             if (!ps.isSharedUser()) {
   9951                 origPermissions = new PermissionsState(permissionsState);
   9952                 permissionsState.reset();
   9953             } else {
   9954                 // We need to know only about runtime permission changes since the
   9955                 // calling code always writes the install permissions state but
   9956                 // the runtime ones are written only if changed. The only cases of
   9957                 // changed runtime permissions here are promotion of an install to
   9958                 // runtime and revocation of a runtime from a shared user.
   9959                 changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
   9960                         ps.sharedUser, UserManagerService.getInstance().getUserIds());
   9961                 if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
   9962                     runtimePermissionsRevoked = true;
   9963                 }
   9964             }
   9965         }
   9966 
   9967         permissionsState.setGlobalGids(mGlobalGids);
   9968 
   9969         final int N = pkg.requestedPermissions.size();
   9970         for (int i=0; i<N; i++) {
   9971             final String name = pkg.requestedPermissions.get(i);
   9972             final BasePermission bp = mSettings.mPermissions.get(name);
   9973 
   9974             if (DEBUG_INSTALL) {
   9975                 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
   9976             }
   9977 
   9978             if (bp == null || bp.packageSetting == null) {
   9979                 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
   9980                     Slog.w(TAG, "Unknown permission " + name
   9981                             + " in package " + pkg.packageName);
   9982                 }
   9983                 continue;
   9984             }
   9985 
   9986             final String perm = bp.name;
   9987             boolean allowedSig = false;
   9988             int grant = GRANT_DENIED;
   9989 
   9990             // Keep track of app op permissions.
   9991             if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
   9992                 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
   9993                 if (pkgs == null) {
   9994                     pkgs = new ArraySet<>();
   9995                     mAppOpPermissionPackages.put(bp.name, pkgs);
   9996                 }
   9997                 pkgs.add(pkg.packageName);
   9998             }
   9999 
   10000             final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
   10001             final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
   10002                     >= Build.VERSION_CODES.M;
   10003             switch (level) {
   10004                 case PermissionInfo.PROTECTION_NORMAL: {
   10005                     // For all apps normal permissions are install time ones.
   10006                     grant = GRANT_INSTALL;
   10007                 } break;
   10008 
   10009                 case PermissionInfo.PROTECTION_DANGEROUS: {
   10010                     // If a permission review is required for legacy apps we represent
   10011                     // their permissions as always granted runtime ones since we need
   10012                     // to keep the review required permission flag per user while an
   10013                     // install permission's state is shared across all users.
   10014                     if (!appSupportsRuntimePermissions && !Build.PERMISSIONS_REVIEW_REQUIRED) {
   10015                         // For legacy apps dangerous permissions are install time ones.
   10016                         grant = GRANT_INSTALL;
   10017                     } else if (origPermissions.hasInstallPermission(bp.name)) {
   10018                         // For legacy apps that became modern, install becomes runtime.
   10019                         grant = GRANT_UPGRADE;
   10020                     } else if (mPromoteSystemApps
   10021                             && isSystemApp(ps)
   10022                             && mExistingSystemPackages.contains(ps.name)) {
   10023                         // For legacy system apps, install becomes runtime.
   10024                         // We cannot check hasInstallPermission() for system apps since those
   10025                         // permissions were granted implicitly and not persisted pre-M.
   10026                         grant = GRANT_UPGRADE;
   10027                     } else {
   10028                         // For modern apps keep runtime permissions unchanged.
   10029                         grant = GRANT_RUNTIME;
   10030                     }
   10031                 } break;
   10032 
   10033                 case PermissionInfo.PROTECTION_SIGNATURE: {
   10034                     // For all apps signature permissions are install time ones.
   10035                     allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
   10036                     if (allowedSig) {
   10037                         grant = GRANT_INSTALL;
   10038                     }
   10039                 } break;
   10040             }
   10041 
   10042             if (DEBUG_INSTALL) {
   10043                 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
   10044             }
   10045 
   10046             if (grant != GRANT_DENIED) {
   10047                 if (!isSystemApp(ps) && ps.installPermissionsFixed) {
   10048                     // If this is an existing, non-system package, then
   10049                     // we can't add any new permissions to it.
   10050                     if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
   10051                         // Except...  if this is a permission that was added
   10052                         // to the platform (note: need to only do this when
   10053                         // updating the platform).
   10054                         if (!isNewPlatformPermissionForPackage(perm, pkg)) {
   10055                             grant = GRANT_DENIED;
   10056                         }
   10057                     }
   10058                 }
   10059 
   10060                 switch (grant) {
   10061                     case GRANT_INSTALL: {
   10062                         // Revoke this as runtime permission to handle the case of
   10063                         // a runtime permission being downgraded to an install one.
   10064                         // Also in permission review mode we keep dangerous permissions
   10065                         // for legacy apps
   10066                         for (int userId : UserManagerService.getInstance().getUserIds()) {
   10067                             if (origPermissions.getRuntimePermissionState(
   10068                                     bp.name, userId) != null) {
   10069                                 // Revoke the runtime permission and clear the flags.
   10070                                 origPermissions.revokeRuntimePermission(bp, userId);
   10071                                 origPermissions.updatePermissionFlags(bp, userId,
   10072                                       PackageManager.MASK_PERMISSION_FLAGS, 0);
   10073                                 // If we revoked a permission permission, we have to write.
   10074                                 changedRuntimePermissionUserIds = ArrayUtils.appendInt(
   10075                                         changedRuntimePermissionUserIds, userId);
   10076                             }
   10077                         }
   10078                         // Grant an install permission.
   10079                         if (permissionsState.grantInstallPermission(bp) !=
   10080                                 PermissionsState.PERMISSION_OPERATION_FAILURE) {
   10081                             changedInstallPermission = true;
   10082                         }
   10083                     } break;
   10084 
   10085                     case GRANT_RUNTIME: {
   10086                         // Grant previously granted runtime permissions.
   10087                         for (int userId : UserManagerService.getInstance().getUserIds()) {
   10088                             PermissionState permissionState = origPermissions
   10089                                     .getRuntimePermissionState(bp.name, userId);
   10090                             int flags = permissionState != null
   10091                                     ? permissionState.getFlags() : 0;
   10092                             if (origPermissions.hasRuntimePermission(bp.name, userId)) {
   10093                                 if (permissionsState.grantRuntimePermission(bp, userId) ==
   10094                                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
   10095                                     // If we cannot put the permission as it was, we have to write.
   10096                                     changedRuntimePermissionUserIds = ArrayUtils.appendInt(
   10097                                             changedRuntimePermissionUserIds, userId);
   10098                                 }
   10099                                 // If the app supports runtime permissions no need for a review.
   10100                                 if (Build.PERMISSIONS_REVIEW_REQUIRED
   10101                                         && appSupportsRuntimePermissions
   10102                                         && (flags & PackageManager
   10103                                                 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
   10104                                     flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
   10105                                     // Since we changed the flags, we have to write.
   10106                                     changedRuntimePermissionUserIds = ArrayUtils.appendInt(
   10107                                             changedRuntimePermissionUserIds, userId);
   10108                                 }
   10109                             } else if (Build.PERMISSIONS_REVIEW_REQUIRED
   10110                                     && !appSupportsRuntimePermissions) {
   10111                                 // For legacy apps that need a permission review, every new
   10112                                 // runtime permission is granted but it is pending a review.
   10113                                 // We also need to review only platform defined runtime
   10114                                 // permissions as these are the only ones the platform knows
   10115                                 // how to disable the API to simulate revocation as legacy
   10116                                 // apps don't expect to run with revoked permissions.
   10117                                 if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) {
   10118                                     if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
   10119                                         flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
   10120                                         // We changed the flags, hence have to write.
   10121                                         changedRuntimePermissionUserIds = ArrayUtils.appendInt(
   10122                                                 changedRuntimePermissionUserIds, userId);
   10123                                     }
   10124                                 }
   10125                                 if (permissionsState.grantRuntimePermission(bp, userId)
   10126                                         != PermissionsState.PERMISSION_OPERATION_FAILURE) {
   10127                                     // We changed the permission, hence have to write.
   10128                                     changedRuntimePermissionUserIds = ArrayUtils.appendInt(
   10129                                             changedRuntimePermissionUserIds, userId);
   10130                                 }
   10131                             }
   10132                             // Propagate the permission flags.
   10133                             permissionsState.updatePermissionFlags(bp, userId, flags, flags);
   10134                         }
   10135                     } break;
   10136 
   10137                     case GRANT_UPGRADE: {
   10138                         // Grant runtime permissions for a previously held install permission.
   10139                         PermissionState permissionState = origPermissions
   10140                                 .getInstallPermissionState(bp.name);
   10141                         final int flags = permissionState != null ? permissionState.getFlags() : 0;
   10142 
   10143                         if (origPermissions.revokeInstallPermission(bp)
   10144                                 != PermissionsState.PERMISSION_OPERATION_FAILURE) {
   10145                             // We will be transferring the permission flags, so clear them.
   10146                             origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
   10147                                     PackageManager.MASK_PERMISSION_FLAGS, 0);
   10148                             changedInstallPermission = true;
   10149                         }
   10150 
   10151                         // If the permission is not to be promoted to runtime we ignore it and
   10152                         // also its other flags as they are not applicable to install permissions.
   10153                         if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
   10154                             for (int userId : currentUserIds) {
   10155                                 if (permissionsState.grantRuntimePermission(bp, userId) !=
   10156                                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
   10157                                     // Transfer the permission flags.
   10158                                     permissionsState.updatePermissionFlags(bp, userId,
   10159                                             flags, flags);
   10160                                     // If we granted the permission, we have to write.
   10161                                     changedRuntimePermissionUserIds = ArrayUtils.appendInt(
   10162                                             changedRuntimePermissionUserIds, userId);
   10163                                 }
   10164                             }
   10165                         }
   10166                     } break;
   10167 
   10168                     default: {
   10169                         if (packageOfInterest == null
   10170                                 || packageOfInterest.equals(pkg.packageName)) {
   10171                             Slog.w(TAG, "Not granting permission " + perm
   10172                                     + " to package " + pkg.packageName
   10173                                     + " because it was previously installed without");
   10174                         }
   10175                     } break;
   10176                 }
   10177             } else {
   10178                 if (permissionsState.revokeInstallPermission(bp) !=
   10179                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
   10180                     // Also drop the permission flags.
   10181                     permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
   10182                             PackageManager.MASK_PERMISSION_FLAGS, 0);
   10183                     changedInstallPermission = true;
   10184                     Slog.i(TAG, "Un-granting permission " + perm
   10185                             + " from package " + pkg.packageName
   10186                             + " (protectionLevel=" + bp.protectionLevel
   10187                             + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
   10188                             + ")");
   10189                 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
   10190                     // Don't print warning for app op permissions, since it is fine for them
   10191                     // not to be granted, there is a UI for the user to decide.
   10192                     if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
   10193                         Slog.w(TAG, "Not granting permission " + perm
   10194                                 + " to package " + pkg.packageName
   10195                                 + " (protectionLevel=" + bp.protectionLevel
   10196                                 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
   10197                                 + ")");
   10198                     }
   10199                 }
   10200             }
   10201         }
   10202 
   10203         if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
   10204                 !isSystemApp(ps) || isUpdatedSystemApp(ps)){
   10205             // This is the first that we have heard about this package, so the
   10206             // permissions we have now selected are fixed until explicitly
   10207             // changed.
   10208             ps.installPermissionsFixed = true;
   10209         }
   10210 
   10211         // Persist the runtime permissions state for users with changes. If permissions
   10212         // were revoked because no app in the shared user declares them we have to
   10213         // write synchronously to avoid losing runtime permissions state.
   10214         for (int userId : changedRuntimePermissionUserIds) {
   10215             mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
   10216         }
   10217 
   10218         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
   10219     }
   10220 
   10221     private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
   10222         boolean allowed = false;
   10223         final int NP = PackageParser.NEW_PERMISSIONS.length;
   10224         for (int ip=0; ip<NP; ip++) {
   10225             final PackageParser.NewPermissionInfo npi
   10226                     = PackageParser.NEW_PERMISSIONS[ip];
   10227             if (npi.name.equals(perm)
   10228                     && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
   10229                 allowed = true;
   10230                 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
   10231                         + pkg.packageName);
   10232                 break;
   10233             }
   10234         }
   10235         return allowed;
   10236     }
   10237 
   10238     private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
   10239             BasePermission bp, PermissionsState origPermissions) {
   10240         boolean allowed;
   10241         allowed = (compareSignatures(
   10242                 bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
   10243                         == PackageManager.SIGNATURE_MATCH)
   10244                 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
   10245                         == PackageManager.SIGNATURE_MATCH);
   10246         if (!allowed && (bp.protectionLevel
   10247                 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) {
   10248             if (isSystemApp(pkg)) {
   10249                 // For updated system applications, a system permission
   10250                 // is granted only if it had been defined by the original application.
   10251                 if (pkg.isUpdatedSystemApp()) {
   10252                     final PackageSetting sysPs = mSettings
   10253                             .getDisabledSystemPkgLPr(pkg.packageName);
   10254                     if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) {
   10255                         // If the original was granted this permission, we take
   10256                         // that grant decision as read and propagate it to the
   10257                         // update.
   10258                         if (sysPs.isPrivileged()) {
   10259                             allowed = true;
   10260                         }
   10261                     } else {
   10262                         // The system apk may have been updated with an older
   10263                         // version of the one on the data partition, but which
   10264                         // granted a new system permission that it didn't have
   10265                         // before.  In this case we do want to allow the app to
   10266                         // now get the new permission if the ancestral apk is
   10267                         // privileged to get it.
   10268                         if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) {
   10269                             for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) {
   10270                                 if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) {
   10271                                     allowed = true;
   10272                                     break;
   10273                                 }
   10274                             }
   10275                         }
   10276                         // Also if a privileged parent package on the system image or any of
   10277                         // its children requested a privileged permission, the updated child
   10278                         // packages can also get the permission.
   10279                         if (pkg.parentPackage != null) {
   10280                             final PackageSetting disabledSysParentPs = mSettings
   10281                                     .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
   10282                             if (disabledSysParentPs != null && disabledSysParentPs.pkg != null
   10283                                     && disabledSysParentPs.isPrivileged()) {
   10284                                 if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) {
   10285                                     allowed = true;
   10286                                 } else if (disabledSysParentPs.pkg.childPackages != null) {
   10287                                     final int count = disabledSysParentPs.pkg.childPackages.size();
   10288                                     for (int i = 0; i < count; i++) {
   10289                                         PackageParser.Package disabledSysChildPkg =
   10290                                                 disabledSysParentPs.pkg.childPackages.get(i);
   10291                                         if (isPackageRequestingPermission(disabledSysChildPkg,
   10292                                                 perm)) {
   10293                                             allowed = true;
   10294                                             break;
   10295                                         }
   10296                                     }
   10297                                 }
   10298                             }
   10299                         }
   10300                     }
   10301                 } else {
   10302                     allowed = isPrivilegedApp(pkg);
   10303                 }
   10304             }
   10305         }
   10306         if (!allowed) {
   10307             if (!allowed && (bp.protectionLevel
   10308                     & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
   10309                     && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
   10310                 // If this was a previously normal/dangerous permission that got moved
   10311                 // to a system permission as part of the runtime permission redesign, then
   10312                 // we still want to blindly grant it to old apps.
   10313                 allowed = true;
   10314             }
   10315             if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
   10316                     && pkg.packageName.equals(mRequiredInstallerPackage)) {
   10317                 // If this permission is to be granted to the system installer and
   10318                 // this app is an installer, then it gets the permission.
   10319                 allowed = true;
   10320             }
   10321             if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
   10322                     && pkg.packageName.equals(mRequiredVerifierPackage)) {
   10323                 // If this permission is to be granted to the system verifier and
   10324                 // this app is a verifier, then it gets the permission.
   10325                 allowed = true;
   10326             }
   10327             if (!allowed && (bp.protectionLevel
   10328                     & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
   10329                     && isSystemApp(pkg)) {
   10330                 // Any pre-installed system app is allowed to get this permission.
   10331                 allowed = true;
   10332             }
   10333             if (!allowed && (bp.protectionLevel
   10334                     & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
   10335                 // For development permissions, a development permission
   10336                 // is granted only if it was already granted.
   10337                 allowed = origPermissions.hasInstallPermission(perm);
   10338             }
   10339             if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0
   10340                     && pkg.packageName.equals(mSetupWizardPackage)) {
   10341                 // If this permission is to be granted to the system setup wizard and
   10342                 // this app is a setup wizard, then it gets the permission.
   10343                 allowed = true;
   10344             }
   10345         }
   10346         return allowed;
   10347     }
   10348 
   10349     private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
   10350         final int permCount = pkg.requestedPermissions.size();
   10351         for (int j = 0; j < permCount; j++) {
   10352             String requestedPermission = pkg.requestedPermissions.get(j);
   10353             if (permission.equals(requestedPermission)) {
   10354                 return true;
   10355             }
   10356         }
   10357         return false;
   10358     }
   10359 
   10360     final class ActivityIntentResolver
   10361             extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
   10362         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
   10363                 boolean defaultOnly, int userId) {
   10364             if (!sUserManager.exists(userId)) return null;
   10365             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
   10366             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
   10367         }
   10368 
   10369         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
   10370                 int userId) {
   10371             if (!sUserManager.exists(userId)) return null;
   10372             mFlags = flags;
   10373             return super.queryIntent(intent, resolvedType,
   10374                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
   10375         }
   10376 
   10377         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
   10378                 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
   10379             if (!sUserManager.exists(userId)) return null;
   10380             if (packageActivities == null) {
   10381                 return null;
   10382             }
   10383             mFlags = flags;
   10384             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
   10385             final int N = packageActivities.size();
   10386             ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
   10387                 new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
   10388 
   10389             ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
   10390             for (int i = 0; i < N; ++i) {
   10391                 intentFilters = packageActivities.get(i).intents;
   10392                 if (intentFilters != null && intentFilters.size() > 0) {
   10393                     PackageParser.ActivityIntentInfo[] array =
   10394                             new PackageParser.ActivityIntentInfo[intentFilters.size()];
   10395                     intentFilters.toArray(array);
   10396                     listCut.add(array);
   10397                 }
   10398             }
   10399             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
   10400         }
   10401 
   10402         /**
   10403          * Finds a privileged activity that matches the specified activity names.
   10404          */
   10405         private PackageParser.Activity findMatchingActivity(
   10406                 List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
   10407             for (PackageParser.Activity sysActivity : activityList) {
   10408                 if (sysActivity.info.name.equals(activityInfo.name)) {
   10409                     return sysActivity;
   10410                 }
   10411                 if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
   10412                     return sysActivity;
   10413                 }
   10414                 if (sysActivity.info.targetActivity != null) {
   10415                     if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
   10416                         return sysActivity;
   10417                     }
   10418                     if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
   10419                         return sysActivity;
   10420                     }
   10421                 }
   10422             }
   10423             return null;
   10424         }
   10425 
   10426         public class IterGenerator<E> {
   10427             public Iterator<E> generate(ActivityIntentInfo info) {
   10428                 return null;
   10429             }
   10430         }
   10431 
   10432         public class ActionIterGenerator extends IterGenerator<String> {
   10433             @Override
   10434             public Iterator<String> generate(ActivityIntentInfo info) {
   10435                 return info.actionsIterator();
   10436             }
   10437         }
   10438 
   10439         public class CategoriesIterGenerator extends IterGenerator<String> {
   10440             @Override
   10441             public Iterator<String> generate(ActivityIntentInfo info) {
   10442                 return info.categoriesIterator();
   10443             }
   10444         }
   10445 
   10446         public class SchemesIterGenerator extends IterGenerator<String> {
   10447             @Override
   10448             public Iterator<String> generate(ActivityIntentInfo info) {
   10449                 return info.schemesIterator();
   10450             }
   10451         }
   10452 
   10453         public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
   10454             @Override
   10455             public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
   10456                 return info.authoritiesIterator();
   10457             }
   10458         }
   10459 
   10460         /**
   10461          * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
   10462          * MODIFIED. Do not pass in a list that should not be changed.
   10463          */
   10464         private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
   10465                 IterGenerator<T> generator, Iterator<T> searchIterator) {
   10466             // loop through the set of actions; every one must be found in the intent filter
   10467             while (searchIterator.hasNext()) {
   10468                 // we must have at least one filter in the list to consider a match
   10469                 if (intentList.size() == 0) {
   10470                     break;
   10471                 }
   10472 
   10473                 final T searchAction = searchIterator.next();
   10474 
   10475                 // loop through the set of intent filters
   10476                 final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
   10477                 while (intentIter.hasNext()) {
   10478                     final ActivityIntentInfo intentInfo = intentIter.next();
   10479                     boolean selectionFound = false;
   10480 
   10481                     // loop through the intent filter's selection criteria; at least one
   10482                     // of them must match the searched criteria
   10483                     final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
   10484                     while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
   10485                         final T intentSelection = intentSelectionIter.next();
   10486                         if (intentSelection != null && intentSelection.equals(searchAction)) {
   10487                             selectionFound = true;
   10488                             break;
   10489                         }
   10490                     }
   10491 
   10492                     // the selection criteria wasn't found in this filter's set; this filter
   10493                     // is not a potential match
   10494                     if (!selectionFound) {
   10495                         intentIter.remove();
   10496                     }
   10497                 }
   10498             }
   10499         }
   10500 
   10501         private boolean isProtectedAction(ActivityIntentInfo filter) {
   10502             final Iterator<String> actionsIter = filter.actionsIterator();
   10503             while (actionsIter != null && actionsIter.hasNext()) {
   10504                 final String filterAction = actionsIter.next();
   10505                 if (PROTECTED_ACTIONS.contains(filterAction)) {
   10506                     return true;
   10507                 }
   10508             }
   10509             return false;
   10510         }
   10511 
   10512         /**
   10513          * Adjusts the priority of the given intent filter according to policy.
   10514          * <p>
   10515          * <ul>
   10516          * <li>The priority for non privileged applications is capped to '0'</li>
   10517          * <li>The priority for protected actions on privileged applications is capped to '0'</li>
   10518          * <li>The priority for unbundled updates to privileged applications is capped to the
   10519          *      priority defined on the system partition</li>
   10520          * </ul>
   10521          * <p>
   10522          * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
   10523          * allowed to obtain any priority on any action.
   10524          */
   10525         private void adjustPriority(
   10526                 List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
   10527             // nothing to do; priority is fine as-is
   10528             if (intent.getPriority() <= 0) {
   10529                 return;
   10530             }
   10531 
   10532             final ActivityInfo activityInfo = intent.activity.info;
   10533             final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
   10534 
   10535             final boolean privilegedApp =
   10536                     ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
   10537             if (!privilegedApp) {
   10538                 // non-privileged applications can never define a priority >0
   10539                 Slog.w(TAG, "Non-privileged app; cap priority to 0;"
   10540                         + " package: " + applicationInfo.packageName
   10541                         + " activity: " + intent.activity.className
   10542                         + " origPrio: " + intent.getPriority());
   10543                 intent.setPriority(0);
   10544                 return;
   10545             }
   10546 
   10547             if (systemActivities == null) {
   10548                 // the system package is not disabled; we're parsing the system partition
   10549                 if (isProtectedAction(intent)) {
   10550                     if (mDeferProtectedFilters) {
   10551                         // We can't deal with these just yet. No component should ever obtain a
   10552                         // >0 priority for a protected actions, with ONE exception -- the setup
   10553                         // wizard. The setup wizard, however, cannot be known until we're able to
   10554                         // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
   10555                         // until all intent filters have been processed. Chicken, meet egg.
   10556                         // Let the filter temporarily have a high priority and rectify the
   10557                         // priorities after all system packages have been scanned.
   10558                         mProtectedFilters.add(intent);
   10559                         if (DEBUG_FILTERS) {
   10560                             Slog.i(TAG, "Protected action; save for later;"
   10561                                     + " package: " + applicationInfo.packageName
   10562                                     + " activity: " + intent.activity.className
   10563                                     + " origPrio: " + intent.getPriority());
   10564                         }
   10565                         return;
   10566                     } else {
   10567                         if (DEBUG_FILTERS && mSetupWizardPackage == null) {
   10568                             Slog.i(TAG, "No setup wizard;"
   10569                                 + " All protected intents capped to priority 0");
   10570                         }
   10571                         if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
   10572                             if (DEBUG_FILTERS) {
   10573                                 Slog.i(TAG, "Found setup wizard;"
   10574                                     + " allow priority " + intent.getPriority() + ";"
   10575                                     + " package: " + intent.activity.info.packageName
   10576                                     + " activity: " + intent.activity.className
   10577                                     + " priority: " + intent.getPriority());
   10578                             }
   10579                             // setup wizard gets whatever it wants
   10580                             return;
   10581                         }
   10582                         Slog.w(TAG, "Protected action; cap priority to 0;"
   10583                                 + " package: " + intent.activity.info.packageName
   10584                                 + " activity: " + intent.activity.className
   10585                                 + " origPrio: " + intent.getPriority());
   10586                         intent.setPriority(0);
   10587                         return;
   10588                     }
   10589                 }
   10590                 // privileged apps on the system image get whatever priority they request
   10591                 return;
   10592             }
   10593 
   10594             // privileged app unbundled update ... try to find the same activity
   10595             final PackageParser.Activity foundActivity =
   10596                     findMatchingActivity(systemActivities, activityInfo);
   10597             if (foundActivity == null) {
   10598                 // this is a new activity; it cannot obtain >0 priority
   10599                 if (DEBUG_FILTERS) {
   10600                     Slog.i(TAG, "New activity; cap priority to 0;"
   10601                             + " package: " + applicationInfo.packageName
   10602                             + " activity: " + intent.activity.className
   10603                             + " origPrio: " + intent.getPriority());
   10604                 }
   10605                 intent.setPriority(0);
   10606                 return;
   10607             }
   10608 
   10609             // found activity, now check for filter equivalence
   10610 
   10611             // a shallow copy is enough; we modify the list, not its contents
   10612             final List<ActivityIntentInfo> intentListCopy =
   10613                     new ArrayList<>(foundActivity.intents);
   10614             final List<ActivityIntentInfo> foundFilters = findFilters(intent);
   10615 
   10616             // find matching action subsets
   10617             final Iterator<String> actionsIterator = intent.actionsIterator();
   10618             if (actionsIterator != null) {
   10619                 getIntentListSubset(
   10620                         intentListCopy, new ActionIterGenerator(), actionsIterator);
   10621                 if (intentListCopy.size() == 0) {
   10622                     // no more intents to match; we're not equivalent
   10623                     if (DEBUG_FILTERS) {
   10624                         Slog.i(TAG, "Mismatched action; cap priority to 0;"
   10625                                 + " package: " + applicationInfo.packageName
   10626                                 + " activity: " + intent.activity.className
   10627                                 + " origPrio: " + intent.getPriority());
   10628                     }
   10629                     intent.setPriority(0);
   10630                     return;
   10631                 }
   10632             }
   10633 
   10634             // find matching category subsets
   10635             final Iterator<String> categoriesIterator = intent.categoriesIterator();
   10636             if (categoriesIterator != null) {
   10637                 getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
   10638                         categoriesIterator);
   10639                 if (intentListCopy.size() == 0) {
   10640                     // no more intents to match; we're not equivalent
   10641                     if (DEBUG_FILTERS) {
   10642                         Slog.i(TAG, "Mismatched category; cap priority to 0;"
   10643                                 + " package: " + applicationInfo.packageName
   10644                                 + " activity: " + intent.activity.className
   10645                                 + " origPrio: " + intent.getPriority());
   10646                     }
   10647                     intent.setPriority(0);
   10648                     return;
   10649                 }
   10650             }
   10651 
   10652             // find matching schemes subsets
   10653             final Iterator<String> schemesIterator = intent.schemesIterator();
   10654             if (schemesIterator != null) {
   10655                 getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
   10656                         schemesIterator);
   10657                 if (intentListCopy.size() == 0) {
   10658                     // no more intents to match; we're not equivalent
   10659                     if (DEBUG_FILTERS) {
   10660                         Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
   10661                                 + " package: " + applicationInfo.packageName
   10662                                 + " activity: " + intent.activity.className
   10663                                 + " origPrio: " + intent.getPriority());
   10664                     }
   10665                     intent.setPriority(0);
   10666                     return;
   10667                 }
   10668             }
   10669 
   10670             // find matching authorities subsets
   10671             final Iterator<IntentFilter.AuthorityEntry>
   10672                     authoritiesIterator = intent.authoritiesIterator();
   10673             if (authoritiesIterator != null) {
   10674                 getIntentListSubset(intentListCopy,
   10675                         new AuthoritiesIterGenerator(),
   10676                         authoritiesIterator);
   10677                 if (intentListCopy.size() == 0) {
   10678                     // no more intents to match; we're not equivalent
   10679                     if (DEBUG_FILTERS) {
   10680                         Slog.i(TAG, "Mismatched authority; cap priority to 0;"
   10681                                 + " package: " + applicationInfo.packageName
   10682                                 + " activity: " + intent.activity.className
   10683                                 + " origPrio: " + intent.getPriority());
   10684                     }
   10685                     intent.setPriority(0);
   10686                     return;
   10687                 }
   10688             }
   10689 
   10690             // we found matching filter(s); app gets the max priority of all intents
   10691             int cappedPriority = 0;
   10692             for (int i = intentListCopy.size() - 1; i >= 0; --i) {
   10693                 cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
   10694             }
   10695             if (intent.getPriority() > cappedPriority) {
   10696                 if (DEBUG_FILTERS) {
   10697                     Slog.i(TAG, "Found matching filter(s);"
   10698                             + " cap priority to " + cappedPriority + ";"
   10699                             + " package: " + applicationInfo.packageName
   10700                             + " activity: " + intent.activity.className
   10701                             + " origPrio: " + intent.getPriority());
   10702                 }
   10703                 intent.setPriority(cappedPriority);
   10704                 return;
   10705             }
   10706             // all this for nothing; the requested priority was <= what was on the system
   10707         }
   10708 
   10709         public final void addActivity(PackageParser.Activity a, String type) {
   10710             mActivities.put(a.getComponentName(), a);
   10711             if (DEBUG_SHOW_INFO)
   10712                 Log.v(
   10713                 TAG, "  " + type + " " +
   10714                 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
   10715             if (DEBUG_SHOW_INFO)
   10716                 Log.v(TAG, "    Class=" + a.info.name);
   10717             final int NI = a.intents.size();
   10718             for (int j=0; j<NI; j++) {
   10719                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
   10720                 if ("activity".equals(type)) {
   10721                     final PackageSetting ps =
   10722                             mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
   10723                     final List<PackageParser.Activity> systemActivities =
   10724                             ps != null && ps.pkg != null ? ps.pkg.activities : null;
   10725                     adjustPriority(systemActivities, intent);
   10726                 }
   10727                 if (DEBUG_SHOW_INFO) {
   10728                     Log.v(TAG, "    IntentFilter:");
   10729                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   10730                 }
   10731                 if (!intent.debugCheck()) {
   10732                     Log.w(TAG, "==> For Activity " + a.info.name);
   10733                 }
   10734                 addFilter(intent);
   10735             }
   10736         }
   10737 
   10738         public final void removeActivity(PackageParser.Activity a, String type) {
   10739             mActivities.remove(a.getComponentName());
   10740             if (DEBUG_SHOW_INFO) {
   10741                 Log.v(TAG, "  " + type + " "
   10742                         + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
   10743                                 : a.info.name) + ":");
   10744                 Log.v(TAG, "    Class=" + a.info.name);
   10745             }
   10746             final int NI = a.intents.size();
   10747             for (int j=0; j<NI; j++) {
   10748                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
   10749                 if (DEBUG_SHOW_INFO) {
   10750                     Log.v(TAG, "    IntentFilter:");
   10751                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   10752                 }
   10753                 removeFilter(intent);
   10754             }
   10755         }
   10756 
   10757         @Override
   10758         protected boolean allowFilterResult(
   10759                 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
   10760             ActivityInfo filterAi = filter.activity.info;
   10761             for (int i=dest.size()-1; i>=0; i--) {
   10762                 ActivityInfo destAi = dest.get(i).activityInfo;
   10763                 if (destAi.name == filterAi.name
   10764                         && destAi.packageName == filterAi.packageName) {
   10765                     return false;
   10766                 }
   10767             }
   10768             return true;
   10769         }
   10770 
   10771         @Override
   10772         protected ActivityIntentInfo[] newArray(int size) {
   10773             return new ActivityIntentInfo[size];
   10774         }
   10775 
   10776         @Override
   10777         protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
   10778             if (!sUserManager.exists(userId)) return true;
   10779             PackageParser.Package p = filter.activity.owner;
   10780             if (p != null) {
   10781                 PackageSetting ps = (PackageSetting)p.mExtras;
   10782                 if (ps != null) {
   10783                     // System apps are never considered stopped for purposes of
   10784                     // filtering, because there may be no way for the user to
   10785                     // actually re-launch them.
   10786                     return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
   10787                             && ps.getStopped(userId);
   10788                 }
   10789             }
   10790             return false;
   10791         }
   10792 
   10793         @Override
   10794         protected boolean isPackageForFilter(String packageName,
   10795                 PackageParser.ActivityIntentInfo info) {
   10796             return packageName.equals(info.activity.owner.packageName);
   10797         }
   10798 
   10799         @Override
   10800         protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
   10801                 int match, int userId) {
   10802             if (!sUserManager.exists(userId)) return null;
   10803             if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
   10804                 return null;
   10805             }
   10806             final PackageParser.Activity activity = info.activity;
   10807             PackageSetting ps = (PackageSetting) activity.owner.mExtras;
   10808             if (ps == null) {
   10809                 return null;
   10810             }
   10811             ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags,
   10812                     ps.readUserState(userId), userId);
   10813             if (ai == null) {
   10814                 return null;
   10815             }
   10816             final ResolveInfo res = new ResolveInfo();
   10817             res.activityInfo = ai;
   10818             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
   10819                 res.filter = info;
   10820             }
   10821             if (info != null) {
   10822                 res.handleAllWebDataURI = info.handleAllWebDataURI();
   10823             }
   10824             res.priority = info.getPriority();
   10825             res.preferredOrder = activity.owner.mPreferredOrder;
   10826             //System.out.println("Result: " + res.activityInfo.className +
   10827             //                   " = " + res.priority);
   10828             res.match = match;
   10829             res.isDefault = info.hasDefault;
   10830             res.labelRes = info.labelRes;
   10831             res.nonLocalizedLabel = info.nonLocalizedLabel;
   10832             if (userNeedsBadging(userId)) {
   10833                 res.noResourceId = true;
   10834             } else {
   10835                 res.icon = info.icon;
   10836             }
   10837             res.iconResourceId = info.icon;
   10838             res.system = res.activityInfo.applicationInfo.isSystemApp();
   10839             return res;
   10840         }
   10841 
   10842         @Override
   10843         protected void sortResults(List<ResolveInfo> results) {
   10844             Collections.sort(results, mResolvePrioritySorter);
   10845         }
   10846 
   10847         @Override
   10848         protected void dumpFilter(PrintWriter out, String prefix,
   10849                 PackageParser.ActivityIntentInfo filter) {
   10850             out.print(prefix); out.print(
   10851                     Integer.toHexString(System.identityHashCode(filter.activity)));
   10852                     out.print(' ');
   10853                     filter.activity.printComponentShortName(out);
   10854                     out.print(" filter ");
   10855                     out.println(Integer.toHexString(System.identityHashCode(filter)));
   10856         }
   10857 
   10858         @Override
   10859         protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
   10860             return filter.activity;
   10861         }
   10862 
   10863         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
   10864             PackageParser.Activity activity = (PackageParser.Activity)label;
   10865             out.print(prefix); out.print(
   10866                     Integer.toHexString(System.identityHashCode(activity)));
   10867                     out.print(' ');
   10868                     activity.printComponentShortName(out);
   10869             if (count > 1) {
   10870                 out.print(" ("); out.print(count); out.print(" filters)");
   10871             }
   10872             out.println();
   10873         }
   10874 
   10875         // Keys are String (activity class name), values are Activity.
   10876         private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
   10877                 = new ArrayMap<ComponentName, PackageParser.Activity>();
   10878         private int mFlags;
   10879     }
   10880 
   10881     private final class ServiceIntentResolver
   10882             extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
   10883         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
   10884                 boolean defaultOnly, int userId) {
   10885             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
   10886             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
   10887         }
   10888 
   10889         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
   10890                 int userId) {
   10891             if (!sUserManager.exists(userId)) return null;
   10892             mFlags = flags;
   10893             return super.queryIntent(intent, resolvedType,
   10894                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
   10895         }
   10896 
   10897         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
   10898                 int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
   10899             if (!sUserManager.exists(userId)) return null;
   10900             if (packageServices == null) {
   10901                 return null;
   10902             }
   10903             mFlags = flags;
   10904             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
   10905             final int N = packageServices.size();
   10906             ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
   10907                 new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
   10908 
   10909             ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
   10910             for (int i = 0; i < N; ++i) {
   10911                 intentFilters = packageServices.get(i).intents;
   10912                 if (intentFilters != null && intentFilters.size() > 0) {
   10913                     PackageParser.ServiceIntentInfo[] array =
   10914                             new PackageParser.ServiceIntentInfo[intentFilters.size()];
   10915                     intentFilters.toArray(array);
   10916                     listCut.add(array);
   10917                 }
   10918             }
   10919             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
   10920         }
   10921 
   10922         public final void addService(PackageParser.Service s) {
   10923             mServices.put(s.getComponentName(), s);
   10924             if (DEBUG_SHOW_INFO) {
   10925                 Log.v(TAG, "  "
   10926                         + (s.info.nonLocalizedLabel != null
   10927                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
   10928                 Log.v(TAG, "    Class=" + s.info.name);
   10929             }
   10930             final int NI = s.intents.size();
   10931             int j;
   10932             for (j=0; j<NI; j++) {
   10933                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
   10934                 if (DEBUG_SHOW_INFO) {
   10935                     Log.v(TAG, "    IntentFilter:");
   10936                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   10937                 }
   10938                 if (!intent.debugCheck()) {
   10939                     Log.w(TAG, "==> For Service " + s.info.name);
   10940                 }
   10941                 addFilter(intent);
   10942             }
   10943         }
   10944 
   10945         public final void removeService(PackageParser.Service s) {
   10946             mServices.remove(s.getComponentName());
   10947             if (DEBUG_SHOW_INFO) {
   10948                 Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
   10949                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
   10950                 Log.v(TAG, "    Class=" + s.info.name);
   10951             }
   10952             final int NI = s.intents.size();
   10953             int j;
   10954             for (j=0; j<NI; j++) {
   10955                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
   10956                 if (DEBUG_SHOW_INFO) {
   10957                     Log.v(TAG, "    IntentFilter:");
   10958                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   10959                 }
   10960                 removeFilter(intent);
   10961             }
   10962         }
   10963 
   10964         @Override
   10965         protected boolean allowFilterResult(
   10966                 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
   10967             ServiceInfo filterSi = filter.service.info;
   10968             for (int i=dest.size()-1; i>=0; i--) {
   10969                 ServiceInfo destAi = dest.get(i).serviceInfo;
   10970                 if (destAi.name == filterSi.name
   10971                         && destAi.packageName == filterSi.packageName) {
   10972                     return false;
   10973                 }
   10974             }
   10975             return true;
   10976         }
   10977 
   10978         @Override
   10979         protected PackageParser.ServiceIntentInfo[] newArray(int size) {
   10980             return new PackageParser.ServiceIntentInfo[size];
   10981         }
   10982 
   10983         @Override
   10984         protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
   10985             if (!sUserManager.exists(userId)) return true;
   10986             PackageParser.Package p = filter.service.owner;
   10987             if (p != null) {
   10988                 PackageSetting ps = (PackageSetting)p.mExtras;
   10989                 if (ps != null) {
   10990                     // System apps are never considered stopped for purposes of
   10991                     // filtering, because there may be no way for the user to
   10992                     // actually re-launch them.
   10993                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
   10994                             && ps.getStopped(userId);
   10995                 }
   10996             }
   10997             return false;
   10998         }
   10999 
   11000         @Override
   11001         protected boolean isPackageForFilter(String packageName,
   11002                 PackageParser.ServiceIntentInfo info) {
   11003             return packageName.equals(info.service.owner.packageName);
   11004         }
   11005 
   11006         @Override
   11007         protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
   11008                 int match, int userId) {
   11009             if (!sUserManager.exists(userId)) return null;
   11010             final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
   11011             if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
   11012                 return null;
   11013             }
   11014             final PackageParser.Service service = info.service;
   11015             PackageSetting ps = (PackageSetting) service.owner.mExtras;
   11016             if (ps == null) {
   11017                 return null;
   11018             }
   11019             ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
   11020                     ps.readUserState(userId), userId);
   11021             if (si == null) {
   11022                 return null;
   11023             }
   11024             final ResolveInfo res = new ResolveInfo();
   11025             res.serviceInfo = si;
   11026             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
   11027                 res.filter = filter;
   11028             }
   11029             res.priority = info.getPriority();
   11030             res.preferredOrder = service.owner.mPreferredOrder;
   11031             res.match = match;
   11032             res.isDefault = info.hasDefault;
   11033             res.labelRes = info.labelRes;
   11034             res.nonLocalizedLabel = info.nonLocalizedLabel;
   11035             res.icon = info.icon;
   11036             res.system = res.serviceInfo.applicationInfo.isSystemApp();
   11037             return res;
   11038         }
   11039 
   11040         @Override
   11041         protected void sortResults(List<ResolveInfo> results) {
   11042             Collections.sort(results, mResolvePrioritySorter);
   11043         }
   11044 
   11045         @Override
   11046         protected void dumpFilter(PrintWriter out, String prefix,
   11047                 PackageParser.ServiceIntentInfo filter) {
   11048             out.print(prefix); out.print(
   11049                     Integer.toHexString(System.identityHashCode(filter.service)));
   11050                     out.print(' ');
   11051                     filter.service.printComponentShortName(out);
   11052                     out.print(" filter ");
   11053                     out.println(Integer.toHexString(System.identityHashCode(filter)));
   11054         }
   11055 
   11056         @Override
   11057         protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
   11058             return filter.service;
   11059         }
   11060 
   11061         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
   11062             PackageParser.Service service = (PackageParser.Service)label;
   11063             out.print(prefix); out.print(
   11064                     Integer.toHexString(System.identityHashCode(service)));
   11065                     out.print(' ');
   11066                     service.printComponentShortName(out);
   11067             if (count > 1) {
   11068                 out.print(" ("); out.print(count); out.print(" filters)");
   11069             }
   11070             out.println();
   11071         }
   11072 
   11073 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
   11074 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
   11075 //            final List<ResolveInfo> retList = Lists.newArrayList();
   11076 //            while (i.hasNext()) {
   11077 //                final ResolveInfo resolveInfo = (ResolveInfo) i;
   11078 //                if (isEnabledLP(resolveInfo.serviceInfo)) {
   11079 //                    retList.add(resolveInfo);
   11080 //                }
   11081 //            }
   11082 //            return retList;
   11083 //        }
   11084 
   11085         // Keys are String (activity class name), values are Activity.
   11086         private final ArrayMap<ComponentName, PackageParser.Service> mServices
   11087                 = new ArrayMap<ComponentName, PackageParser.Service>();
   11088         private int mFlags;
   11089     };
   11090 
   11091     private final class ProviderIntentResolver
   11092             extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
   11093         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
   11094                 boolean defaultOnly, int userId) {
   11095             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
   11096             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
   11097         }
   11098 
   11099         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
   11100                 int userId) {
   11101             if (!sUserManager.exists(userId))
   11102                 return null;
   11103             mFlags = flags;
   11104             return super.queryIntent(intent, resolvedType,
   11105                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
   11106         }
   11107 
   11108         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
   11109                 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
   11110             if (!sUserManager.exists(userId))
   11111                 return null;
   11112             if (packageProviders == null) {
   11113                 return null;
   11114             }
   11115             mFlags = flags;
   11116             final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
   11117             final int N = packageProviders.size();
   11118             ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
   11119                     new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
   11120 
   11121             ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
   11122             for (int i = 0; i < N; ++i) {
   11123                 intentFilters = packageProviders.get(i).intents;
   11124                 if (intentFilters != null && intentFilters.size() > 0) {
   11125                     PackageParser.ProviderIntentInfo[] array =
   11126                             new PackageParser.ProviderIntentInfo[intentFilters.size()];
   11127                     intentFilters.toArray(array);
   11128                     listCut.add(array);
   11129                 }
   11130             }
   11131             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
   11132         }
   11133 
   11134         public final void addProvider(PackageParser.Provider p) {
   11135             if (mProviders.containsKey(p.getComponentName())) {
   11136                 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
   11137                 return;
   11138             }
   11139 
   11140             mProviders.put(p.getComponentName(), p);
   11141             if (DEBUG_SHOW_INFO) {
   11142                 Log.v(TAG, "  "
   11143                         + (p.info.nonLocalizedLabel != null
   11144                                 ? p.info.nonLocalizedLabel : p.info.name) + ":");
   11145                 Log.v(TAG, "    Class=" + p.info.name);
   11146             }
   11147             final int NI = p.intents.size();
   11148             int j;
   11149             for (j = 0; j < NI; j++) {
   11150                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
   11151                 if (DEBUG_SHOW_INFO) {
   11152                     Log.v(TAG, "    IntentFilter:");
   11153                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   11154                 }
   11155                 if (!intent.debugCheck()) {
   11156                     Log.w(TAG, "==> For Provider " + p.info.name);
   11157                 }
   11158                 addFilter(intent);
   11159             }
   11160         }
   11161 
   11162         public final void removeProvider(PackageParser.Provider p) {
   11163             mProviders.remove(p.getComponentName());
   11164             if (DEBUG_SHOW_INFO) {
   11165                 Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
   11166                         ? p.info.nonLocalizedLabel : p.info.name) + ":");
   11167                 Log.v(TAG, "    Class=" + p.info.name);
   11168             }
   11169             final int NI = p.intents.size();
   11170             int j;
   11171             for (j = 0; j < NI; j++) {
   11172                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
   11173                 if (DEBUG_SHOW_INFO) {
   11174                     Log.v(TAG, "    IntentFilter:");
   11175                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   11176                 }
   11177                 removeFilter(intent);
   11178             }
   11179         }
   11180 
   11181         @Override
   11182         protected boolean allowFilterResult(
   11183                 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
   11184             ProviderInfo filterPi = filter.provider.info;
   11185             for (int i = dest.size() - 1; i >= 0; i--) {
   11186                 ProviderInfo destPi = dest.get(i).providerInfo;
   11187                 if (destPi.name == filterPi.name
   11188                         && destPi.packageName == filterPi.packageName) {
   11189                     return false;
   11190                 }
   11191             }
   11192             return true;
   11193         }
   11194 
   11195         @Override
   11196         protected PackageParser.ProviderIntentInfo[] newArray(int size) {
   11197             return new PackageParser.ProviderIntentInfo[size];
   11198         }
   11199 
   11200         @Override
   11201         protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
   11202             if (!sUserManager.exists(userId))
   11203                 return true;
   11204             PackageParser.Package p = filter.provider.owner;
   11205             if (p != null) {
   11206                 PackageSetting ps = (PackageSetting) p.mExtras;
   11207                 if (ps != null) {
   11208                     // System apps are never considered stopped for purposes of
   11209                     // filtering, because there may be no way for the user to
   11210                     // actually re-launch them.
   11211                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
   11212                             && ps.getStopped(userId);
   11213                 }
   11214             }
   11215             return false;
   11216         }
   11217 
   11218         @Override
   11219         protected boolean isPackageForFilter(String packageName,
   11220                 PackageParser.ProviderIntentInfo info) {
   11221             return packageName.equals(info.provider.owner.packageName);
   11222         }
   11223 
   11224         @Override
   11225         protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
   11226                 int match, int userId) {
   11227             if (!sUserManager.exists(userId))
   11228                 return null;
   11229             final PackageParser.ProviderIntentInfo info = filter;
   11230             if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
   11231                 return null;
   11232             }
   11233             final PackageParser.Provider provider = info.provider;
   11234             PackageSetting ps = (PackageSetting) provider.owner.mExtras;
   11235             if (ps == null) {
   11236                 return null;
   11237             }
   11238             ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
   11239                     ps.readUserState(userId), userId);
   11240             if (pi == null) {
   11241                 return null;
   11242             }
   11243             final ResolveInfo res = new ResolveInfo();
   11244             res.providerInfo = pi;
   11245             if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
   11246                 res.filter = filter;
   11247             }
   11248             res.priority = info.getPriority();
   11249             res.preferredOrder = provider.owner.mPreferredOrder;
   11250             res.match = match;
   11251             res.isDefault = info.hasDefault;
   11252             res.labelRes = info.labelRes;
   11253             res.nonLocalizedLabel = info.nonLocalizedLabel;
   11254             res.icon = info.icon;
   11255             res.system = res.providerInfo.applicationInfo.isSystemApp();
   11256             return res;
   11257         }
   11258 
   11259         @Override
   11260         protected void sortResults(List<ResolveInfo> results) {
   11261             Collections.sort(results, mResolvePrioritySorter);
   11262         }
   11263 
   11264         @Override
   11265         protected void dumpFilter(PrintWriter out, String prefix,
   11266                 PackageParser.ProviderIntentInfo filter) {
   11267             out.print(prefix);
   11268             out.print(
   11269                     Integer.toHexString(System.identityHashCode(filter.provider)));
   11270             out.print(' ');
   11271             filter.provider.printComponentShortName(out);
   11272             out.print(" filter ");
   11273             out.println(Integer.toHexString(System.identityHashCode(filter)));
   11274         }
   11275 
   11276         @Override
   11277         protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
   11278             return filter.provider;
   11279         }
   11280 
   11281         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
   11282             PackageParser.Provider provider = (PackageParser.Provider)label;
   11283             out.print(prefix); out.print(
   11284                     Integer.toHexString(System.identityHashCode(provider)));
   11285                     out.print(' ');
   11286                     provider.printComponentShortName(out);
   11287             if (count > 1) {
   11288                 out.print(" ("); out.print(count); out.print(" filters)");
   11289             }
   11290             out.println();
   11291         }
   11292 
   11293         private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
   11294                 = new ArrayMap<ComponentName, PackageParser.Provider>();
   11295         private int mFlags;
   11296     }
   11297 
   11298     private static final class EphemeralIntentResolver
   11299             extends IntentResolver<EphemeralResolveIntentInfo, EphemeralResolveInfo> {
   11300         /**
   11301          * The result that has the highest defined order. Ordering applies on a
   11302          * per-package basis. Mapping is from package name to Pair of order and
   11303          * EphemeralResolveInfo.
   11304          * <p>
   11305          * NOTE: This is implemented as a field variable for convenience and efficiency.
   11306          * By having a field variable, we're able to track filter ordering as soon as
   11307          * a non-zero order is defined. Otherwise, multiple loops across the result set
   11308          * would be needed to apply ordering. If the intent resolver becomes re-entrant,
   11309          * this needs to be contained entirely within {@link #filterResults()}.
   11310          */
   11311         final ArrayMap<String, Pair<Integer, EphemeralResolveInfo>> mOrderResult = new ArrayMap<>();
   11312 
   11313         @Override
   11314         protected EphemeralResolveIntentInfo[] newArray(int size) {
   11315             return new EphemeralResolveIntentInfo[size];
   11316         }
   11317 
   11318         @Override
   11319         protected boolean isPackageForFilter(String packageName, EphemeralResolveIntentInfo info) {
   11320             return true;
   11321         }
   11322 
   11323         @Override
   11324         protected EphemeralResolveInfo newResult(EphemeralResolveIntentInfo info, int match,
   11325                 int userId) {
   11326             if (!sUserManager.exists(userId)) {
   11327                 return null;
   11328             }
   11329             final String packageName = info.getEphemeralResolveInfo().getPackageName();
   11330             final Integer order = info.getOrder();
   11331             final Pair<Integer, EphemeralResolveInfo> lastOrderResult =
   11332                     mOrderResult.get(packageName);
   11333             // ordering is enabled and this item's order isn't high enough
   11334             if (lastOrderResult != null && lastOrderResult.first >= order) {
   11335                 return null;
   11336             }
   11337             final EphemeralResolveInfo res = info.getEphemeralResolveInfo();
   11338             if (order > 0) {
   11339                 // non-zero order, enable ordering
   11340                 mOrderResult.put(packageName, new Pair<>(order, res));
   11341             }
   11342             return res;
   11343         }
   11344 
   11345         @Override
   11346         protected void filterResults(List<EphemeralResolveInfo> results) {
   11347             // only do work if ordering is enabled [most of the time it won't be]
   11348             if (mOrderResult.size() == 0) {
   11349                 return;
   11350             }
   11351             int resultSize = results.size();
   11352             for (int i = 0; i < resultSize; i++) {
   11353                 final EphemeralResolveInfo info = results.get(i);
   11354                 final String packageName = info.getPackageName();
   11355                 final Pair<Integer, EphemeralResolveInfo> savedInfo = mOrderResult.get(packageName);
   11356                 if (savedInfo == null) {
   11357                     // package doesn't having ordering
   11358                     continue;
   11359                 }
   11360                 if (savedInfo.second == info) {
   11361                     // circled back to the highest ordered item; remove from order list
   11362                     mOrderResult.remove(savedInfo);
   11363                     if (mOrderResult.size() == 0) {
   11364                         // no more ordered items
   11365                         break;
   11366                     }
   11367                     continue;
   11368                 }
   11369                 // item has a worse order, remove it from the result list
   11370                 results.remove(i);
   11371                 resultSize--;
   11372                 i--;
   11373             }
   11374         }
   11375     }
   11376 
   11377     private static final Comparator<ResolveInfo> mResolvePrioritySorter =
   11378             new Comparator<ResolveInfo>() {
   11379         public int compare(ResolveInfo r1, ResolveInfo r2) {
   11380             int v1 = r1.priority;
   11381             int v2 = r2.priority;
   11382             //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
   11383             if (v1 != v2) {
   11384                 return (v1 > v2) ? -1 : 1;
   11385             }
   11386             v1 = r1.preferredOrder;
   11387             v2 = r2.preferredOrder;
   11388             if (v1 != v2) {
   11389                 return (v1 > v2) ? -1 : 1;
   11390             }
   11391             if (r1.isDefault != r2.isDefault) {
   11392                 return r1.isDefault ? -1 : 1;
   11393             }
   11394             v1 = r1.match;
   11395             v2 = r2.match;
   11396             //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
   11397             if (v1 != v2) {
   11398                 return (v1 > v2) ? -1 : 1;
   11399             }
   11400             if (r1.system != r2.system) {
   11401                 return r1.system ? -1 : 1;
   11402             }
   11403             if (r1.activityInfo != null) {
   11404                 return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
   11405             }
   11406             if (r1.serviceInfo != null) {
   11407                 return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
   11408             }
   11409             if (r1.providerInfo != null) {
   11410                 return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
   11411             }
   11412             return 0;
   11413         }
   11414     };
   11415 
   11416     private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
   11417             new Comparator<ProviderInfo>() {
   11418         public int compare(ProviderInfo p1, ProviderInfo p2) {
   11419             final int v1 = p1.initOrder;
   11420             final int v2 = p2.initOrder;
   11421             return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
   11422         }
   11423     };
   11424 
   11425     final void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
   11426             final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
   11427             final int[] userIds) {
   11428         mHandler.post(new Runnable() {
   11429             @Override
   11430             public void run() {
   11431                 try {
   11432                     final IActivityManager am = ActivityManagerNative.getDefault();
   11433                     if (am == null) return;
   11434                     final int[] resolvedUserIds;
   11435                     if (userIds == null) {
   11436                         resolvedUserIds = am.getRunningUserIds();
   11437                     } else {
   11438                         resolvedUserIds = userIds;
   11439                     }
   11440                     for (int id : resolvedUserIds) {
   11441                         final Intent intent = new Intent(action,
   11442                                 pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
   11443                         if (extras != null) {
   11444                             intent.putExtras(extras);
   11445                         }
   11446                         if (targetPkg != null) {
   11447                             intent.setPackage(targetPkg);
   11448                         }
   11449                         // Modify the UID when posting to other users
   11450                         int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
   11451                         if (uid > 0 && UserHandle.getUserId(uid) != id) {
   11452                             uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
   11453                             intent.putExtra(Intent.EXTRA_UID, uid);
   11454                         }
   11455                         intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
   11456                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
   11457                         if (DEBUG_BROADCASTS) {
   11458                             RuntimeException here = new RuntimeException("here");
   11459                             here.fillInStackTrace();
   11460                             Slog.d(TAG, "Sending to user " + id + ": "
   11461                                     + intent.toShortString(false, true, false, false)
   11462                                     + " " + intent.getExtras(), here);
   11463                         }
   11464                         am.broadcastIntent(null, intent, null, finishedReceiver,
   11465                                 0, null, null, null, android.app.AppOpsManager.OP_NONE,
   11466                                 null, finishedReceiver != null, false, id);
   11467                     }
   11468                 } catch (RemoteException ex) {
   11469                 }
   11470             }
   11471         });
   11472     }
   11473 
   11474     /**
   11475      * Check if the external storage media is available. This is true if there
   11476      * is a mounted external storage medium or if the external storage is
   11477      * emulated.
   11478      */
   11479     private boolean isExternalMediaAvailable() {
   11480         return mMediaMounted || Environment.isExternalStorageEmulated();
   11481     }
   11482 
   11483     @Override
   11484     public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
   11485         // writer
   11486         synchronized (mPackages) {
   11487             if (!isExternalMediaAvailable()) {
   11488                 // If the external storage is no longer mounted at this point,
   11489                 // the caller may not have been able to delete all of this
   11490                 // packages files and can not delete any more.  Bail.
   11491                 return null;
   11492             }
   11493             final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
   11494             if (lastPackage != null) {
   11495                 pkgs.remove(lastPackage);
   11496             }
   11497             if (pkgs.size() > 0) {
   11498                 return pkgs.get(0);
   11499             }
   11500         }
   11501         return null;
   11502     }
   11503 
   11504     void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
   11505         final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
   11506                 userId, andCode ? 1 : 0, packageName);
   11507         if (mSystemReady) {
   11508             msg.sendToTarget();
   11509         } else {
   11510             if (mPostSystemReadyMessages == null) {
   11511                 mPostSystemReadyMessages = new ArrayList<>();
   11512             }
   11513             mPostSystemReadyMessages.add(msg);
   11514         }
   11515     }
   11516 
   11517     void startCleaningPackages() {
   11518         // reader
   11519         if (!isExternalMediaAvailable()) {
   11520             return;
   11521         }
   11522         synchronized (mPackages) {
   11523             if (mSettings.mPackagesToBeCleaned.isEmpty()) {
   11524                 return;
   11525             }
   11526         }
   11527         Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
   11528         intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
   11529         IActivityManager am = ActivityManagerNative.getDefault();
   11530         if (am != null) {
   11531             try {
   11532                 am.startService(null, intent, null, mContext.getOpPackageName(),
   11533                         UserHandle.USER_SYSTEM);
   11534             } catch (RemoteException e) {
   11535             }
   11536         }
   11537     }
   11538 
   11539     @Override
   11540     public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
   11541             int installFlags, String installerPackageName, int userId) {
   11542         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
   11543 
   11544         final int callingUid = Binder.getCallingUid();
   11545         enforceCrossUserPermission(callingUid, userId,
   11546                 true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");
   11547 
   11548         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
   11549             try {
   11550                 if (observer != null) {
   11551                     observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
   11552                 }
   11553             } catch (RemoteException re) {
   11554             }
   11555             return;
   11556         }
   11557 
   11558         if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
   11559             installFlags |= PackageManager.INSTALL_FROM_ADB;
   11560 
   11561         } else {
   11562             // Caller holds INSTALL_PACKAGES permission, so we're less strict
   11563             // about installerPackageName.
   11564 
   11565             installFlags &= ~PackageManager.INSTALL_FROM_ADB;
   11566             installFlags &= ~PackageManager.INSTALL_ALL_USERS;
   11567         }
   11568 
   11569         UserHandle user;
   11570         if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
   11571             user = UserHandle.ALL;
   11572         } else {
   11573             user = new UserHandle(userId);
   11574         }
   11575 
   11576         // Only system components can circumvent runtime permissions when installing.
   11577         if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
   11578                 && mContext.checkCallingOrSelfPermission(Manifest.permission
   11579                 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
   11580             throw new SecurityException("You need the "
   11581                     + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
   11582                     + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
   11583         }
   11584 
   11585         final File originFile = new File(originPath);
   11586         final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
   11587 
   11588         final Message msg = mHandler.obtainMessage(INIT_COPY);
   11589         final VerificationInfo verificationInfo = new VerificationInfo(
   11590                 null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);
   11591         final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,
   11592                 installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,
   11593                 null /*packageAbiOverride*/, null /*grantedPermissions*/,
   11594                 null /*certificates*/);
   11595         params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
   11596         msg.obj = params;
   11597 
   11598         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
   11599                 System.identityHashCode(msg.obj));
   11600         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
   11601                 System.identityHashCode(msg.obj));
   11602 
   11603         mHandler.sendMessage(msg);
   11604     }
   11605 
   11606     void installStage(String packageName, File stagedDir, String stagedCid,
   11607             IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
   11608             String installerPackageName, int installerUid, UserHandle user,
   11609             Certificate[][] certificates) {
   11610         if (DEBUG_EPHEMERAL) {
   11611             if ((sessionParams.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) {
   11612                 Slog.d(TAG, "Ephemeral install of " + packageName);
   11613             }
   11614         }
   11615         final VerificationInfo verificationInfo = new VerificationInfo(
   11616                 sessionParams.originatingUri, sessionParams.referrerUri,
   11617                 sessionParams.originatingUid, installerUid);
   11618 
   11619         final OriginInfo origin;
   11620         if (stagedDir != null) {
   11621             origin = OriginInfo.fromStagedFile(stagedDir);
   11622         } else {
   11623             origin = OriginInfo.fromStagedContainer(stagedCid);
   11624         }
   11625 
   11626         final Message msg = mHandler.obtainMessage(INIT_COPY);
   11627         final InstallParams params = new InstallParams(origin, null, observer,
   11628                 sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
   11629                 verificationInfo, user, sessionParams.abiOverride,
   11630                 sessionParams.grantedRuntimePermissions, certificates);
   11631         params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
   11632         msg.obj = params;
   11633 
   11634         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
   11635                 System.identityHashCode(msg.obj));
   11636         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
   11637                 System.identityHashCode(msg.obj));
   11638 
   11639         mHandler.sendMessage(msg);
   11640     }
   11641 
   11642     private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
   11643             int userId) {
   11644         final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
   11645         sendPackageAddedForUser(packageName, isSystem, pkgSetting.appId, userId);
   11646     }
   11647 
   11648     private void sendPackageAddedForUser(String packageName, boolean isSystem,
   11649             int appId, int userId) {
   11650         Bundle extras = new Bundle(1);
   11651         extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, appId));
   11652 
   11653         sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
   11654                 packageName, extras, 0, null, null, new int[] {userId});
   11655         try {
   11656             IActivityManager am = ActivityManagerNative.getDefault();
   11657             if (isSystem && am.isUserRunning(userId, 0)) {
   11658                 // The just-installed/enabled app is bundled on the system, so presumed
   11659                 // to be able to run automatically without needing an explicit launch.
   11660                 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
   11661                 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED)
   11662                         .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
   11663                         .setPackage(packageName);
   11664                 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
   11665                         android.app.AppOpsManager.OP_NONE, null, false, false, userId);
   11666             }
   11667         } catch (RemoteException e) {
   11668             // shouldn't happen
   11669             Slog.w(TAG, "Unable to bootstrap installed package", e);
   11670         }
   11671     }
   11672 
   11673     @Override
   11674     public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
   11675             int userId) {
   11676         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
   11677         PackageSetting pkgSetting;
   11678         final int uid = Binder.getCallingUid();
   11679         enforceCrossUserPermission(uid, userId,
   11680                 true /* requireFullPermission */, true /* checkShell */,
   11681                 "setApplicationHiddenSetting for user " + userId);
   11682 
   11683         if (hidden && isPackageDeviceAdmin(packageName, userId)) {
   11684             Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
   11685             return false;
   11686         }
   11687 
   11688         long callingId = Binder.clearCallingIdentity();
   11689         try {
   11690             boolean sendAdded = false;
   11691             boolean sendRemoved = false;
   11692             // writer
   11693             synchronized (mPackages) {
   11694                 pkgSetting = mSettings.mPackages.get(packageName);
   11695                 if (pkgSetting == null) {
   11696                     return false;
   11697                 }
   11698                 // Do not allow "android" is being disabled
   11699                 if ("android".equals(packageName)) {
   11700                     Slog.w(TAG, "Cannot hide package: android");
   11701                     return false;
   11702                 }
   11703                 // Only allow protected packages to hide themselves.
   11704                 if (hidden && !UserHandle.isSameApp(uid, pkgSetting.appId)
   11705                         && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
   11706                     Slog.w(TAG, "Not hiding protected package: " + packageName);
   11707                     return false;
   11708                 }
   11709 
   11710                 if (pkgSetting.getHidden(userId) != hidden) {
   11711                     pkgSetting.setHidden(hidden, userId);
   11712                     mSettings.writePackageRestrictionsLPr(userId);
   11713                     if (hidden) {
   11714                         sendRemoved = true;
   11715                     } else {
   11716                         sendAdded = true;
   11717                     }
   11718                 }
   11719             }
   11720             if (sendAdded) {
   11721                 sendPackageAddedForUser(packageName, pkgSetting, userId);
   11722                 return true;
   11723             }
   11724             if (sendRemoved) {
   11725                 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
   11726                         "hiding pkg");
   11727                 sendApplicationHiddenForUser(packageName, pkgSetting, userId);
   11728                 return true;
   11729             }
   11730         } finally {
   11731             Binder.restoreCallingIdentity(callingId);
   11732         }
   11733         return false;
   11734     }
   11735 
   11736     private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
   11737             int userId) {
   11738         final PackageRemovedInfo info = new PackageRemovedInfo();
   11739         info.removedPackage = packageName;
   11740         info.removedUsers = new int[] {userId};
   11741         info.uid = UserHandle.getUid(userId, pkgSetting.appId);
   11742         info.sendPackageRemovedBroadcasts(true /*killApp*/);
   11743     }
   11744 
   11745     private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
   11746         if (pkgList.length > 0) {
   11747             Bundle extras = new Bundle(1);
   11748             extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
   11749 
   11750             sendPackageBroadcast(
   11751                     suspended ? Intent.ACTION_PACKAGES_SUSPENDED
   11752                             : Intent.ACTION_PACKAGES_UNSUSPENDED,
   11753                     null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
   11754                     new int[] {userId});
   11755         }
   11756     }
   11757 
   11758     /**
   11759      * Returns true if application is not found or there was an error. Otherwise it returns
   11760      * the hidden state of the package for the given user.
   11761      */
   11762     @Override
   11763     public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
   11764         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
   11765         enforceCrossUserPermission(Binder.getCallingUid(), userId,
   11766                 true /* requireFullPermission */, false /* checkShell */,
   11767                 "getApplicationHidden for user " + userId);
   11768         PackageSetting pkgSetting;
   11769         long callingId = Binder.clearCallingIdentity();
   11770         try {
   11771             // writer
   11772             synchronized (mPackages) {
   11773                 pkgSetting = mSettings.mPackages.get(packageName);
   11774                 if (pkgSetting == null) {
   11775                     return true;
   11776                 }
   11777                 return pkgSetting.getHidden(userId);
   11778             }
   11779         } finally {
   11780             Binder.restoreCallingIdentity(callingId);
   11781         }
   11782     }
   11783 
   11784     /**
   11785      * @hide
   11786      */
   11787     @Override
   11788     public int installExistingPackageAsUser(String packageName, int userId) {
   11789         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
   11790                 null);
   11791         PackageSetting pkgSetting;
   11792         final int uid = Binder.getCallingUid();
   11793         enforceCrossUserPermission(uid, userId,
   11794                 true /* requireFullPermission */, true /* checkShell */,
   11795                 "installExistingPackage for user " + userId);
   11796         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
   11797             return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
   11798         }
   11799 
   11800         long callingId = Binder.clearCallingIdentity();
   11801         try {
   11802             boolean installed = false;
   11803 
   11804             // writer
   11805             synchronized (mPackages) {
   11806                 pkgSetting = mSettings.mPackages.get(packageName);
   11807                 if (pkgSetting == null) {
   11808                     return PackageManager.INSTALL_FAILED_INVALID_URI;
   11809                 }
   11810                 if (!pkgSetting.getInstalled(userId)) {
   11811                     pkgSetting.setInstalled(true, userId);
   11812                     pkgSetting.setHidden(false, userId);
   11813                     mSettings.writePackageRestrictionsLPr(userId);
   11814                     installed = true;
   11815                 }
   11816             }
   11817 
   11818             if (installed) {
   11819                 if (pkgSetting.pkg != null) {
   11820                     synchronized (mInstallLock) {
   11821                         // We don't need to freeze for a brand new install
   11822                         prepareAppDataAfterInstallLIF(pkgSetting.pkg);
   11823                     }
   11824                 }
   11825                 sendPackageAddedForUser(packageName, pkgSetting, userId);
   11826             }
   11827         } finally {
   11828             Binder.restoreCallingIdentity(callingId);
   11829         }
   11830 
   11831         return PackageManager.INSTALL_SUCCEEDED;
   11832     }
   11833 
   11834     boolean isUserRestricted(int userId, String restrictionKey) {
   11835         Bundle restrictions = sUserManager.getUserRestrictions(userId);
   11836         if (restrictions.getBoolean(restrictionKey, false)) {
   11837             Log.w(TAG, "User is restricted: " + restrictionKey);
   11838             return true;
   11839         }
   11840         return false;
   11841     }
   11842 
   11843     @Override
   11844     public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
   11845             int userId) {
   11846         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
   11847         enforceCrossUserPermission(Binder.getCallingUid(), userId,
   11848                 true /* requireFullPermission */, true /* checkShell */,
   11849                 "setPackagesSuspended for user " + userId);
   11850 
   11851         if (ArrayUtils.isEmpty(packageNames)) {
   11852             return packageNames;
   11853         }
   11854 
   11855         // List of package names for whom the suspended state has changed.
   11856         List<String> changedPackages = new ArrayList<>(packageNames.length);
   11857         // List of package names for whom the suspended state is not set as requested in this
   11858         // method.
   11859         List<String> unactionedPackages = new ArrayList<>(packageNames.length);
   11860         long callingId = Binder.clearCallingIdentity();
   11861         try {
   11862             for (int i = 0; i < packageNames.length; i++) {
   11863                 String packageName = packageNames[i];
   11864                 boolean changed = false;
   11865                 final int appId;
   11866                 synchronized (mPackages) {
   11867                     final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
   11868                     if (pkgSetting == null) {
   11869                         Slog.w(TAG, "Could not find package setting for package \"" + packageName
   11870                                 + "\". Skipping suspending/un-suspending.");
   11871                         unactionedPackages.add(packageName);
   11872                         continue;
   11873                     }
   11874                     appId = pkgSetting.appId;
   11875                     if (pkgSetting.getSuspended(userId) != suspended) {
   11876                         if (!canSuspendPackageForUserLocked(packageName, userId)) {
   11877                             unactionedPackages.add(packageName);
   11878                             continue;
   11879                         }
   11880                         pkgSetting.setSuspended(suspended, userId);
   11881                         mSettings.writePackageRestrictionsLPr(userId);
   11882                         changed = true;
   11883                         changedPackages.add(packageName);
   11884                     }
   11885                 }
   11886 
   11887                 if (changed && suspended) {
   11888                     killApplication(packageName, UserHandle.getUid(userId, appId),
   11889                             "suspending package");
   11890                 }
   11891             }
   11892         } finally {
   11893             Binder.restoreCallingIdentity(callingId);
   11894         }
   11895 
   11896         if (!changedPackages.isEmpty()) {
   11897             sendPackagesSuspendedForUser(changedPackages.toArray(
   11898                     new String[changedPackages.size()]), userId, suspended);
   11899         }
   11900 
   11901         return unactionedPackages.toArray(new String[unactionedPackages.size()]);
   11902     }
   11903 
   11904     @Override
   11905     public boolean isPackageSuspendedForUser(String packageName, int userId) {
   11906         enforceCrossUserPermission(Binder.getCallingUid(), userId,
   11907                 true /* requireFullPermission */, false /* checkShell */,
   11908                 "isPackageSuspendedForUser for user " + userId);
   11909         synchronized (mPackages) {
   11910             final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
   11911             if (pkgSetting == null) {
   11912                 throw new IllegalArgumentException("Unknown target package: " + packageName);
   11913             }
   11914             return pkgSetting.getSuspended(userId);
   11915         }
   11916     }
   11917 
   11918     private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
   11919         if (isPackageDeviceAdmin(packageName, userId)) {
   11920             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
   11921                     + "\": has an active device admin");
   11922             return false;
   11923         }
   11924 
   11925         String activeLauncherPackageName = getActiveLauncherPackageName(userId);
   11926         if (packageName.equals(activeLauncherPackageName)) {
   11927             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
   11928                     + "\": contains the active launcher");
   11929             return false;
   11930         }
   11931 
   11932         if (packageName.equals(mRequiredInstallerPackage)) {
   11933             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
   11934                     + "\": required for package installation");
   11935             return false;
   11936         }
   11937 
   11938         if (packageName.equals(mRequiredUninstallerPackage)) {
   11939             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
   11940                     + "\": required for package uninstallation");
   11941             return false;
   11942         }
   11943 
   11944         if (packageName.equals(mRequiredVerifierPackage)) {
   11945             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
   11946                     + "\": required for package verification");
   11947             return false;
   11948         }
   11949 
   11950         if (packageName.equals(getDefaultDialerPackageName(userId))) {
   11951             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
   11952                     + "\": is the default dialer");
   11953             return false;
   11954         }
   11955 
   11956         if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
   11957             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
   11958                     + "\": protected package");
   11959             return false;
   11960         }
   11961 
   11962         return true;
   11963     }
   11964 
   11965     private String getActiveLauncherPackageName(int userId) {
   11966         Intent intent = new Intent(Intent.ACTION_MAIN);
   11967         intent.addCategory(Intent.CATEGORY_HOME);
   11968         ResolveInfo resolveInfo = resolveIntent(
   11969                 intent,
   11970                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
   11971                 PackageManager.MATCH_DEFAULT_ONLY,
   11972                 userId);
   11973 
   11974         return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
   11975     }
   11976 
   11977     private String getDefaultDialerPackageName(int userId) {
   11978         synchronized (mPackages) {
   11979             return mSettings.getDefaultDialerPackageNameLPw(userId);
   11980         }
   11981     }
   11982 
   11983     @Override
   11984     public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
   11985         mContext.enforceCallingOrSelfPermission(
   11986                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
   11987                 "Only package verification agents can verify applications");
   11988 
   11989         final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
   11990         final PackageVerificationResponse response = new PackageVerificationResponse(
   11991                 verificationCode, Binder.getCallingUid());
   11992         msg.arg1 = id;
   11993         msg.obj = response;
   11994         mHandler.sendMessage(msg);
   11995     }
   11996 
   11997     @Override
   11998     public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
   11999             long millisecondsToDelay) {
   12000         mContext.enforceCallingOrSelfPermission(
   12001                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
   12002                 "Only package verification agents can extend verification timeouts");
   12003 
   12004         final PackageVerificationState state = mPendingVerification.get(id);
   12005         final PackageVerificationResponse response = new PackageVerificationResponse(
   12006                 verificationCodeAtTimeout, Binder.getCallingUid());
   12007 
   12008         if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
   12009             millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
   12010         }
   12011         if (millisecondsToDelay < 0) {
   12012             millisecondsToDelay = 0;
   12013         }
   12014         if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
   12015                 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
   12016             verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
   12017         }
   12018 
   12019         if ((state != null) && !state.timeoutExtended()) {
   12020             state.extendTimeout();
   12021 
   12022             final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
   12023             msg.arg1 = id;
   12024             msg.obj = response;
   12025             mHandler.sendMessageDelayed(msg, millisecondsToDelay);
   12026         }
   12027     }
   12028 
   12029     private void broadcastPackageVerified(int verificationId, Uri packageUri,
   12030             int verificationCode, UserHandle user) {
   12031         final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
   12032         intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
   12033         intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
   12034         intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
   12035         intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
   12036 
   12037         mContext.sendBroadcastAsUser(intent, user,
   12038                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
   12039     }
   12040 
   12041     private ComponentName matchComponentForVerifier(String packageName,
   12042             List<ResolveInfo> receivers) {
   12043         ActivityInfo targetReceiver = null;
   12044 
   12045         final int NR = receivers.size();
   12046         for (int i = 0; i < NR; i++) {
   12047             final ResolveInfo info = receivers.get(i);
   12048             if (info.activityInfo == null) {
   12049                 continue;
   12050             }
   12051 
   12052             if (packageName.equals(info.activityInfo.packageName)) {
   12053                 targetReceiver = info.activityInfo;
   12054                 break;
   12055             }
   12056         }
   12057 
   12058         if (targetReceiver == null) {
   12059             return null;
   12060         }
   12061 
   12062         return new ComponentName(targetReceiver.packageName, targetReceiver.name);
   12063     }
   12064 
   12065     private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
   12066             List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
   12067         if (pkgInfo.verifiers.length == 0) {
   12068             return null;
   12069         }
   12070 
   12071         final int N = pkgInfo.verifiers.length;
   12072         final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
   12073         for (int i = 0; i < N; i++) {
   12074             final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
   12075 
   12076             final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
   12077                     receivers);
   12078             if (comp == null) {
   12079                 continue;
   12080             }
   12081 
   12082             final int verifierUid = getUidForVerifier(verifierInfo);
   12083             if (verifierUid == -1) {
   12084                 continue;
   12085             }
   12086 
   12087             if (DEBUG_VERIFY) {
   12088                 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
   12089                         + " with the correct signature");
   12090             }
   12091             sufficientVerifiers.add(comp);
   12092             verificationState.addSufficientVerifier(verifierUid);
   12093         }
   12094 
   12095         return sufficientVerifiers;
   12096     }
   12097 
   12098     private int getUidForVerifier(VerifierInfo verifierInfo) {
   12099         synchronized (mPackages) {
   12100             final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
   12101             if (pkg == null) {
   12102                 return -1;
   12103             } else if (pkg.mSignatures.length != 1) {
   12104                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
   12105                         + " has more than one signature; ignoring");
   12106                 return -1;
   12107             }
   12108 
   12109             /*
   12110              * If the public key of the package's signature does not match
   12111              * our expected public key, then this is a different package and
   12112              * we should skip.
   12113              */
   12114 
   12115             final byte[] expectedPublicKey;
   12116             try {
   12117                 final Signature verifierSig = pkg.mSignatures[0];
   12118                 final PublicKey publicKey = verifierSig.getPublicKey();
   12119                 expectedPublicKey = publicKey.getEncoded();
   12120             } catch (CertificateException e) {
   12121                 return -1;
   12122             }
   12123 
   12124             final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
   12125 
   12126             if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
   12127                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
   12128                         + " does not have the expected public key; ignoring");
   12129                 return -1;
   12130             }
   12131 
   12132             return pkg.applicationInfo.uid;
   12133         }
   12134     }
   12135 
   12136     @Override
   12137     public void finishPackageInstall(int token, boolean didLaunch) {
   12138         enforceSystemOrRoot("Only the system is allowed to finish installs");
   12139 
   12140         if (DEBUG_INSTALL) {
   12141             Slog.v(TAG, "BM finishing package install for " + token);
   12142         }
   12143         Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
   12144 
   12145         final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
   12146         mHandler.sendMessage(msg);
   12147     }
   12148 
   12149     /**
   12150      * Get the verification agent timeout.
   12151      *
   12152      * @return verification timeout in milliseconds
   12153      */
   12154     private long getVerificationTimeout() {
   12155         return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
   12156                 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
   12157                 DEFAULT_VERIFICATION_TIMEOUT);
   12158     }
   12159 
   12160     /**
   12161      * Get the default verification agent response code.
   12162      *
   12163      * @return default verification response code
   12164      */
   12165     private int getDefaultVerificationResponse() {
   12166         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
   12167                 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
   12168                 DEFAULT_VERIFICATION_RESPONSE);
   12169     }
   12170 
   12171     /**
   12172      * Check whether or not package verification has been enabled.
   12173      *
   12174      * @return true if verification should be performed
   12175      */
   12176     private boolean isVerificationEnabled(int userId, int installFlags) {
   12177         if (!DEFAULT_VERIFY_ENABLE) {
   12178             return false;
   12179         }
   12180         // Ephemeral apps don't get the full verification treatment
   12181         if ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) {
   12182             if (DEBUG_EPHEMERAL) {
   12183                 Slog.d(TAG, "INSTALL_EPHEMERAL so skipping verification");
   12184             }
   12185             return false;
   12186         }
   12187 
   12188         boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
   12189 
   12190         // Check if installing from ADB
   12191         if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
   12192             // Do not run verification in a test harness environment
   12193             if (ActivityManager.isRunningInTestHarness()) {
   12194                 return false;
   12195             }
   12196             if (ensureVerifyAppsEnabled) {
   12197                 return true;
   12198             }
   12199             // Check if the developer does not want package verification for ADB installs
   12200             if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
   12201                     android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
   12202                 return false;
   12203             }
   12204         }
   12205 
   12206         if (ensureVerifyAppsEnabled) {
   12207             return true;
   12208         }
   12209 
   12210         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
   12211                 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
   12212     }
   12213 
   12214     @Override
   12215     public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
   12216             throws RemoteException {
   12217         mContext.enforceCallingOrSelfPermission(
   12218                 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
   12219                 "Only intentfilter verification agents can verify applications");
   12220 
   12221         final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
   12222         final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
   12223                 Binder.getCallingUid(), verificationCode, failedDomains);
   12224         msg.arg1 = id;
   12225         msg.obj = response;
   12226         mHandler.sendMessage(msg);
   12227     }
   12228 
   12229     @Override
   12230     public int getIntentVerificationStatus(String packageName, int userId) {
   12231         synchronized (mPackages) {
   12232             return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
   12233         }
   12234     }
   12235 
   12236     @Override
   12237     public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
   12238         mContext.enforceCallingOrSelfPermission(
   12239                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
   12240 
   12241         boolean result = false;
   12242         synchronized (mPackages) {
   12243             result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
   12244         }
   12245         if (result) {
   12246             scheduleWritePackageRestrictionsLocked(userId);
   12247         }
   12248         return result;
   12249     }
   12250 
   12251     @Override
   12252     public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
   12253             String packageName) {
   12254         synchronized (mPackages) {
   12255             return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
   12256         }
   12257     }
   12258 
   12259     @Override
   12260     public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
   12261         if (TextUtils.isEmpty(packageName)) {
   12262             return ParceledListSlice.emptyList();
   12263         }
   12264         synchronized (mPackages) {
   12265             PackageParser.Package pkg = mPackages.get(packageName);
   12266             if (pkg == null || pkg.activities == null) {
   12267                 return ParceledListSlice.emptyList();
   12268             }
   12269             final int count = pkg.activities.size();
   12270             ArrayList<IntentFilter> result = new ArrayList<>();
   12271             for (int n=0; n<count; n++) {
   12272                 PackageParser.Activity activity = pkg.activities.get(n);
   12273                 if (activity.intents != null && activity.intents.size() > 0) {
   12274                     result.addAll(activity.intents);
   12275                 }
   12276             }
   12277             return new ParceledListSlice<>(result);
   12278         }
   12279     }
   12280 
   12281     @Override
   12282     public boolean setDefaultBrowserPackageName(String packageName, int userId) {
   12283         mContext.enforceCallingOrSelfPermission(
   12284                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
   12285 
   12286         synchronized (mPackages) {
   12287             boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
   12288             if (packageName != null) {
   12289                 result |= updateIntentVerificationStatus(packageName,
   12290                         PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS,
   12291                         userId);
   12292                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
   12293                         packageName, userId);
   12294             }
   12295             return result;
   12296         }
   12297     }
   12298 
   12299     @Override
   12300     public String getDefaultBrowserPackageName(int userId) {
   12301         synchronized (mPackages) {
   12302             return mSettings.getDefaultBrowserPackageNameLPw(userId);
   12303         }
   12304     }
   12305 
   12306     /**
   12307      * Get the "allow unknown sources" setting.
   12308      *
   12309      * @return the current "allow unknown sources" setting
   12310      */
   12311     private int getUnknownSourcesSettings() {
   12312         return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
   12313                 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
   12314                 -1);
   12315     }
   12316 
   12317     @Override
   12318     public void setInstallerPackageName(String targetPackage, String installerPackageName) {
   12319         final int uid = Binder.getCallingUid();
   12320         // writer
   12321         synchronized (mPackages) {
   12322             PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
   12323             if (targetPackageSetting == null) {
   12324                 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
   12325             }
   12326 
   12327             PackageSetting installerPackageSetting;
   12328             if (installerPackageName != null) {
   12329                 installerPackageSetting = mSettings.mPackages.get(installerPackageName);
   12330                 if (installerPackageSetting == null) {
   12331                     throw new IllegalArgumentException("Unknown installer package: "
   12332                             + installerPackageName);
   12333                 }
   12334             } else {
   12335                 installerPackageSetting = null;
   12336             }
   12337 
   12338             Signature[] callerSignature;
   12339             Object obj = mSettings.getUserIdLPr(uid);
   12340             if (obj != null) {
   12341                 if (obj instanceof SharedUserSetting) {
   12342                     callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
   12343                 } else if (obj instanceof PackageSetting) {
   12344                     callerSignature = ((PackageSetting)obj).signatures.mSignatures;
   12345                 } else {
   12346                     throw new SecurityException("Bad object " + obj + " for uid " + uid);
   12347                 }
   12348             } else {
   12349                 throw new SecurityException("Unknown calling UID: " + uid);
   12350             }
   12351 
   12352             // Verify: can't set installerPackageName to a package that is
   12353             // not signed with the same cert as the caller.
   12354             if (installerPackageSetting != null) {
   12355                 if (compareSignatures(callerSignature,
   12356                         installerPackageSetting.signatures.mSignatures)
   12357                         != PackageManager.SIGNATURE_MATCH) {
   12358                     throw new SecurityException(
   12359                             "Caller does not have same cert as new installer package "
   12360                             + installerPackageName);
   12361                 }
   12362             }
   12363 
   12364             // Verify: if target already has an installer package, it must
   12365             // be signed with the same cert as the caller.
   12366             if (targetPackageSetting.installerPackageName != null) {
   12367                 PackageSetting setting = mSettings.mPackages.get(
   12368                         targetPackageSetting.installerPackageName);
   12369                 // If the currently set package isn't valid, then it's always
   12370                 // okay to change it.
   12371                 if (setting != null) {
   12372                     if (compareSignatures(callerSignature,
   12373                             setting.signatures.mSignatures)
   12374                             != PackageManager.SIGNATURE_MATCH) {
   12375                         throw new SecurityException(
   12376                                 "Caller does not have same cert as old installer package "
   12377                                 + targetPackageSetting.installerPackageName);
   12378                     }
   12379                 }
   12380             }
   12381 
   12382             // Okay!
   12383             targetPackageSetting.installerPackageName = installerPackageName;
   12384             if (installerPackageName != null) {
   12385                 mSettings.mInstallerPackages.add(installerPackageName);
   12386             }
   12387             scheduleWriteSettingsLocked();
   12388         }
   12389     }
   12390 
   12391     private void processPendingInstall(final InstallArgs args, final int currentStatus) {
   12392         // Queue up an async operation since the package installation may take a little while.
   12393         mHandler.post(new Runnable() {
   12394             public void run() {
   12395                 mHandler.removeCallbacks(this);
   12396                  // Result object to be returned
   12397                 PackageInstalledInfo res = new PackageInstalledInfo();
   12398                 res.setReturnCode(currentStatus);
   12399                 res.uid = -1;
   12400                 res.pkg = null;
   12401                 res.removedInfo = null;
   12402                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
   12403                     args.doPreInstall(res.returnCode);
   12404                     synchronized (mInstallLock) {
   12405                         installPackageTracedLI(args, res);
   12406                     }
   12407                     args.doPostInstall(res.returnCode, res.uid);
   12408                 }
   12409 
   12410                 // A restore should be performed at this point if (a) the install
   12411                 // succeeded, (b) the operation is not an update, and (c) the new
   12412                 // package has not opted out of backup participation.
   12413                 final boolean update = res.removedInfo != null
   12414                         && res.removedInfo.removedPackage != null;
   12415                 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
   12416                 boolean doRestore = !update
   12417                         && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
   12418 
   12419                 // Set up the post-install work request bookkeeping.  This will be used
   12420                 // and cleaned up by the post-install event handling regardless of whether
   12421                 // there's a restore pass performed.  Token values are >= 1.
   12422                 int token;
   12423                 if (mNextInstallToken < 0) mNextInstallToken = 1;
   12424                 token = mNextInstallToken++;
   12425 
   12426                 PostInstallData data = new PostInstallData(args, res);
   12427                 mRunningInstalls.put(token, data);
   12428                 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
   12429 
   12430                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
   12431                     // Pass responsibility to the Backup Manager.  It will perform a
   12432                     // restore if appropriate, then pass responsibility back to the
   12433                     // Package Manager to run the post-install observer callbacks
   12434                     // and broadcasts.
   12435                     IBackupManager bm = IBackupManager.Stub.asInterface(
   12436                             ServiceManager.getService(Context.BACKUP_SERVICE));
   12437                     if (bm != null) {
   12438                         if (DEBUG_INSTALL) Log.v(TAG, "token " + token
   12439                                 + " to BM for possible restore");
   12440                         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
   12441                         try {
   12442                             // TODO: http://b/22388012
   12443                             if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
   12444                                 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
   12445                             } else {
   12446                                 doRestore = false;
   12447                             }
   12448                         } catch (RemoteException e) {
   12449                             // can't happen; the backup manager is local
   12450                         } catch (Exception e) {
   12451                             Slog.e(TAG, "Exception trying to enqueue restore", e);
   12452                             doRestore = false;
   12453                         }
   12454                     } else {
   12455                         Slog.e(TAG, "Backup Manager not found!");
   12456                         doRestore = false;
   12457                     }
   12458                 }
   12459 
   12460                 if (!doRestore) {
   12461                     // No restore possible, or the Backup Manager was mysteriously not
   12462                     // available -- just fire the post-install work request directly.
   12463                     if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
   12464 
   12465                     Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
   12466 
   12467                     Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
   12468                     mHandler.sendMessage(msg);
   12469                 }
   12470             }
   12471         });
   12472     }
   12473 
   12474     /**
   12475      * Callback from PackageSettings whenever an app is first transitioned out of the
   12476      * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
   12477      * the app was "launched" for a restoreAtInstall operation.  Therefore we check
   12478      * here whether the app is the target of an ongoing install, and only send the
   12479      * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
   12480      * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
   12481      * handling.
   12482      */
   12483     void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) {
   12484         // Serialize this with the rest of the install-process message chain.  In the
   12485         // restore-at-install case, this Runnable will necessarily run before the
   12486         // POST_INSTALL message is processed, so the contents of mRunningInstalls
   12487         // are coherent.  In the non-restore case, the app has already completed install
   12488         // and been launched through some other means, so it is not in a problematic
   12489         // state for observers to see the FIRST_LAUNCH signal.
   12490         mHandler.post(new Runnable() {
   12491             @Override
   12492             public void run() {
   12493                 for (int i = 0; i < mRunningInstalls.size(); i++) {
   12494                     final PostInstallData data = mRunningInstalls.valueAt(i);
   12495                     if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
   12496                         continue;
   12497                     }
   12498                     if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) {
   12499                         // right package; but is it for the right user?
   12500                         for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
   12501                             if (userId == data.res.newUsers[uIndex]) {
   12502                                 if (DEBUG_BACKUP) {
   12503                                     Slog.i(TAG, "Package " + pkgName
   12504                                             + " being restored so deferring FIRST_LAUNCH");
   12505                                 }
   12506                                 return;
   12507                             }
   12508                         }
   12509                     }
   12510                 }
   12511                 // didn't find it, so not being restored
   12512                 if (DEBUG_BACKUP) {
   12513                     Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH");
   12514                 }
   12515                 sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId});
   12516             }
   12517         });
   12518     }
   12519 
   12520     private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) {
   12521         sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
   12522                 installerPkg, null, userIds);
   12523     }
   12524 
   12525     private abstract class HandlerParams {
   12526         private static final int MAX_RETRIES = 4;
   12527 
   12528         /**
   12529          * Number of times startCopy() has been attempted and had a non-fatal
   12530          * error.
   12531          */
   12532         private int mRetries = 0;
   12533 
   12534         /** User handle for the user requesting the information or installation. */
   12535         private final UserHandle mUser;
   12536         String traceMethod;
   12537         int traceCookie;
   12538 
   12539         HandlerParams(UserHandle user) {
   12540             mUser = user;
   12541         }
   12542 
   12543         UserHandle getUser() {
   12544             return mUser;
   12545         }
   12546 
   12547         HandlerParams setTraceMethod(String traceMethod) {
   12548             this.traceMethod = traceMethod;
   12549             return this;
   12550         }
   12551 
   12552         HandlerParams setTraceCookie(int traceCookie) {
   12553             this.traceCookie = traceCookie;
   12554             return this;
   12555         }
   12556 
   12557         final boolean startCopy() {
   12558             boolean res;
   12559             try {
   12560                 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
   12561 
   12562                 if (++mRetries > MAX_RETRIES) {
   12563                     Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
   12564                     mHandler.sendEmptyMessage(MCS_GIVE_UP);
   12565                     handleServiceError();
   12566                     return false;
   12567                 } else {
   12568                     handleStartCopy();
   12569                     res = true;
   12570                 }
   12571             } catch (RemoteException e) {
   12572                 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
   12573                 mHandler.sendEmptyMessage(MCS_RECONNECT);
   12574                 res = false;
   12575             }
   12576             handleReturnCode();
   12577             return res;
   12578         }
   12579 
   12580         final void serviceError() {
   12581             if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
   12582             handleServiceError();
   12583             handleReturnCode();
   12584         }
   12585 
   12586         abstract void handleStartCopy() throws RemoteException;
   12587         abstract void handleServiceError();
   12588         abstract void handleReturnCode();
   12589     }
   12590 
   12591     class MeasureParams extends HandlerParams {
   12592         private final PackageStats mStats;
   12593         private boolean mSuccess;
   12594 
   12595         private final IPackageStatsObserver mObserver;
   12596 
   12597         public MeasureParams(PackageStats stats, IPackageStatsObserver observer) {
   12598             super(new UserHandle(stats.userHandle));
   12599             mObserver = observer;
   12600             mStats = stats;
   12601         }
   12602 
   12603         @Override
   12604         public String toString() {
   12605             return "MeasureParams{"
   12606                 + Integer.toHexString(System.identityHashCode(this))
   12607                 + " " + mStats.packageName + "}";
   12608         }
   12609 
   12610         @Override
   12611         void handleStartCopy() throws RemoteException {
   12612             synchronized (mInstallLock) {
   12613                 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats);
   12614             }
   12615 
   12616             if (mSuccess) {
   12617                 boolean mounted = false;
   12618                 try {
   12619                     final String status = Environment.getExternalStorageState();
   12620                     mounted = (Environment.MEDIA_MOUNTED.equals(status)
   12621                             || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status));
   12622                 } catch (Exception e) {
   12623                 }
   12624 
   12625                 if (mounted) {
   12626                     final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle);
   12627 
   12628                     mStats.externalCacheSize = calculateDirectorySize(mContainerService,
   12629                             userEnv.buildExternalStorageAppCacheDirs(mStats.packageName));
   12630 
   12631                     mStats.externalDataSize = calculateDirectorySize(mContainerService,
   12632                             userEnv.buildExternalStorageAppDataDirs(mStats.packageName));
   12633 
   12634                     // Always subtract cache size, since it's a subdirectory
   12635                     mStats.externalDataSize -= mStats.externalCacheSize;
   12636 
   12637                     mStats.externalMediaSize = calculateDirectorySize(mContainerService,
   12638                             userEnv.buildExternalStorageAppMediaDirs(mStats.packageName));
   12639 
   12640                     mStats.externalObbSize = calculateDirectorySize(mContainerService,
   12641                             userEnv.buildExternalStorageAppObbDirs(mStats.packageName));
   12642                 }
   12643             }
   12644         }
   12645 
   12646         @Override
   12647         void handleReturnCode() {
   12648             if (mObserver != null) {
   12649                 try {
   12650                     mObserver.onGetStatsCompleted(mStats, mSuccess);
   12651                 } catch (RemoteException e) {
   12652                     Slog.i(TAG, "Observer no longer exists.");
   12653                 }
   12654             }
   12655         }
   12656 
   12657         @Override
   12658         void handleServiceError() {
   12659             Slog.e(TAG, "Could not measure application " + mStats.packageName
   12660                             + " external storage");
   12661         }
   12662     }
   12663 
   12664     private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths)
   12665             throws RemoteException {
   12666         long result = 0;
   12667         for (File path : paths) {
   12668             result += mcs.calculateDirectorySize(path.getAbsolutePath());
   12669         }
   12670         return result;
   12671     }
   12672 
   12673     private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
   12674         for (File path : paths) {
   12675             try {
   12676                 mcs.clearDirectory(path.getAbsolutePath());
   12677             } catch (RemoteException e) {
   12678             }
   12679         }
   12680     }
   12681 
   12682     static class OriginInfo {
   12683         /**
   12684          * Location where install is coming from, before it has been
   12685          * copied/renamed into place. This could be a single monolithic APK
   12686          * file, or a cluster directory. This location may be untrusted.
   12687          */
   12688         final File file;
   12689         final String cid;
   12690 
   12691         /**
   12692          * Flag indicating that {@link #file} or {@link #cid} has already been
   12693          * staged, meaning downstream users don't need to defensively copy the
   12694          * contents.
   12695          */
   12696         final boolean staged;
   12697 
   12698         /**
   12699          * Flag indicating that {@link #file} or {@link #cid} is an already
   12700          * installed app that is being moved.
   12701          */
   12702         final boolean existing;
   12703 
   12704         final String resolvedPath;
   12705         final File resolvedFile;
   12706 
   12707         static OriginInfo fromNothing() {
   12708             return new OriginInfo(null, null, false, false);
   12709         }
   12710 
   12711         static OriginInfo fromUntrustedFile(File file) {
   12712             return new OriginInfo(file, null, false, false);
   12713         }
   12714 
   12715         static OriginInfo fromExistingFile(File file) {
   12716             return new OriginInfo(file, null, false, true);
   12717         }
   12718 
   12719         static OriginInfo fromStagedFile(File file) {
   12720             return new OriginInfo(file, null, true, false);
   12721         }
   12722 
   12723         static OriginInfo fromStagedContainer(String cid) {
   12724             return new OriginInfo(null, cid, true, false);
   12725         }
   12726 
   12727         private OriginInfo(File file, String cid, boolean staged, boolean existing) {
   12728             this.file = file;
   12729             this.cid = cid;
   12730             this.staged = staged;
   12731             this.existing = existing;
   12732 
   12733             if (cid != null) {
   12734                 resolvedPath = PackageHelper.getSdDir(cid);
   12735                 resolvedFile = new File(resolvedPath);
   12736             } else if (file != null) {
   12737                 resolvedPath = file.getAbsolutePath();
   12738                 resolvedFile = file;
   12739             } else {
   12740                 resolvedPath = null;
   12741                 resolvedFile = null;
   12742             }
   12743         }
   12744     }
   12745 
   12746     static class MoveInfo {
   12747         final int moveId;
   12748         final String fromUuid;
   12749         final String toUuid;
   12750         final String packageName;
   12751         final String dataAppName;
   12752         final int appId;
   12753         final String seinfo;
   12754         final int targetSdkVersion;
   12755 
   12756         public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
   12757                 String dataAppName, int appId, String seinfo, int targetSdkVersion) {
   12758             this.moveId = moveId;
   12759             this.fromUuid = fromUuid;
   12760             this.toUuid = toUuid;
   12761             this.packageName = packageName;
   12762             this.dataAppName = dataAppName;
   12763             this.appId = appId;
   12764             this.seinfo = seinfo;
   12765             this.targetSdkVersion = targetSdkVersion;
   12766         }
   12767     }
   12768 
   12769     static class VerificationInfo {
   12770         /** A constant used to indicate that a uid value is not present. */
   12771         public static final int NO_UID = -1;
   12772 
   12773         /** URI referencing where the package was downloaded from. */
   12774         final Uri originatingUri;
   12775 
   12776         /** HTTP referrer URI associated with the originatingURI. */
   12777         final Uri referrer;
   12778 
   12779         /** UID of the application that the install request originated from. */
   12780         final int originatingUid;
   12781 
   12782         /** UID of application requesting the install */
   12783         final int installerUid;
   12784 
   12785         VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
   12786             this.originatingUri = originatingUri;
   12787             this.referrer = referrer;
   12788             this.originatingUid = originatingUid;
   12789             this.installerUid = installerUid;
   12790         }
   12791     }
   12792 
   12793     class InstallParams extends HandlerParams {
   12794         final OriginInfo origin;
   12795         final MoveInfo move;
   12796         final IPackageInstallObserver2 observer;
   12797         int installFlags;
   12798         final String installerPackageName;
   12799         final String volumeUuid;
   12800         private InstallArgs mArgs;
   12801         private int mRet;
   12802         final String packageAbiOverride;
   12803         final String[] grantedRuntimePermissions;
   12804         final VerificationInfo verificationInfo;
   12805         final Certificate[][] certificates;
   12806 
   12807         InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
   12808                 int installFlags, String installerPackageName, String volumeUuid,
   12809                 VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
   12810                 String[] grantedPermissions, Certificate[][] certificates) {
   12811             super(user);
   12812             this.origin = origin;
   12813             this.move = move;
   12814             this.observer = observer;
   12815             this.installFlags = installFlags;
   12816             this.installerPackageName = installerPackageName;
   12817             this.volumeUuid = volumeUuid;
   12818             this.verificationInfo = verificationInfo;
   12819             this.packageAbiOverride = packageAbiOverride;
   12820             this.grantedRuntimePermissions = grantedPermissions;
   12821             this.certificates = certificates;
   12822         }
   12823 
   12824         @Override
   12825         public String toString() {
   12826             return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
   12827                     + " file=" + origin.file + " cid=" + origin.cid + "}";
   12828         }
   12829 
   12830         private int installLocationPolicy(PackageInfoLite pkgLite) {
   12831             String packageName = pkgLite.packageName;
   12832             int installLocation = pkgLite.installLocation;
   12833             boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
   12834             // reader
   12835             synchronized (mPackages) {
   12836                 // Currently installed package which the new package is attempting to replace or
   12837                 // null if no such package is installed.
   12838                 PackageParser.Package installedPkg = mPackages.get(packageName);
   12839                 // Package which currently owns the data which the new package will own if installed.
   12840                 // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
   12841                 // will be null whereas dataOwnerPkg will contain information about the package
   12842                 // which was uninstalled while keeping its data.
   12843                 PackageParser.Package dataOwnerPkg = installedPkg;
   12844                 if (dataOwnerPkg  == null) {
   12845                     PackageSetting ps = mSettings.mPackages.get(packageName);
   12846                     if (ps != null) {
   12847                         dataOwnerPkg = ps.pkg;
   12848                     }
   12849                 }
   12850 
   12851                 if (dataOwnerPkg != null) {
   12852                     // If installed, the package will get access to data left on the device by its
   12853                     // predecessor. As a security measure, this is permited only if this is not a
   12854                     // version downgrade or if the predecessor package is marked as debuggable and
   12855                     // a downgrade is explicitly requested.
   12856                     //
   12857                     // On debuggable platform builds, downgrades are permitted even for
   12858                     // non-debuggable packages to make testing easier. Debuggable platform builds do
   12859                     // not offer security guarantees and thus it's OK to disable some security
   12860                     // mechanisms to make debugging/testing easier on those builds. However, even on
   12861                     // debuggable builds downgrades of packages are permitted only if requested via
   12862                     // installFlags. This is because we aim to keep the behavior of debuggable
   12863                     // platform builds as close as possible to the behavior of non-debuggable
   12864                     // platform builds.
   12865                     final boolean downgradeRequested =
   12866                             (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
   12867                     final boolean packageDebuggable =
   12868                                 (dataOwnerPkg.applicationInfo.flags
   12869                                         & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
   12870                     final boolean downgradePermitted =
   12871                             (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
   12872                     if (!downgradePermitted) {
   12873                         try {
   12874                             checkDowngrade(dataOwnerPkg, pkgLite);
   12875                         } catch (PackageManagerException e) {
   12876                             Slog.w(TAG, "Downgrade detected: " + e.getMessage());
   12877                             return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
   12878                         }
   12879                     }
   12880                 }
   12881 
   12882                 if (installedPkg != null) {
   12883                     if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
   12884                         // Check for updated system application.
   12885                         if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
   12886                             if (onSd) {
   12887                                 Slog.w(TAG, "Cannot install update to system app on sdcard");
   12888                                 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
   12889                             }
   12890                             return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
   12891                         } else {
   12892                             if (onSd) {
   12893                                 // Install flag overrides everything.
   12894                                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
   12895                             }
   12896                             // If current upgrade specifies particular preference
   12897                             if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
   12898                                 // Application explicitly specified internal.
   12899                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
   12900                             } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
   12901                                 // App explictly prefers external. Let policy decide
   12902                             } else {
   12903                                 // Prefer previous location
   12904                                 if (isExternal(installedPkg)) {
   12905                                     return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
   12906                                 }
   12907                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
   12908                             }
   12909                         }
   12910                     } else {
   12911                         // Invalid install. Return error code
   12912                         return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
   12913                     }
   12914                 }
   12915             }
   12916             // All the special cases have been taken care of.
   12917             // Return result based on recommended install location.
   12918             if (onSd) {
   12919                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
   12920             }
   12921             return pkgLite.recommendedInstallLocation;
   12922         }
   12923 
   12924         /*
   12925          * Invoke remote method to get package information and install
   12926          * location values. Override install location based on default
   12927          * policy if needed and then create install arguments based
   12928          * on the install location.
   12929          */
   12930         public void handleStartCopy() throws RemoteException {
   12931             int ret = PackageManager.INSTALL_SUCCEEDED;
   12932 
   12933             // If we're already staged, we've firmly committed to an install location
   12934             if (origin.staged) {
   12935                 if (origin.file != null) {
   12936                     installFlags |= PackageManager.INSTALL_INTERNAL;
   12937                     installFlags &= ~PackageManager.INSTALL_EXTERNAL;
   12938                 } else if (origin.cid != null) {
   12939                     installFlags |= PackageManager.INSTALL_EXTERNAL;
   12940                     installFlags &= ~PackageManager.INSTALL_INTERNAL;
   12941                 } else {
   12942                     throw new IllegalStateException("Invalid stage location");
   12943                 }
   12944             }
   12945 
   12946             final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
   12947             final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
   12948             final boolean ephemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
   12949             PackageInfoLite pkgLite = null;
   12950 
   12951             if (onInt && onSd) {
   12952                 // Check if both bits are set.
   12953                 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
   12954                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
   12955             } else if (onSd && ephemeral) {
   12956                 Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
   12957                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
   12958             } else {
   12959                 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
   12960                         packageAbiOverride);
   12961 
   12962                 if (DEBUG_EPHEMERAL && ephemeral) {
   12963                     Slog.v(TAG, "pkgLite for install: " + pkgLite);
   12964                 }
   12965 
   12966                 /*
   12967                  * If we have too little free space, try to free cache
   12968                  * before giving up.
   12969                  */
   12970                 if (!origin.staged && pkgLite.recommendedInstallLocation
   12971                         == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
   12972                     // TODO: focus freeing disk space on the target device
   12973                     final StorageManager storage = StorageManager.from(mContext);
   12974                     final long lowThreshold = storage.getStorageLowBytes(
   12975                             Environment.getDataDirectory());
   12976 
   12977                     final long sizeBytes = mContainerService.calculateInstalledSize(
   12978                             origin.resolvedPath, isForwardLocked(), packageAbiOverride);
   12979 
   12980                     try {
   12981                         mInstaller.freeCache(null, sizeBytes + lowThreshold);
   12982                         pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
   12983                                 installFlags, packageAbiOverride);
   12984                     } catch (InstallerException e) {
   12985                         Slog.w(TAG, "Failed to free cache", e);
   12986                     }
   12987 
   12988                     /*
   12989                      * The cache free must have deleted the file we
   12990                      * downloaded to install.
   12991                      *
   12992                      * TODO: fix the "freeCache" call to not delete
   12993                      *       the file we care about.
   12994                      */
   12995                     if (pkgLite.recommendedInstallLocation
   12996                             == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
   12997                         pkgLite.recommendedInstallLocation
   12998                             = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
   12999                     }
   13000                 }
   13001             }
   13002 
   13003             if (ret == PackageManager.INSTALL_SUCCEEDED) {
   13004                 int loc = pkgLite.recommendedInstallLocation;
   13005                 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
   13006                     ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
   13007                 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
   13008                     ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
   13009                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
   13010                     ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   13011                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
   13012                     ret = PackageManager.INSTALL_FAILED_INVALID_APK;
   13013                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
   13014                     ret = PackageManager.INSTALL_FAILED_INVALID_URI;
   13015                 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
   13016                     ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
   13017                 } else {
   13018                     // Override with defaults if needed.
   13019                     loc = installLocationPolicy(pkgLite);
   13020                     if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
   13021                         ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
   13022                     } else if (!onSd && !onInt) {
   13023                         // Override install location with flags
   13024                         if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
   13025                             // Set the flag to install on external media.
   13026                             installFlags |= PackageManager.INSTALL_EXTERNAL;
   13027                             installFlags &= ~PackageManager.INSTALL_INTERNAL;
   13028                         } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
   13029                             if (DEBUG_EPHEMERAL) {
   13030                                 Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
   13031                             }
   13032                             installFlags |= PackageManager.INSTALL_EPHEMERAL;
   13033                             installFlags &= ~(PackageManager.INSTALL_EXTERNAL
   13034                                     |PackageManager.INSTALL_INTERNAL);
   13035                         } else {
   13036                             // Make sure the flag for installing on external
   13037                             // media is unset
   13038                             installFlags |= PackageManager.INSTALL_INTERNAL;
   13039                             installFlags &= ~PackageManager.INSTALL_EXTERNAL;
   13040                         }
   13041                     }
   13042                 }
   13043             }
   13044 
   13045             final InstallArgs args = createInstallArgs(this);
   13046             mArgs = args;
   13047 
   13048             if (ret == PackageManager.INSTALL_SUCCEEDED) {
   13049                 // TODO: http://b/22976637
   13050                 // Apps installed for "all" users use the device owner to verify the app
   13051                 UserHandle verifierUser = getUser();
   13052                 if (verifierUser == UserHandle.ALL) {
   13053                     verifierUser = UserHandle.SYSTEM;
   13054                 }
   13055 
   13056                 /*
   13057                  * Determine if we have any installed package verifiers. If we
   13058                  * do, then we'll defer to them to verify the packages.
   13059                  */
   13060                 final int requiredUid = mRequiredVerifierPackage == null ? -1
   13061                         : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
   13062                                 verifierUser.getIdentifier());
   13063                 if (!origin.existing && requiredUid != -1
   13064                         && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) {
   13065                     final Intent verification = new Intent(
   13066                             Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
   13067                     verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   13068                     verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
   13069                             PACKAGE_MIME_TYPE);
   13070                     verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
   13071 
   13072                     // Query all live verifiers based on current user state
   13073                     final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
   13074                             PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier());
   13075 
   13076                     if (DEBUG_VERIFY) {
   13077                         Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
   13078                                 + verification.toString() + " with " + pkgLite.verifiers.length
   13079                                 + " optional verifiers");
   13080                     }
   13081 
   13082                     final int verificationId = mPendingVerificationToken++;
   13083 
   13084                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
   13085 
   13086                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
   13087                             installerPackageName);
   13088 
   13089                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
   13090                             installFlags);
   13091 
   13092                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
   13093                             pkgLite.packageName);
   13094 
   13095                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
   13096                             pkgLite.versionCode);
   13097 
   13098                     if (verificationInfo != null) {
   13099                         if (verificationInfo.originatingUri != null) {
   13100                             verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
   13101                                     verificationInfo.originatingUri);
   13102                         }
   13103                         if (verificationInfo.referrer != null) {
   13104                             verification.putExtra(Intent.EXTRA_REFERRER,
   13105                                     verificationInfo.referrer);
   13106                         }
   13107                         if (verificationInfo.originatingUid >= 0) {
   13108                             verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
   13109                                     verificationInfo.originatingUid);
   13110                         }
   13111                         if (verificationInfo.installerUid >= 0) {
   13112                             verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
   13113                                     verificationInfo.installerUid);
   13114                         }
   13115                     }
   13116 
   13117                     final PackageVerificationState verificationState = new PackageVerificationState(
   13118                             requiredUid, args);
   13119 
   13120                     mPendingVerification.append(verificationId, verificationState);
   13121 
   13122                     final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
   13123                             receivers, verificationState);
   13124 
   13125                     /*
   13126                      * If any sufficient verifiers were listed in the package
   13127                      * manifest, attempt to ask them.
   13128                      */
   13129                     if (sufficientVerifiers != null) {
   13130                         final int N = sufficientVerifiers.size();
   13131                         if (N == 0) {
   13132                             Slog.i(TAG, "Additional verifiers required, but none installed.");
   13133                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
   13134                         } else {
   13135                             for (int i = 0; i < N; i++) {
   13136                                 final ComponentName verifierComponent = sufficientVerifiers.get(i);
   13137 
   13138                                 final Intent sufficientIntent = new Intent(verification);
   13139                                 sufficientIntent.setComponent(verifierComponent);
   13140                                 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
   13141                             }
   13142                         }
   13143                     }
   13144 
   13145                     final ComponentName requiredVerifierComponent = matchComponentForVerifier(
   13146                             mRequiredVerifierPackage, receivers);
   13147                     if (ret == PackageManager.INSTALL_SUCCEEDED
   13148                             && mRequiredVerifierPackage != null) {
   13149                         Trace.asyncTraceBegin(
   13150                                 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
   13151                         /*
   13152                          * Send the intent to the required verification agent,
   13153                          * but only start the verification timeout after the
   13154                          * target BroadcastReceivers have run.
   13155                          */
   13156                         verification.setComponent(requiredVerifierComponent);
   13157                         mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
   13158                                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
   13159                                 new BroadcastReceiver() {
   13160                                     @Override
   13161                                     public void onReceive(Context context, Intent intent) {
   13162                                         final Message msg = mHandler
   13163                                                 .obtainMessage(CHECK_PENDING_VERIFICATION);
   13164                                         msg.arg1 = verificationId;
   13165                                         mHandler.sendMessageDelayed(msg, getVerificationTimeout());
   13166                                     }
   13167                                 }, null, 0, null, null);
   13168 
   13169                         /*
   13170                          * We don't want the copy to proceed until verification
   13171                          * succeeds, so null out this field.
   13172                          */
   13173                         mArgs = null;
   13174                     }
   13175                 } else {
   13176                     /*
   13177                      * No package verification is enabled, so immediately start
   13178                      * the remote call to initiate copy using temporary file.
   13179                      */
   13180                     ret = args.copyApk(mContainerService, true);
   13181                 }
   13182             }
   13183 
   13184             mRet = ret;
   13185         }
   13186 
   13187         @Override
   13188         void handleReturnCode() {
   13189             // If mArgs is null, then MCS couldn't be reached. When it
   13190             // reconnects, it will try again to install. At that point, this
   13191             // will succeed.
   13192             if (mArgs != null) {
   13193                 processPendingInstall(mArgs, mRet);
   13194             }
   13195         }
   13196 
   13197         @Override
   13198         void handleServiceError() {
   13199             mArgs = createInstallArgs(this);
   13200             mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
   13201         }
   13202 
   13203         public boolean isForwardLocked() {
   13204             return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
   13205         }
   13206     }
   13207 
   13208     /**
   13209      * Used during creation of InstallArgs
   13210      *
   13211      * @param installFlags package installation flags
   13212      * @return true if should be installed on external storage
   13213      */
   13214     private static boolean installOnExternalAsec(int installFlags) {
   13215         if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
   13216             return false;
   13217         }
   13218         if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
   13219             return true;
   13220         }
   13221         return false;
   13222     }
   13223 
   13224     /**
   13225      * Used during creation of InstallArgs
   13226      *
   13227      * @param installFlags package installation flags
   13228      * @return true if should be installed as forward locked
   13229      */
   13230     private static boolean installForwardLocked(int installFlags) {
   13231         return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
   13232     }
   13233 
   13234     private InstallArgs createInstallArgs(InstallParams params) {
   13235         if (params.move != null) {
   13236             return new MoveInstallArgs(params);
   13237         } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
   13238             return new AsecInstallArgs(params);
   13239         } else {
   13240             return new FileInstallArgs(params);
   13241         }
   13242     }
   13243 
   13244     /**
   13245      * Create args that describe an existing installed package. Typically used
   13246      * when cleaning up old installs, or used as a move source.
   13247      */
   13248     private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
   13249             String resourcePath, String[] instructionSets) {
   13250         final boolean isInAsec;
   13251         if (installOnExternalAsec(installFlags)) {
   13252             /* Apps on SD card are always in ASEC containers. */
   13253             isInAsec = true;
   13254         } else if (installForwardLocked(installFlags)
   13255                 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
   13256             /*
   13257              * Forward-locked apps are only in ASEC containers if they're the
   13258              * new style
   13259              */
   13260             isInAsec = true;
   13261         } else {
   13262             isInAsec = false;
   13263         }
   13264 
   13265         if (isInAsec) {
   13266             return new AsecInstallArgs(codePath, instructionSets,
   13267                     installOnExternalAsec(installFlags), installForwardLocked(installFlags));
   13268         } else {
   13269             return new FileInstallArgs(codePath, resourcePath, instructionSets);
   13270         }
   13271     }
   13272 
   13273     static abstract class InstallArgs {
   13274         /** @see InstallParams#origin */
   13275         final OriginInfo origin;
   13276         /** @see InstallParams#move */
   13277         final MoveInfo move;
   13278 
   13279         final IPackageInstallObserver2 observer;
   13280         // Always refers to PackageManager flags only
   13281         final int installFlags;
   13282         final String installerPackageName;
   13283         final String volumeUuid;
   13284         final UserHandle user;
   13285         final String abiOverride;
   13286         final String[] installGrantPermissions;
   13287         /** If non-null, drop an async trace when the install completes */
   13288         final String traceMethod;
   13289         final int traceCookie;
   13290         final Certificate[][] certificates;
   13291 
   13292         // The list of instruction sets supported by this app. This is currently
   13293         // only used during the rmdex() phase to clean up resources. We can get rid of this
   13294         // if we move dex files under the common app path.
   13295         /* nullable */ String[] instructionSets;
   13296 
   13297         InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
   13298                 int installFlags, String installerPackageName, String volumeUuid,
   13299                 UserHandle user, String[] instructionSets,
   13300                 String abiOverride, String[] installGrantPermissions,
   13301                 String traceMethod, int traceCookie, Certificate[][] certificates) {
   13302             this.origin = origin;
   13303             this.move = move;
   13304             this.installFlags = installFlags;
   13305             this.observer = observer;
   13306             this.installerPackageName = installerPackageName;
   13307             this.volumeUuid = volumeUuid;
   13308             this.user = user;
   13309             this.instructionSets = instructionSets;
   13310             this.abiOverride = abiOverride;
   13311             this.installGrantPermissions = installGrantPermissions;
   13312             this.traceMethod = traceMethod;
   13313             this.traceCookie = traceCookie;
   13314             this.certificates = certificates;
   13315         }
   13316 
   13317         abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
   13318         abstract int doPreInstall(int status);
   13319 
   13320         /**
   13321          * Rename package into final resting place. All paths on the given
   13322          * scanned package should be updated to reflect the rename.
   13323          */
   13324         abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
   13325         abstract int doPostInstall(int status, int uid);
   13326 
   13327         /** @see PackageSettingBase#codePathString */
   13328         abstract String getCodePath();
   13329         /** @see PackageSettingBase#resourcePathString */
   13330         abstract String getResourcePath();
   13331 
   13332         // Need installer lock especially for dex file removal.
   13333         abstract void cleanUpResourcesLI();
   13334         abstract boolean doPostDeleteLI(boolean delete);
   13335 
   13336         /**
   13337          * Called before the source arguments are copied. This is used mostly
   13338          * for MoveParams when it needs to read the source file to put it in the
   13339          * destination.
   13340          */
   13341         int doPreCopy() {
   13342             return PackageManager.INSTALL_SUCCEEDED;
   13343         }
   13344 
   13345         /**
   13346          * Called after the source arguments are copied. This is used mostly for
   13347          * MoveParams when it needs to read the source file to put it in the
   13348          * destination.
   13349          */
   13350         int doPostCopy(int uid) {
   13351             return PackageManager.INSTALL_SUCCEEDED;
   13352         }
   13353 
   13354         protected boolean isFwdLocked() {
   13355             return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
   13356         }
   13357 
   13358         protected boolean isExternalAsec() {
   13359             return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
   13360         }
   13361 
   13362         protected boolean isEphemeral() {
   13363             return (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
   13364         }
   13365 
   13366         UserHandle getUser() {
   13367             return user;
   13368         }
   13369     }
   13370 
   13371     private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
   13372         if (!allCodePaths.isEmpty()) {
   13373             if (instructionSets == null) {
   13374                 throw new IllegalStateException("instructionSet == null");
   13375             }
   13376             String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
   13377             for (String codePath : allCodePaths) {
   13378                 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
   13379                     try {
   13380                         mInstaller.rmdex(codePath, dexCodeInstructionSet);
   13381                     } catch (InstallerException ignored) {
   13382                     }
   13383                 }
   13384             }
   13385         }
   13386     }
   13387 
   13388     /**
   13389      * Logic to handle installation of non-ASEC applications, including copying
   13390      * and renaming logic.
   13391      */
   13392     class FileInstallArgs extends InstallArgs {
   13393         private File codeFile;
   13394         private File resourceFile;
   13395 
   13396         // Example topology:
   13397         // /data/app/com.example/base.apk
   13398         // /data/app/com.example/split_foo.apk
   13399         // /data/app/com.example/lib/arm/libfoo.so
   13400         // /data/app/com.example/lib/arm64/libfoo.so
   13401         // /data/app/com.example/dalvik/arm/base.apk@classes.dex
   13402 
   13403         /** New install */
   13404         FileInstallArgs(InstallParams params) {
   13405             super(params.origin, params.move, params.observer, params.installFlags,
   13406                     params.installerPackageName, params.volumeUuid,
   13407                     params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
   13408                     params.grantedRuntimePermissions,
   13409                     params.traceMethod, params.traceCookie, params.certificates);
   13410             if (isFwdLocked()) {
   13411                 throw new IllegalArgumentException("Forward locking only supported in ASEC");
   13412             }
   13413         }
   13414 
   13415         /** Existing install */
   13416         FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
   13417             super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
   13418                     null, null, null, 0, null /*certificates*/);
   13419             this.codeFile = (codePath != null) ? new File(codePath) : null;
   13420             this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
   13421         }
   13422 
   13423         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
   13424             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
   13425             try {
   13426                 return doCopyApk(imcs, temp);
   13427             } finally {
   13428                 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
   13429             }
   13430         }
   13431 
   13432         private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
   13433             if (origin.staged) {
   13434                 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
   13435                 codeFile = origin.file;
   13436                 resourceFile = origin.file;
   13437                 return PackageManager.INSTALL_SUCCEEDED;
   13438             }
   13439 
   13440             try {
   13441                 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
   13442                 final File tempDir =
   13443                         mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
   13444                 codeFile = tempDir;
   13445                 resourceFile = tempDir;
   13446             } catch (IOException e) {
   13447                 Slog.w(TAG, "Failed to create copy file: " + e);
   13448                 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   13449             }
   13450 
   13451             final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
   13452                 @Override
   13453                 public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
   13454                     if (!FileUtils.isValidExtFilename(name)) {
   13455                         throw new IllegalArgumentException("Invalid filename: " + name);
   13456                     }
   13457                     try {
   13458                         final File file = new File(codeFile, name);
   13459                         final FileDescriptor fd = Os.open(file.getAbsolutePath(),
   13460                                 O_RDWR | O_CREAT, 0644);
   13461                         Os.chmod(file.getAbsolutePath(), 0644);
   13462                         return new ParcelFileDescriptor(fd);
   13463                     } catch (ErrnoException e) {
   13464                         throw new RemoteException("Failed to open: " + e.getMessage());
   13465                     }
   13466                 }
   13467             };
   13468 
   13469             int ret = PackageManager.INSTALL_SUCCEEDED;
   13470             ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
   13471             if (ret != PackageManager.INSTALL_SUCCEEDED) {
   13472                 Slog.e(TAG, "Failed to copy package");
   13473                 return ret;
   13474             }
   13475 
   13476             final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
   13477             NativeLibraryHelper.Handle handle = null;
   13478             try {
   13479                 handle = NativeLibraryHelper.Handle.create(codeFile);
   13480                 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
   13481                         abiOverride);
   13482             } catch (IOException e) {
   13483                 Slog.e(TAG, "Copying native libraries failed", e);
   13484                 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
   13485             } finally {
   13486                 IoUtils.closeQuietly(handle);
   13487             }
   13488 
   13489             return ret;
   13490         }
   13491 
   13492         int doPreInstall(int status) {
   13493             if (status != PackageManager.INSTALL_SUCCEEDED) {
   13494                 cleanUp();
   13495             }
   13496             return status;
   13497         }
   13498 
   13499         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
   13500             if (status != PackageManager.INSTALL_SUCCEEDED) {
   13501                 cleanUp();
   13502                 return false;
   13503             }
   13504 
   13505             final File targetDir = codeFile.getParentFile();
   13506             final File beforeCodeFile = codeFile;
   13507             final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
   13508 
   13509             if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
   13510             try {
   13511                 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
   13512             } catch (ErrnoException e) {
   13513                 Slog.w(TAG, "Failed to rename", e);
   13514                 return false;
   13515             }
   13516 
   13517             if (!SELinux.restoreconRecursive(afterCodeFile)) {
   13518                 Slog.w(TAG, "Failed to restorecon");
   13519                 return false;
   13520             }
   13521 
   13522             // Reflect the rename internally
   13523             codeFile = afterCodeFile;
   13524             resourceFile = afterCodeFile;
   13525 
   13526             // Reflect the rename in scanned details
   13527             pkg.setCodePath(afterCodeFile.getAbsolutePath());
   13528             pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
   13529                     afterCodeFile, pkg.baseCodePath));
   13530             pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
   13531                     afterCodeFile, pkg.splitCodePaths));
   13532 
   13533             // Reflect the rename in app info
   13534             pkg.setApplicationVolumeUuid(pkg.volumeUuid);
   13535             pkg.setApplicationInfoCodePath(pkg.codePath);
   13536             pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
   13537             pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
   13538             pkg.setApplicationInfoResourcePath(pkg.codePath);
   13539             pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
   13540             pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
   13541 
   13542             return true;
   13543         }
   13544 
   13545         int doPostInstall(int status, int uid) {
   13546             if (status != PackageManager.INSTALL_SUCCEEDED) {
   13547                 cleanUp();
   13548             }
   13549             return status;
   13550         }
   13551 
   13552         @Override
   13553         String getCodePath() {
   13554             return (codeFile != null) ? codeFile.getAbsolutePath() : null;
   13555         }
   13556 
   13557         @Override
   13558         String getResourcePath() {
   13559             return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
   13560         }
   13561 
   13562         private boolean cleanUp() {
   13563             if (codeFile == null || !codeFile.exists()) {
   13564                 return false;
   13565             }
   13566 
   13567             removeCodePathLI(codeFile);
   13568 
   13569             if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
   13570                 resourceFile.delete();
   13571             }
   13572 
   13573             return true;
   13574         }
   13575 
   13576         void cleanUpResourcesLI() {
   13577             // Try enumerating all code paths before deleting
   13578             List<String> allCodePaths = Collections.EMPTY_LIST;
   13579             if (codeFile != null && codeFile.exists()) {
   13580                 try {
   13581                     final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
   13582                     allCodePaths = pkg.getAllCodePaths();
   13583                 } catch (PackageParserException e) {
   13584                     // Ignored; we tried our best
   13585                 }
   13586             }
   13587 
   13588             cleanUp();
   13589             removeDexFiles(allCodePaths, instructionSets);
   13590         }
   13591 
   13592         boolean doPostDeleteLI(boolean delete) {
   13593             // XXX err, shouldn't we respect the delete flag?
   13594             cleanUpResourcesLI();
   13595             return true;
   13596         }
   13597     }
   13598 
   13599     private boolean isAsecExternal(String cid) {
   13600         final String asecPath = PackageHelper.getSdFilesystem(cid);
   13601         return !asecPath.startsWith(mAsecInternalPath);
   13602     }
   13603 
   13604     private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
   13605             PackageManagerException {
   13606         if (copyRet < 0) {
   13607             if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
   13608                     copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
   13609                 throw new PackageManagerException(copyRet, message);
   13610             }
   13611         }
   13612     }
   13613 
   13614     /**
   13615      * Extract the MountService "container ID" from the full code path of an
   13616      * .apk.
   13617      */
   13618     static String cidFromCodePath(String fullCodePath) {
   13619         int eidx = fullCodePath.lastIndexOf("/");
   13620         String subStr1 = fullCodePath.substring(0, eidx);
   13621         int sidx = subStr1.lastIndexOf("/");
   13622         return subStr1.substring(sidx+1, eidx);
   13623     }
   13624 
   13625     /**
   13626      * Logic to handle installation of ASEC applications, including copying and
   13627      * renaming logic.
   13628      */
   13629     class AsecInstallArgs extends InstallArgs {
   13630         static final String RES_FILE_NAME = "pkg.apk";
   13631         static final String PUBLIC_RES_FILE_NAME = "res.zip";
   13632 
   13633         String cid;
   13634         String packagePath;
   13635         String resourcePath;
   13636 
   13637         /** New install */
   13638         AsecInstallArgs(InstallParams params) {
   13639             super(params.origin, params.move, params.observer, params.installFlags,
   13640                     params.installerPackageName, params.volumeUuid,
   13641                     params.getUser(), null /* instruction sets */, params.packageAbiOverride,
   13642                     params.grantedRuntimePermissions,
   13643                     params.traceMethod, params.traceCookie, params.certificates);
   13644         }
   13645 
   13646         /** Existing install */
   13647         AsecInstallArgs(String fullCodePath, String[] instructionSets,
   13648                         boolean isExternal, boolean isForwardLocked) {
   13649             super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
   13650               | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
   13651                     instructionSets, null, null, null, 0, null /*certificates*/);
   13652             // Hackily pretend we're still looking at a full code path
   13653             if (!fullCodePath.endsWith(RES_FILE_NAME)) {
   13654                 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
   13655             }
   13656 
   13657             // Extract cid from fullCodePath
   13658             int eidx = fullCodePath.lastIndexOf("/");
   13659             String subStr1 = fullCodePath.substring(0, eidx);
   13660             int sidx = subStr1.lastIndexOf("/");
   13661             cid = subStr1.substring(sidx+1, eidx);
   13662             setMountPath(subStr1);
   13663         }
   13664 
   13665         AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
   13666             super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
   13667               | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
   13668                     instructionSets, null, null, null, 0, null /*certificates*/);
   13669             this.cid = cid;
   13670             setMountPath(PackageHelper.getSdDir(cid));
   13671         }
   13672 
   13673         void createCopyFile() {
   13674             cid = mInstallerService.allocateExternalStageCidLegacy();
   13675         }
   13676 
   13677         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
   13678             if (origin.staged && origin.cid != null) {
   13679                 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy");
   13680                 cid = origin.cid;
   13681                 setMountPath(PackageHelper.getSdDir(cid));
   13682                 return PackageManager.INSTALL_SUCCEEDED;
   13683             }
   13684 
   13685             if (temp) {
   13686                 createCopyFile();
   13687             } else {
   13688                 /*
   13689                  * Pre-emptively destroy the container since it's destroyed if
   13690                  * copying fails due to it existing anyway.
   13691                  */
   13692                 PackageHelper.destroySdDir(cid);
   13693             }
   13694 
   13695             final String newMountPath = imcs.copyPackageToContainer(
   13696                     origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
   13697                     isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
   13698 
   13699             if (newMountPath != null) {
   13700                 setMountPath(newMountPath);
   13701                 return PackageManager.INSTALL_SUCCEEDED;
   13702             } else {
   13703                 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
   13704             }
   13705         }
   13706 
   13707         @Override
   13708         String getCodePath() {
   13709             return packagePath;
   13710         }
   13711 
   13712         @Override
   13713         String getResourcePath() {
   13714             return resourcePath;
   13715         }
   13716 
   13717         int doPreInstall(int status) {
   13718             if (status != PackageManager.INSTALL_SUCCEEDED) {
   13719                 // Destroy container
   13720                 PackageHelper.destroySdDir(cid);
   13721             } else {
   13722                 boolean mounted = PackageHelper.isContainerMounted(cid);
   13723                 if (!mounted) {
   13724                     String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
   13725                             Process.SYSTEM_UID);
   13726                     if (newMountPath != null) {
   13727                         setMountPath(newMountPath);
   13728                     } else {
   13729                         return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
   13730                     }
   13731                 }
   13732             }
   13733             return status;
   13734         }
   13735 
   13736         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
   13737             String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
   13738             String newMountPath = null;
   13739             if (PackageHelper.isContainerMounted(cid)) {
   13740                 // Unmount the container
   13741                 if (!PackageHelper.unMountSdDir(cid)) {
   13742                     Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
   13743                     return false;
   13744                 }
   13745             }
   13746             if (!PackageHelper.renameSdDir(cid, newCacheId)) {
   13747                 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
   13748                         " which might be stale. Will try to clean up.");
   13749                 // Clean up the stale container and proceed to recreate.
   13750                 if (!PackageHelper.destroySdDir(newCacheId)) {
   13751                     Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
   13752                     return false;
   13753                 }
   13754                 // Successfully cleaned up stale container. Try to rename again.
   13755                 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
   13756                     Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
   13757                             + " inspite of cleaning it up.");
   13758                     return false;
   13759                 }
   13760             }
   13761             if (!PackageHelper.isContainerMounted(newCacheId)) {
   13762                 Slog.w(TAG, "Mounting container " + newCacheId);
   13763                 newMountPath = PackageHelper.mountSdDir(newCacheId,
   13764                         getEncryptKey(), Process.SYSTEM_UID);
   13765             } else {
   13766                 newMountPath = PackageHelper.getSdDir(newCacheId);
   13767             }
   13768             if (newMountPath == null) {
   13769                 Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
   13770                 return false;
   13771             }
   13772             Log.i(TAG, "Succesfully renamed " + cid +
   13773                     " to " + newCacheId +
   13774                     " at new path: " + newMountPath);
   13775             cid = newCacheId;
   13776 
   13777             final File beforeCodeFile = new File(packagePath);
   13778             setMountPath(newMountPath);
   13779             final File afterCodeFile = new File(packagePath);
   13780 
   13781             // Reflect the rename in scanned details
   13782             pkg.setCodePath(afterCodeFile.getAbsolutePath());
   13783             pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
   13784                     afterCodeFile, pkg.baseCodePath));
   13785             pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
   13786                     afterCodeFile, pkg.splitCodePaths));
   13787 
   13788             // Reflect the rename in app info
   13789             pkg.setApplicationVolumeUuid(pkg.volumeUuid);
   13790             pkg.setApplicationInfoCodePath(pkg.codePath);
   13791             pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
   13792             pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
   13793             pkg.setApplicationInfoResourcePath(pkg.codePath);
   13794             pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
   13795             pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
   13796 
   13797             return true;
   13798         }
   13799 
   13800         private void setMountPath(String mountPath) {
   13801             final File mountFile = new File(mountPath);
   13802 
   13803             final File monolithicFile = new File(mountFile, RES_FILE_NAME);
   13804             if (monolithicFile.exists()) {
   13805                 packagePath = monolithicFile.getAbsolutePath();
   13806                 if (isFwdLocked()) {
   13807                     resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
   13808                 } else {
   13809                     resourcePath = packagePath;
   13810                 }
   13811             } else {
   13812                 packagePath = mountFile.getAbsolutePath();
   13813                 resourcePath = packagePath;
   13814             }
   13815         }
   13816 
   13817         int doPostInstall(int status, int uid) {
   13818             if (status != PackageManager.INSTALL_SUCCEEDED) {
   13819                 cleanUp();
   13820             } else {
   13821                 final int groupOwner;
   13822                 final String protectedFile;
   13823                 if (isFwdLocked()) {
   13824                     groupOwner = UserHandle.getSharedAppGid(uid);
   13825                     protectedFile = RES_FILE_NAME;
   13826                 } else {
   13827                     groupOwner = -1;
   13828                     protectedFile = null;
   13829                 }
   13830 
   13831                 if (uid < Process.FIRST_APPLICATION_UID
   13832                         || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
   13833                     Slog.e(TAG, "Failed to finalize " + cid);
   13834                     PackageHelper.destroySdDir(cid);
   13835                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
   13836                 }
   13837 
   13838                 boolean mounted = PackageHelper.isContainerMounted(cid);
   13839                 if (!mounted) {
   13840                     PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
   13841                 }
   13842             }
   13843             return status;
   13844         }
   13845 
   13846         private void cleanUp() {
   13847             if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
   13848 
   13849             // Destroy secure container
   13850             PackageHelper.destroySdDir(cid);
   13851         }
   13852 
   13853         private List<String> getAllCodePaths() {
   13854             final File codeFile = new File(getCodePath());
   13855             if (codeFile != null && codeFile.exists()) {
   13856                 try {
   13857                     final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
   13858                     return pkg.getAllCodePaths();
   13859                 } catch (PackageParserException e) {
   13860                     // Ignored; we tried our best
   13861                 }
   13862             }
   13863             return Collections.EMPTY_LIST;
   13864         }
   13865 
   13866         void cleanUpResourcesLI() {
   13867             // Enumerate all code paths before deleting
   13868             cleanUpResourcesLI(getAllCodePaths());
   13869         }
   13870 
   13871         private void cleanUpResourcesLI(List<String> allCodePaths) {
   13872             cleanUp();
   13873             removeDexFiles(allCodePaths, instructionSets);
   13874         }
   13875 
   13876         String getPackageName() {
   13877             return getAsecPackageName(cid);
   13878         }
   13879 
   13880         boolean doPostDeleteLI(boolean delete) {
   13881             if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
   13882             final List<String> allCodePaths = getAllCodePaths();
   13883             boolean mounted = PackageHelper.isContainerMounted(cid);
   13884             if (mounted) {
   13885                 // Unmount first
   13886                 if (PackageHelper.unMountSdDir(cid)) {
   13887                     mounted = false;
   13888                 }
   13889             }
   13890             if (!mounted && delete) {
   13891                 cleanUpResourcesLI(allCodePaths);
   13892             }
   13893             return !mounted;
   13894         }
   13895 
   13896         @Override
   13897         int doPreCopy() {
   13898             if (isFwdLocked()) {
   13899                 if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE,
   13900                         MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) {
   13901                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
   13902                 }
   13903             }
   13904 
   13905             return PackageManager.INSTALL_SUCCEEDED;
   13906         }
   13907 
   13908         @Override
   13909         int doPostCopy(int uid) {
   13910             if (isFwdLocked()) {
   13911                 if (uid < Process.FIRST_APPLICATION_UID
   13912                         || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
   13913                                 RES_FILE_NAME)) {
   13914                     Slog.e(TAG, "Failed to finalize " + cid);
   13915                     PackageHelper.destroySdDir(cid);
   13916                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
   13917                 }
   13918             }
   13919 
   13920             return PackageManager.INSTALL_SUCCEEDED;
   13921         }
   13922     }
   13923 
   13924     /**
   13925      * Logic to handle movement of existing installed applications.
   13926      */
   13927     class MoveInstallArgs extends InstallArgs {
   13928         private File codeFile;
   13929         private File resourceFile;
   13930 
   13931         /** New install */
   13932         MoveInstallArgs(InstallParams params) {
   13933             super(params.origin, params.move, params.observer, params.installFlags,
   13934                     params.installerPackageName, params.volumeUuid,
   13935                     params.getUser(), null /* instruction sets */, params.packageAbiOverride,
   13936                     params.grantedRuntimePermissions,
   13937                     params.traceMethod, params.traceCookie, params.certificates);
   13938         }
   13939 
   13940         int copyApk(IMediaContainerService imcs, boolean temp) {
   13941             if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
   13942                     + move.fromUuid + " to " + move.toUuid);
   13943             synchronized (mInstaller) {
   13944                 try {
   13945                     mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
   13946                             move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
   13947                 } catch (InstallerException e) {
   13948                     Slog.w(TAG, "Failed to move app", e);
   13949                     return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
   13950                 }
   13951             }
   13952 
   13953             codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
   13954             resourceFile = codeFile;
   13955             if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
   13956 
   13957             return PackageManager.INSTALL_SUCCEEDED;
   13958         }
   13959 
   13960         int doPreInstall(int status) {
   13961             if (status != PackageManager.INSTALL_SUCCEEDED) {
   13962                 cleanUp(move.toUuid);
   13963             }
   13964             return status;
   13965         }
   13966 
   13967         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
   13968             if (status != PackageManager.INSTALL_SUCCEEDED) {
   13969                 cleanUp(move.toUuid);
   13970                 return false;
   13971             }
   13972 
   13973             // Reflect the move in app info
   13974             pkg.setApplicationVolumeUuid(pkg.volumeUuid);
   13975             pkg.setApplicationInfoCodePath(pkg.codePath);
   13976             pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
   13977             pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
   13978             pkg.setApplicationInfoResourcePath(pkg.codePath);
   13979             pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
   13980             pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
   13981 
   13982             return true;
   13983         }
   13984 
   13985         int doPostInstall(int status, int uid) {
   13986             if (status == PackageManager.INSTALL_SUCCEEDED) {
   13987                 cleanUp(move.fromUuid);
   13988             } else {
   13989                 cleanUp(move.toUuid);
   13990             }
   13991             return status;
   13992         }
   13993 
   13994         @Override
   13995         String getCodePath() {
   13996             return (codeFile != null) ? codeFile.getAbsolutePath() : null;
   13997         }
   13998 
   13999         @Override
   14000         String getResourcePath() {
   14001             return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
   14002         }
   14003 
   14004         private boolean cleanUp(String volumeUuid) {
   14005             final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
   14006                     move.dataAppName);
   14007             Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
   14008             final int[] userIds = sUserManager.getUserIds();
   14009             synchronized (mInstallLock) {
   14010                 // Clean up both app data and code
   14011                 // All package moves are frozen until finished
   14012                 for (int userId : userIds) {
   14013                     try {
   14014                         mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
   14015                                 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
   14016                     } catch (InstallerException e) {
   14017                         Slog.w(TAG, String.valueOf(e));
   14018                     }
   14019                 }
   14020                 removeCodePathLI(codeFile);
   14021             }
   14022             return true;
   14023         }
   14024 
   14025         void cleanUpResourcesLI() {
   14026             throw new UnsupportedOperationException();
   14027         }
   14028 
   14029         boolean doPostDeleteLI(boolean delete) {
   14030             throw new UnsupportedOperationException();
   14031         }
   14032     }
   14033 
   14034     static String getAsecPackageName(String packageCid) {
   14035         int idx = packageCid.lastIndexOf("-");
   14036         if (idx == -1) {
   14037             return packageCid;
   14038         }
   14039         return packageCid.substring(0, idx);
   14040     }
   14041 
   14042     // Utility method used to create code paths based on package name and available index.
   14043     private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
   14044         String idxStr = "";
   14045         int idx = 1;
   14046         // Fall back to default value of idx=1 if prefix is not
   14047         // part of oldCodePath
   14048         if (oldCodePath != null) {
   14049             String subStr = oldCodePath;
   14050             // Drop the suffix right away
   14051             if (suffix != null && subStr.endsWith(suffix)) {
   14052                 subStr = subStr.substring(0, subStr.length() - suffix.length());
   14053             }
   14054             // If oldCodePath already contains prefix find out the
   14055             // ending index to either increment or decrement.
   14056             int sidx = subStr.lastIndexOf(prefix);
   14057             if (sidx != -1) {
   14058                 subStr = subStr.substring(sidx + prefix.length());
   14059                 if (subStr != null) {
   14060                     if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
   14061                         subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
   14062                     }
   14063                     try {
   14064                         idx = Integer.parseInt(subStr);
   14065                         if (idx <= 1) {
   14066                             idx++;
   14067                         } else {
   14068                             idx--;
   14069                         }
   14070                     } catch(NumberFormatException e) {
   14071                     }
   14072                 }
   14073             }
   14074         }
   14075         idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
   14076         return prefix + idxStr;
   14077     }
   14078 
   14079     private File getNextCodePath(File targetDir, String packageName) {
   14080         int suffix = 1;
   14081         File result;
   14082         do {
   14083             result = new File(targetDir, packageName + "-" + suffix);
   14084             suffix++;
   14085         } while (result.exists());
   14086         return result;
   14087     }
   14088 
   14089     // Utility method that returns the relative package path with respect
   14090     // to the installation directory. Like say for /data/data/com.test-1.apk
   14091     // string com.test-1 is returned.
   14092     static String deriveCodePathName(String codePath) {
   14093         if (codePath == null) {
   14094             return null;
   14095         }
   14096         final File codeFile = new File(codePath);
   14097         final String name = codeFile.getName();
   14098         if (codeFile.isDirectory()) {
   14099             return name;
   14100         } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
   14101             final int lastDot = name.lastIndexOf('.');
   14102             return name.substring(0, lastDot);
   14103         } else {
   14104             Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
   14105             return null;
   14106         }
   14107     }
   14108 
   14109     static class PackageInstalledInfo {
   14110         String name;
   14111         int uid;
   14112         // The set of users that originally had this package installed.
   14113         int[] origUsers;
   14114         // The set of users that now have this package installed.
   14115         int[] newUsers;
   14116         PackageParser.Package pkg;
   14117         int returnCode;
   14118         String returnMsg;
   14119         PackageRemovedInfo removedInfo;
   14120         ArrayMap<String, PackageInstalledInfo> addedChildPackages;
   14121 
   14122         public void setError(int code, String msg) {
   14123             setReturnCode(code);
   14124             setReturnMessage(msg);
   14125             Slog.w(TAG, msg);
   14126         }
   14127 
   14128         public void setError(String msg, PackageParserException e) {
   14129             setReturnCode(e.error);
   14130             setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
   14131             Slog.w(TAG, msg, e);
   14132         }
   14133 
   14134         public void setError(String msg, PackageManagerException e) {
   14135             returnCode = e.error;
   14136             setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
   14137             Slog.w(TAG, msg, e);
   14138         }
   14139 
   14140         public void setReturnCode(int returnCode) {
   14141             this.returnCode = returnCode;
   14142             final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
   14143             for (int i = 0; i < childCount; i++) {
   14144                 addedChildPackages.valueAt(i).returnCode = returnCode;
   14145             }
   14146         }
   14147 
   14148         private void setReturnMessage(String returnMsg) {
   14149             this.returnMsg = returnMsg;
   14150             final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
   14151             for (int i = 0; i < childCount; i++) {
   14152                 addedChildPackages.valueAt(i).returnMsg = returnMsg;
   14153             }
   14154         }
   14155 
   14156         // In some error cases we want to convey more info back to the observer
   14157         String origPackage;
   14158         String origPermission;
   14159     }
   14160 
   14161     /*
   14162      * Install a non-existing package.
   14163      */
   14164     private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
   14165             int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
   14166             PackageInstalledInfo res) {
   14167         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
   14168 
   14169         // Remember this for later, in case we need to rollback this install
   14170         String pkgName = pkg.packageName;
   14171 
   14172         if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
   14173 
   14174         synchronized(mPackages) {
   14175             if (mSettings.mRenamedPackages.containsKey(pkgName)) {
   14176                 // A package with the same name is already installed, though
   14177                 // it has been renamed to an older name.  The package we
   14178                 // are trying to install should be installed as an update to
   14179                 // the existing one, but that has not been requested, so bail.
   14180                 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
   14181                         + " without first uninstalling package running as "
   14182                         + mSettings.mRenamedPackages.get(pkgName));
   14183                 return;
   14184             }
   14185             if (mPackages.containsKey(pkgName)) {
   14186                 // Don't allow installation over an existing package with the same name.
   14187                 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
   14188                         + " without first uninstalling.");
   14189                 return;
   14190             }
   14191         }
   14192 
   14193         try {
   14194             PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
   14195                     System.currentTimeMillis(), user);
   14196 
   14197             updateSettingsLI(newPackage, installerPackageName, null, res, user);
   14198 
   14199             if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
   14200                 prepareAppDataAfterInstallLIF(newPackage);
   14201 
   14202             } else {
   14203                 // Remove package from internal structures, but keep around any
   14204                 // data that might have already existed
   14205                 deletePackageLIF(pkgName, UserHandle.ALL, false, null,
   14206                         PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
   14207             }
   14208         } catch (PackageManagerException e) {
   14209             res.setError("Package couldn't be installed in " + pkg.codePath, e);
   14210         }
   14211 
   14212         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
   14213     }
   14214 
   14215     private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
   14216         // Can't rotate keys during boot or if sharedUser.
   14217         if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
   14218                 || !oldPs.keySetData.isUsingUpgradeKeySets()) {
   14219             return false;
   14220         }
   14221         // app is using upgradeKeySets; make sure all are valid
   14222         KeySetManagerService ksms = mSettings.mKeySetManagerService;
   14223         long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
   14224         for (int i = 0; i < upgradeKeySets.length; i++) {
   14225             if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
   14226                 Slog.wtf(TAG, "Package "
   14227                          + (oldPs.name != null ? oldPs.name : "<null>")
   14228                          + " contains upgrade-key-set reference to unknown key-set: "
   14229                          + upgradeKeySets[i]
   14230                          + " reverting to signatures check.");
   14231                 return false;
   14232             }
   14233         }
   14234         return true;
   14235     }
   14236 
   14237     private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
   14238         // Upgrade keysets are being used.  Determine if new package has a superset of the
   14239         // required keys.
   14240         long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
   14241         KeySetManagerService ksms = mSettings.mKeySetManagerService;
   14242         for (int i = 0; i < upgradeKeySets.length; i++) {
   14243             Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
   14244             if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
   14245                 return true;
   14246             }
   14247         }
   14248         return false;
   14249     }
   14250 
   14251     private static void updateDigest(MessageDigest digest, File file) throws IOException {
   14252         try (DigestInputStream digestStream =
   14253                 new DigestInputStream(new FileInputStream(file), digest)) {
   14254             while (digestStream.read() != -1) {} // nothing to do; just plow through the file
   14255         }
   14256     }
   14257 
   14258     private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags,
   14259             UserHandle user, String installerPackageName, PackageInstalledInfo res) {
   14260         final boolean isEphemeral = (policyFlags & PackageParser.PARSE_IS_EPHEMERAL) != 0;
   14261 
   14262         final PackageParser.Package oldPackage;
   14263         final String pkgName = pkg.packageName;
   14264         final int[] allUsers;
   14265         final int[] installedUsers;
   14266 
   14267         synchronized(mPackages) {
   14268             oldPackage = mPackages.get(pkgName);
   14269             if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
   14270 
   14271             // don't allow upgrade to target a release SDK from a pre-release SDK
   14272             final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
   14273                     == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
   14274             final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
   14275                     == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
   14276             if (oldTargetsPreRelease
   14277                     && !newTargetsPreRelease
   14278                     && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
   14279                 Slog.w(TAG, "Can't install package targeting released sdk");
   14280                 res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
   14281                 return;
   14282             }
   14283 
   14284             // don't allow an upgrade from full to ephemeral
   14285             final boolean oldIsEphemeral = oldPackage.applicationInfo.isEphemeralApp();
   14286             if (isEphemeral && !oldIsEphemeral) {
   14287                 // can't downgrade from full to ephemeral
   14288                 Slog.w(TAG, "Can't replace app with ephemeral: " + pkgName);
   14289                 res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID);
   14290                 return;
   14291             }
   14292 
   14293             // verify signatures are valid
   14294             final PackageSetting ps = mSettings.mPackages.get(pkgName);
   14295             if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
   14296                 if (!checkUpgradeKeySetLP(ps, pkg)) {
   14297                     res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
   14298                             "New package not signed by keys specified by upgrade-keysets: "
   14299                                     + pkgName);
   14300                     return;
   14301                 }
   14302             } else {
   14303                 // default to original signature matching
   14304                 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
   14305                         != PackageManager.SIGNATURE_MATCH) {
   14306                     res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
   14307                             "New package has a different signature: " + pkgName);
   14308                     return;
   14309                 }
   14310             }
   14311 
   14312             // don't allow a system upgrade unless the upgrade hash matches
   14313             if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) {
   14314                 byte[] digestBytes = null;
   14315                 try {
   14316                     final MessageDigest digest = MessageDigest.getInstance("SHA-512");
   14317                     updateDigest(digest, new File(pkg.baseCodePath));
   14318                     if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
   14319                         for (String path : pkg.splitCodePaths) {
   14320                             updateDigest(digest, new File(path));
   14321                         }
   14322                     }
   14323                     digestBytes = digest.digest();
   14324                 } catch (NoSuchAlgorithmException | IOException e) {
   14325                     res.setError(INSTALL_FAILED_INVALID_APK,
   14326                             "Could not compute hash: " + pkgName);
   14327                     return;
   14328                 }
   14329                 if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
   14330                     res.setError(INSTALL_FAILED_INVALID_APK,
   14331                             "New package fails restrict-update check: " + pkgName);
   14332                     return;
   14333                 }
   14334                 // retain upgrade restriction
   14335                 pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
   14336             }
   14337 
   14338             // Check for shared user id changes
   14339             String invalidPackageName =
   14340                     getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
   14341             if (invalidPackageName != null) {
   14342                 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
   14343                         "Package " + invalidPackageName + " tried to change user "
   14344                                 + oldPackage.mSharedUserId);
   14345                 return;
   14346             }
   14347 
   14348             // In case of rollback, remember per-user/profile install state
   14349             allUsers = sUserManager.getUserIds();
   14350             installedUsers = ps.queryInstalledUsers(allUsers, true);
   14351         }
   14352 
   14353         // Update what is removed
   14354         res.removedInfo = new PackageRemovedInfo();
   14355         res.removedInfo.uid = oldPackage.applicationInfo.uid;
   14356         res.removedInfo.removedPackage = oldPackage.packageName;
   14357         res.removedInfo.isUpdate = true;
   14358         res.removedInfo.origUsers = installedUsers;
   14359         final int childCount = (oldPackage.childPackages != null)
   14360                 ? oldPackage.childPackages.size() : 0;
   14361         for (int i = 0; i < childCount; i++) {
   14362             boolean childPackageUpdated = false;
   14363             PackageParser.Package childPkg = oldPackage.childPackages.get(i);
   14364             if (res.addedChildPackages != null) {
   14365                 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
   14366                 if (childRes != null) {
   14367                     childRes.removedInfo.uid = childPkg.applicationInfo.uid;
   14368                     childRes.removedInfo.removedPackage = childPkg.packageName;
   14369                     childRes.removedInfo.isUpdate = true;
   14370                     childPackageUpdated = true;
   14371                 }
   14372             }
   14373             if (!childPackageUpdated) {
   14374                 PackageRemovedInfo childRemovedRes = new PackageRemovedInfo();
   14375                 childRemovedRes.removedPackage = childPkg.packageName;
   14376                 childRemovedRes.isUpdate = false;
   14377                 childRemovedRes.dataRemoved = true;
   14378                 synchronized (mPackages) {
   14379                     PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName);
   14380                     if (childPs != null) {
   14381                         childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
   14382                     }
   14383                 }
   14384                 if (res.removedInfo.removedChildPackages == null) {
   14385                     res.removedInfo.removedChildPackages = new ArrayMap<>();
   14386                 }
   14387                 res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
   14388             }
   14389         }
   14390 
   14391         boolean sysPkg = (isSystemApp(oldPackage));
   14392         if (sysPkg) {
   14393             // Set the system/privileged flags as needed
   14394             final boolean privileged =
   14395                     (oldPackage.applicationInfo.privateFlags
   14396                             & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
   14397             final int systemPolicyFlags = policyFlags
   14398                     | PackageParser.PARSE_IS_SYSTEM
   14399                     | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0);
   14400 
   14401             replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags,
   14402                     user, allUsers, installerPackageName, res);
   14403         } else {
   14404             replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags,
   14405                     user, allUsers, installerPackageName, res);
   14406         }
   14407     }
   14408 
   14409     public List<String> getPreviousCodePaths(String packageName) {
   14410         final PackageSetting ps = mSettings.mPackages.get(packageName);
   14411         final List<String> result = new ArrayList<String>();
   14412         if (ps != null && ps.oldCodePaths != null) {
   14413             result.addAll(ps.oldCodePaths);
   14414         }
   14415         return result;
   14416     }
   14417 
   14418     private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
   14419             PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
   14420             int[] allUsers, String installerPackageName, PackageInstalledInfo res) {
   14421         if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
   14422                 + deletedPackage);
   14423 
   14424         String pkgName = deletedPackage.packageName;
   14425         boolean deletedPkg = true;
   14426         boolean addedPkg = false;
   14427         boolean updatedSettings = false;
   14428         final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
   14429         final int deleteFlags = PackageManager.DELETE_KEEP_DATA
   14430                 | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
   14431 
   14432         final long origUpdateTime = (pkg.mExtras != null)
   14433                 ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
   14434 
   14435         // First delete the existing package while retaining the data directory
   14436         if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
   14437                 res.removedInfo, true, pkg)) {
   14438             // If the existing package wasn't successfully deleted
   14439             res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
   14440             deletedPkg = false;
   14441         } else {
   14442             // Successfully deleted the old package; proceed with replace.
   14443 
   14444             // If deleted package lived in a container, give users a chance to
   14445             // relinquish resources before killing.
   14446             if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
   14447                 if (DEBUG_INSTALL) {
   14448                     Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
   14449                 }
   14450                 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
   14451                 final ArrayList<String> pkgList = new ArrayList<String>(1);
   14452                 pkgList.add(deletedPackage.applicationInfo.packageName);
   14453                 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
   14454             }
   14455 
   14456             clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
   14457                     | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
   14458             clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
   14459 
   14460             try {
   14461                 final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags,
   14462                         scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
   14463                 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user);
   14464 
   14465                 // Update the in-memory copy of the previous code paths.
   14466                 PackageSetting ps = mSettings.mPackages.get(pkgName);
   14467                 if (!killApp) {
   14468                     if (ps.oldCodePaths == null) {
   14469                         ps.oldCodePaths = new ArraySet<>();
   14470                     }
   14471                     Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
   14472                     if (deletedPackage.splitCodePaths != null) {
   14473                         Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
   14474                     }
   14475                 } else {
   14476                     ps.oldCodePaths = null;
   14477                 }
   14478                 if (ps.childPackageNames != null) {
   14479                     for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
   14480                         final String childPkgName = ps.childPackageNames.get(i);
   14481                         final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
   14482                         childPs.oldCodePaths = ps.oldCodePaths;
   14483                     }
   14484                 }
   14485                 prepareAppDataAfterInstallLIF(newPackage);
   14486                 addedPkg = true;
   14487             } catch (PackageManagerException e) {
   14488                 res.setError("Package couldn't be installed in " + pkg.codePath, e);
   14489             }
   14490         }
   14491 
   14492         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
   14493             if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
   14494 
   14495             // Revert all internal state mutations and added folders for the failed install
   14496             if (addedPkg) {
   14497                 deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
   14498                         res.removedInfo, true, null);
   14499             }
   14500 
   14501             // Restore the old package
   14502             if (deletedPkg) {
   14503                 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
   14504                 File restoreFile = new File(deletedPackage.codePath);
   14505                 // Parse old package
   14506                 boolean oldExternal = isExternal(deletedPackage);
   14507                 int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
   14508                         (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
   14509                         (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
   14510                 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
   14511                 try {
   14512                     scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
   14513                             null);
   14514                 } catch (PackageManagerException e) {
   14515                     Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
   14516                             + e.getMessage());
   14517                     return;
   14518                 }
   14519 
   14520                 synchronized (mPackages) {
   14521                     // Ensure the installer package name up to date
   14522                     setInstallerPackageNameLPw(deletedPackage, installerPackageName);
   14523 
   14524                     // Update permissions for restored package
   14525                     updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
   14526 
   14527                     mSettings.writeLPr();
   14528                 }
   14529 
   14530                 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
   14531             }
   14532         } else {
   14533             synchronized (mPackages) {
   14534                 PackageSetting ps = mSettings.peekPackageLPr(pkg.packageName);
   14535                 if (ps != null) {
   14536                     res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
   14537                     if (res.removedInfo.removedChildPackages != null) {
   14538                         final int childCount = res.removedInfo.removedChildPackages.size();
   14539                         // Iterate in reverse as we may modify the collection
   14540                         for (int i = childCount - 1; i >= 0; i--) {
   14541                             String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
   14542                             if (res.addedChildPackages.containsKey(childPackageName)) {
   14543                                 res.removedInfo.removedChildPackages.removeAt(i);
   14544                             } else {
   14545                                 PackageRemovedInfo childInfo = res.removedInfo
   14546                                         .removedChildPackages.valueAt(i);
   14547                                 childInfo.removedForAllUsers = mPackages.get(
   14548                                         childInfo.removedPackage) == null;
   14549                             }
   14550                         }
   14551                     }
   14552                 }
   14553             }
   14554         }
   14555     }
   14556 
   14557     private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
   14558             PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
   14559             int[] allUsers, String installerPackageName, PackageInstalledInfo res) {
   14560         if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
   14561                 + ", old=" + deletedPackage);
   14562 
   14563         final boolean disabledSystem;
   14564 
   14565         // Remove existing system package
   14566         removePackageLI(deletedPackage, true);
   14567 
   14568         synchronized (mPackages) {
   14569             disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
   14570         }
   14571         if (!disabledSystem) {
   14572             // We didn't need to disable the .apk as a current system package,
   14573             // which means we are replacing another update that is already
   14574             // installed.  We need to make sure to delete the older one's .apk.
   14575             res.removedInfo.args = createInstallArgsForExisting(0,
   14576                     deletedPackage.applicationInfo.getCodePath(),
   14577                     deletedPackage.applicationInfo.getResourcePath(),
   14578                     getAppDexInstructionSets(deletedPackage.applicationInfo));
   14579         } else {
   14580             res.removedInfo.args = null;
   14581         }
   14582 
   14583         // Successfully disabled the old package. Now proceed with re-installation
   14584         clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
   14585                 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
   14586         clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
   14587 
   14588         res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
   14589         pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
   14590                 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
   14591 
   14592         PackageParser.Package newPackage = null;
   14593         try {
   14594             // Add the package to the internal data structures
   14595             newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user);
   14596 
   14597             // Set the update and install times
   14598             PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
   14599             setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
   14600                     System.currentTimeMillis());
   14601 
   14602             // Update the package dynamic state if succeeded
   14603             if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
   14604                 // Now that the install succeeded make sure we remove data
   14605                 // directories for any child package the update removed.
   14606                 final int deletedChildCount = (deletedPackage.childPackages != null)
   14607                         ? deletedPackage.childPackages.size() : 0;
   14608                 final int newChildCount = (newPackage.childPackages != null)
   14609                         ? newPackage.childPackages.size() : 0;
   14610                 for (int i = 0; i < deletedChildCount; i++) {
   14611                     PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
   14612                     boolean childPackageDeleted = true;
   14613                     for (int j = 0; j < newChildCount; j++) {
   14614                         PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
   14615                         if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
   14616                             childPackageDeleted = false;
   14617                             break;
   14618                         }
   14619                     }
   14620                     if (childPackageDeleted) {
   14621                         PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
   14622                                 deletedChildPkg.packageName);
   14623                         if (ps != null && res.removedInfo.removedChildPackages != null) {
   14624                             PackageRemovedInfo removedChildRes = res.removedInfo
   14625                                     .removedChildPackages.get(deletedChildPkg.packageName);
   14626                             removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
   14627                             removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
   14628                         }
   14629                     }
   14630                 }
   14631 
   14632                 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user);
   14633                 prepareAppDataAfterInstallLIF(newPackage);
   14634             }
   14635         } catch (PackageManagerException e) {
   14636             res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
   14637             res.setError("Package couldn't be installed in " + pkg.codePath, e);
   14638         }
   14639 
   14640         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
   14641             // Re installation failed. Restore old information
   14642             // Remove new pkg information
   14643             if (newPackage != null) {
   14644                 removeInstalledPackageLI(newPackage, true);
   14645             }
   14646             // Add back the old system package
   14647             try {
   14648                 scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user);
   14649             } catch (PackageManagerException e) {
   14650                 Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
   14651             }
   14652 
   14653             synchronized (mPackages) {
   14654                 if (disabledSystem) {
   14655                     enableSystemPackageLPw(deletedPackage);
   14656                 }
   14657 
   14658                 // Ensure the installer package name up to date
   14659                 setInstallerPackageNameLPw(deletedPackage, installerPackageName);
   14660 
   14661                 // Update permissions for restored package
   14662                 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
   14663 
   14664                 mSettings.writeLPr();
   14665             }
   14666 
   14667             Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
   14668                     + " after failed upgrade");
   14669         }
   14670     }
   14671 
   14672     /**
   14673      * Checks whether the parent or any of the child packages have a change shared
   14674      * user. For a package to be a valid update the shred users of the parent and
   14675      * the children should match. We may later support changing child shared users.
   14676      * @param oldPkg The updated package.
   14677      * @param newPkg The update package.
   14678      * @return The shared user that change between the versions.
   14679      */
   14680     private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
   14681             PackageParser.Package newPkg) {
   14682         // Check parent shared user
   14683         if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
   14684             return newPkg.packageName;
   14685         }
   14686         // Check child shared users
   14687         final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
   14688         final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
   14689         for (int i = 0; i < newChildCount; i++) {
   14690             PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
   14691             // If this child was present, did it have the same shared user?
   14692             for (int j = 0; j < oldChildCount; j++) {
   14693                 PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
   14694                 if (newChildPkg.packageName.equals(oldChildPkg.packageName)
   14695                         && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
   14696                     return newChildPkg.packageName;
   14697                 }
   14698             }
   14699         }
   14700         return null;
   14701     }
   14702 
   14703     private void removeNativeBinariesLI(PackageSetting ps) {
   14704         // Remove the lib path for the parent package
   14705         if (ps != null) {
   14706             NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
   14707             // Remove the lib path for the child packages
   14708             final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
   14709             for (int i = 0; i < childCount; i++) {
   14710                 PackageSetting childPs = null;
   14711                 synchronized (mPackages) {
   14712                     childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i));
   14713                 }
   14714                 if (childPs != null) {
   14715                     NativeLibraryHelper.removeNativeBinariesLI(childPs
   14716                             .legacyNativeLibraryPathString);
   14717                 }
   14718             }
   14719         }
   14720     }
   14721 
   14722     private void enableSystemPackageLPw(PackageParser.Package pkg) {
   14723         // Enable the parent package
   14724         mSettings.enableSystemPackageLPw(pkg.packageName);
   14725         // Enable the child packages
   14726         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
   14727         for (int i = 0; i < childCount; i++) {
   14728             PackageParser.Package childPkg = pkg.childPackages.get(i);
   14729             mSettings.enableSystemPackageLPw(childPkg.packageName);
   14730         }
   14731     }
   14732 
   14733     private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
   14734             PackageParser.Package newPkg) {
   14735         // Disable the parent package (parent always replaced)
   14736         boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
   14737         // Disable the child packages
   14738         final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
   14739         for (int i = 0; i < childCount; i++) {
   14740             PackageParser.Package childPkg = oldPkg.childPackages.get(i);
   14741             final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
   14742             disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
   14743         }
   14744         return disabled;
   14745     }
   14746 
   14747     private void setInstallerPackageNameLPw(PackageParser.Package pkg,
   14748             String installerPackageName) {
   14749         // Enable the parent package
   14750         mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
   14751         // Enable the child packages
   14752         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
   14753         for (int i = 0; i < childCount; i++) {
   14754             PackageParser.Package childPkg = pkg.childPackages.get(i);
   14755             mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
   14756         }
   14757     }
   14758 
   14759     private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
   14760         // Collect all used permissions in the UID
   14761         ArraySet<String> usedPermissions = new ArraySet<>();
   14762         final int packageCount = su.packages.size();
   14763         for (int i = 0; i < packageCount; i++) {
   14764             PackageSetting ps = su.packages.valueAt(i);
   14765             if (ps.pkg == null) {
   14766                 continue;
   14767             }
   14768             final int requestedPermCount = ps.pkg.requestedPermissions.size();
   14769             for (int j = 0; j < requestedPermCount; j++) {
   14770                 String permission = ps.pkg.requestedPermissions.get(j);
   14771                 BasePermission bp = mSettings.mPermissions.get(permission);
   14772                 if (bp != null) {
   14773                     usedPermissions.add(permission);
   14774                 }
   14775             }
   14776         }
   14777 
   14778         PermissionsState permissionsState = su.getPermissionsState();
   14779         // Prune install permissions
   14780         List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
   14781         final int installPermCount = installPermStates.size();
   14782         for (int i = installPermCount - 1; i >= 0;  i--) {
   14783             PermissionState permissionState = installPermStates.get(i);
   14784             if (!usedPermissions.contains(permissionState.getName())) {
   14785                 BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
   14786                 if (bp != null) {
   14787                     permissionsState.revokeInstallPermission(bp);
   14788                     permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
   14789                             PackageManager.MASK_PERMISSION_FLAGS, 0);
   14790                 }
   14791             }
   14792         }
   14793 
   14794         int[] runtimePermissionChangedUserIds = EmptyArray.INT;
   14795 
   14796         // Prune runtime permissions
   14797         for (int userId : allUserIds) {
   14798             List<PermissionState> runtimePermStates = permissionsState
   14799                     .getRuntimePermissionStates(userId);
   14800             final int runtimePermCount = runtimePermStates.size();
   14801             for (int i = runtimePermCount - 1; i >= 0; i--) {
   14802                 PermissionState permissionState = runtimePermStates.get(i);
   14803                 if (!usedPermissions.contains(permissionState.getName())) {
   14804                     BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
   14805                     if (bp != null) {
   14806                         permissionsState.revokeRuntimePermission(bp, userId);
   14807                         permissionsState.updatePermissionFlags(bp, userId,
   14808                                 PackageManager.MASK_PERMISSION_FLAGS, 0);
   14809                         runtimePermissionChangedUserIds = ArrayUtils.appendInt(
   14810                                 runtimePermissionChangedUserIds, userId);
   14811                     }
   14812                 }
   14813             }
   14814         }
   14815 
   14816         return runtimePermissionChangedUserIds;
   14817     }
   14818 
   14819     private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
   14820             int[] allUsers, PackageInstalledInfo res, UserHandle user) {
   14821         // Update the parent package setting
   14822         updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
   14823                 res, user);
   14824         // Update the child packages setting
   14825         final int childCount = (newPackage.childPackages != null)
   14826                 ? newPackage.childPackages.size() : 0;
   14827         for (int i = 0; i < childCount; i++) {
   14828             PackageParser.Package childPackage = newPackage.childPackages.get(i);
   14829             PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
   14830             updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
   14831                     childRes.origUsers, childRes, user);
   14832         }
   14833     }
   14834 
   14835     private void updateSettingsInternalLI(PackageParser.Package newPackage,
   14836             String installerPackageName, int[] allUsers, int[] installedForUsers,
   14837             PackageInstalledInfo res, UserHandle user) {
   14838         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
   14839 
   14840         String pkgName = newPackage.packageName;
   14841         synchronized (mPackages) {
   14842             //write settings. the installStatus will be incomplete at this stage.
   14843             //note that the new package setting would have already been
   14844             //added to mPackages. It hasn't been persisted yet.
   14845             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
   14846             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
   14847             mSettings.writeLPr();
   14848             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
   14849         }
   14850 
   14851         if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
   14852         synchronized (mPackages) {
   14853             updatePermissionsLPw(newPackage.packageName, newPackage,
   14854                     UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
   14855                             ? UPDATE_PERMISSIONS_ALL : 0));
   14856             // For system-bundled packages, we assume that installing an upgraded version
   14857             // of the package implies that the user actually wants to run that new code,
   14858             // so we enable the package.
   14859             PackageSetting ps = mSettings.mPackages.get(pkgName);
   14860             final int userId = user.getIdentifier();
   14861             if (ps != null) {
   14862                 if (isSystemApp(newPackage)) {
   14863                     if (DEBUG_INSTALL) {
   14864                         Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
   14865                     }
   14866                     // Enable system package for requested users
   14867                     if (res.origUsers != null) {
   14868                         for (int origUserId : res.origUsers) {
   14869                             if (userId == UserHandle.USER_ALL || userId == origUserId) {
   14870                                 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
   14871                                         origUserId, installerPackageName);
   14872                             }
   14873                         }
   14874                     }
   14875                     // Also convey the prior install/uninstall state
   14876                     if (allUsers != null && installedForUsers != null) {
   14877                         for (int currentUserId : allUsers) {
   14878                             final boolean installed = ArrayUtils.contains(
   14879                                     installedForUsers, currentUserId);
   14880                             if (DEBUG_INSTALL) {
   14881                                 Slog.d(TAG, "    user " + currentUserId + " => " + installed);
   14882                             }
   14883                             ps.setInstalled(installed, currentUserId);
   14884                         }
   14885                         // these install state changes will be persisted in the
   14886                         // upcoming call to mSettings.writeLPr().
   14887                     }
   14888                 }
   14889                 // It's implied that when a user requests installation, they want the app to be
   14890                 // installed and enabled.
   14891                 if (userId != UserHandle.USER_ALL) {
   14892                     ps.setInstalled(true, userId);
   14893                     ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
   14894                 }
   14895             }
   14896             res.name = pkgName;
   14897             res.uid = newPackage.applicationInfo.uid;
   14898             res.pkg = newPackage;
   14899             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
   14900             mSettings.setInstallerPackageName(pkgName, installerPackageName);
   14901             res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
   14902             //to update install status
   14903             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
   14904             mSettings.writeLPr();
   14905             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
   14906         }
   14907 
   14908         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
   14909     }
   14910 
   14911     private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
   14912         try {
   14913             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
   14914             installPackageLI(args, res);
   14915         } finally {
   14916             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
   14917         }
   14918     }
   14919 
   14920     private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
   14921         final int installFlags = args.installFlags;
   14922         final String installerPackageName = args.installerPackageName;
   14923         final String volumeUuid = args.volumeUuid;
   14924         final File tmpPackageFile = new File(args.getCodePath());
   14925         final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
   14926         final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
   14927                 || (args.volumeUuid != null));
   14928         final boolean ephemeral = ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0);
   14929         final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
   14930         boolean replace = false;
   14931         int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
   14932         if (args.move != null) {
   14933             // moving a complete application; perform an initial scan on the new install location
   14934             scanFlags |= SCAN_INITIAL;
   14935         }
   14936         if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
   14937             scanFlags |= SCAN_DONT_KILL_APP;
   14938         }
   14939 
   14940         // Result object to be returned
   14941         res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
   14942 
   14943         if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
   14944 
   14945         // Sanity check
   14946         if (ephemeral && (forwardLocked || onExternal)) {
   14947             Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
   14948                     + " external=" + onExternal);
   14949             res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID);
   14950             return;
   14951         }
   14952 
   14953         // Retrieve PackageSettings and parse package
   14954         final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
   14955                 | PackageParser.PARSE_ENFORCE_CODE
   14956                 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
   14957                 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
   14958                 | (ephemeral ? PackageParser.PARSE_IS_EPHEMERAL : 0)
   14959                 | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
   14960         PackageParser pp = new PackageParser();
   14961         pp.setSeparateProcesses(mSeparateProcesses);
   14962         pp.setDisplayMetrics(mMetrics);
   14963 
   14964         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
   14965         final PackageParser.Package pkg;
   14966         try {
   14967             pkg = pp.parsePackage(tmpPackageFile, parseFlags);
   14968         } catch (PackageParserException e) {
   14969             res.setError("Failed parse during installPackageLI", e);
   14970             return;
   14971         } finally {
   14972             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
   14973         }
   14974 
   14975         // If we are installing a clustered package add results for the children
   14976         if (pkg.childPackages != null) {
   14977             synchronized (mPackages) {
   14978                 final int childCount = pkg.childPackages.size();
   14979                 for (int i = 0; i < childCount; i++) {
   14980                     PackageParser.Package childPkg = pkg.childPackages.get(i);
   14981                     PackageInstalledInfo childRes = new PackageInstalledInfo();
   14982                     childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
   14983                     childRes.pkg = childPkg;
   14984                     childRes.name = childPkg.packageName;
   14985                     PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName);
   14986                     if (childPs != null) {
   14987                         childRes.origUsers = childPs.queryInstalledUsers(
   14988                                 sUserManager.getUserIds(), true);
   14989                     }
   14990                     if ((mPackages.containsKey(childPkg.packageName))) {
   14991                         childRes.removedInfo = new PackageRemovedInfo();
   14992                         childRes.removedInfo.removedPackage = childPkg.packageName;
   14993                     }
   14994                     if (res.addedChildPackages == null) {
   14995                         res.addedChildPackages = new ArrayMap<>();
   14996                     }
   14997                     res.addedChildPackages.put(childPkg.packageName, childRes);
   14998                 }
   14999             }
   15000         }
   15001 
   15002         // If package doesn't declare API override, mark that we have an install
   15003         // time CPU ABI override.
   15004         if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
   15005             pkg.cpuAbiOverride = args.abiOverride;
   15006         }
   15007 
   15008         String pkgName = res.name = pkg.packageName;
   15009         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
   15010             if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
   15011                 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
   15012                 return;
   15013             }
   15014         }
   15015 
   15016         try {
   15017             // either use what we've been given or parse directly from the APK
   15018             if (args.certificates != null) {
   15019                 try {
   15020                     PackageParser.populateCertificates(pkg, args.certificates);
   15021                 } catch (PackageParserException e) {
   15022                     // there was something wrong with the certificates we were given;
   15023                     // try to pull them from the APK
   15024                     PackageParser.collectCertificates(pkg, parseFlags);
   15025                 }
   15026             } else {
   15027                 PackageParser.collectCertificates(pkg, parseFlags);
   15028             }
   15029         } catch (PackageParserException e) {
   15030             res.setError("Failed collect during installPackageLI", e);
   15031             return;
   15032         }
   15033 
   15034         // Get rid of all references to package scan path via parser.
   15035         pp = null;
   15036         String oldCodePath = null;
   15037         boolean systemApp = false;
   15038         synchronized (mPackages) {
   15039             // Check if installing already existing package
   15040             if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
   15041                 String oldName = mSettings.mRenamedPackages.get(pkgName);
   15042                 if (pkg.mOriginalPackages != null
   15043                         && pkg.mOriginalPackages.contains(oldName)
   15044                         && mPackages.containsKey(oldName)) {
   15045                     // This package is derived from an original package,
   15046                     // and this device has been updating from that original
   15047                     // name.  We must continue using the original name, so
   15048                     // rename the new package here.
   15049                     pkg.setPackageName(oldName);
   15050                     pkgName = pkg.packageName;
   15051                     replace = true;
   15052                     if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
   15053                             + oldName + " pkgName=" + pkgName);
   15054                 } else if (mPackages.containsKey(pkgName)) {
   15055                     // This package, under its official name, already exists
   15056                     // on the device; we should replace it.
   15057                     replace = true;
   15058                     if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
   15059                 }
   15060 
   15061                 // Child packages are installed through the parent package
   15062                 if (pkg.parentPackage != null) {
   15063                     res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
   15064                             "Package " + pkg.packageName + " is child of package "
   15065                                     + pkg.parentPackage.parentPackage + ". Child packages "
   15066                                     + "can be updated only through the parent package.");
   15067                     return;
   15068                 }
   15069 
   15070                 if (replace) {
   15071                     // Prevent apps opting out from runtime permissions
   15072                     PackageParser.Package oldPackage = mPackages.get(pkgName);
   15073                     final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
   15074                     final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
   15075                     if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
   15076                             && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
   15077                         res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
   15078                                 "Package " + pkg.packageName + " new target SDK " + newTargetSdk
   15079                                         + " doesn't support runtime permissions but the old"
   15080                                         + " target SDK " + oldTargetSdk + " does.");
   15081                         return;
   15082                     }
   15083 
   15084                     // Prevent installing of child packages
   15085                     if (oldPackage.parentPackage != null) {
   15086                         res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
   15087                                 "Package " + pkg.packageName + " is child of package "
   15088                                         + oldPackage.parentPackage + ". Child packages "
   15089                                         + "can be updated only through the parent package.");
   15090                         return;
   15091                     }
   15092                 }
   15093             }
   15094 
   15095             PackageSetting ps = mSettings.mPackages.get(pkgName);
   15096             if (ps != null) {
   15097                 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
   15098 
   15099                 // Quick sanity check that we're signed correctly if updating;
   15100                 // we'll check this again later when scanning, but we want to
   15101                 // bail early here before tripping over redefined permissions.
   15102                 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
   15103                     if (!checkUpgradeKeySetLP(ps, pkg)) {
   15104                         res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
   15105                                 + pkg.packageName + " upgrade keys do not match the "
   15106                                 + "previously installed version");
   15107                         return;
   15108                     }
   15109                 } else {
   15110                     try {
   15111                         verifySignaturesLP(ps, pkg);
   15112                     } catch (PackageManagerException e) {
   15113                         res.setError(e.error, e.getMessage());
   15114                         return;
   15115                     }
   15116                 }
   15117 
   15118                 oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
   15119                 if (ps.pkg != null && ps.pkg.applicationInfo != null) {
   15120                     systemApp = (ps.pkg.applicationInfo.flags &
   15121                             ApplicationInfo.FLAG_SYSTEM) != 0;
   15122                 }
   15123                 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
   15124             }
   15125 
   15126             // Check whether the newly-scanned package wants to define an already-defined perm
   15127             int N = pkg.permissions.size();
   15128             for (int i = N-1; i >= 0; i--) {
   15129                 PackageParser.Permission perm = pkg.permissions.get(i);
   15130                 BasePermission bp = mSettings.mPermissions.get(perm.info.name);
   15131                 if (bp != null) {
   15132                     // If the defining package is signed with our cert, it's okay.  This
   15133                     // also includes the "updating the same package" case, of course.
   15134                     // "updating same package" could also involve key-rotation.
   15135                     final boolean sigsOk;
   15136                     if (bp.sourcePackage.equals(pkg.packageName)
   15137                             && (bp.packageSetting instanceof PackageSetting)
   15138                             && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting,
   15139                                     scanFlags))) {
   15140                         sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
   15141                     } else {
   15142                         sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
   15143                                 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
   15144                     }
   15145                     if (!sigsOk) {
   15146                         // If the owning package is the system itself, we log but allow
   15147                         // install to proceed; we fail the install on all other permission
   15148                         // redefinitions.
   15149                         if (!bp.sourcePackage.equals("android")) {
   15150                             res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
   15151                                     + pkg.packageName + " attempting to redeclare permission "
   15152                                     + perm.info.name + " already owned by " + bp.sourcePackage);
   15153                             res.origPermission = perm.info.name;
   15154                             res.origPackage = bp.sourcePackage;
   15155                             return;
   15156                         } else {
   15157                             Slog.w(TAG, "Package " + pkg.packageName
   15158                                     + " attempting to redeclare system permission "
   15159                                     + perm.info.name + "; ignoring new declaration");
   15160                             pkg.permissions.remove(i);
   15161                         }
   15162                     }
   15163                 }
   15164             }
   15165         }
   15166 
   15167         if (systemApp) {
   15168             if (onExternal) {
   15169                 // Abort update; system app can't be replaced with app on sdcard
   15170                 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
   15171                         "Cannot install updates to system apps on sdcard");
   15172                 return;
   15173             } else if (ephemeral) {
   15174                 // Abort update; system app can't be replaced with an ephemeral app
   15175                 res.setError(INSTALL_FAILED_EPHEMERAL_INVALID,
   15176                         "Cannot update a system app with an ephemeral app");
   15177                 return;
   15178             }
   15179         }
   15180 
   15181         if (args.move != null) {
   15182             // We did an in-place move, so dex is ready to roll
   15183             scanFlags |= SCAN_NO_DEX;
   15184             scanFlags |= SCAN_MOVE;
   15185 
   15186             synchronized (mPackages) {
   15187                 final PackageSetting ps = mSettings.mPackages.get(pkgName);
   15188                 if (ps == null) {
   15189                     res.setError(INSTALL_FAILED_INTERNAL_ERROR,
   15190                             "Missing settings for moved package " + pkgName);
   15191                 }
   15192 
   15193                 // We moved the entire application as-is, so bring over the
   15194                 // previously derived ABI information.
   15195                 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
   15196                 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
   15197             }
   15198 
   15199         } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
   15200             // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
   15201             scanFlags |= SCAN_NO_DEX;
   15202 
   15203             try {
   15204                 String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
   15205                     args.abiOverride : pkg.cpuAbiOverride);
   15206                 derivePackageAbi(pkg, new File(pkg.codePath), abiOverride,
   15207                         true /* extract libs */);
   15208             } catch (PackageManagerException pme) {
   15209                 Slog.e(TAG, "Error deriving application ABI", pme);
   15210                 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
   15211                 return;
   15212             }
   15213 
   15214             // Shared libraries for the package need to be updated.
   15215             synchronized (mPackages) {
   15216                 try {
   15217                     updateSharedLibrariesLPw(pkg, null);
   15218                 } catch (PackageManagerException e) {
   15219                     Slog.e(TAG, "updateSharedLibrariesLPw failed: " + e.getMessage());
   15220                 }
   15221             }
   15222             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
   15223             // Do not run PackageDexOptimizer through the local performDexOpt
   15224             // method because `pkg` may not be in `mPackages` yet.
   15225             //
   15226             // Also, don't fail application installs if the dexopt step fails.
   15227             mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
   15228                     null /* instructionSets */, false /* checkProfiles */,
   15229                     getCompilerFilterForReason(REASON_INSTALL),
   15230                     getOrCreateCompilerPackageStats(pkg));
   15231             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
   15232 
   15233             // Notify BackgroundDexOptService that the package has been changed.
   15234             // If this is an update of a package which used to fail to compile,
   15235             // BDOS will remove it from its blacklist.
   15236             BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
   15237         }
   15238 
   15239         if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
   15240             res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
   15241             return;
   15242         }
   15243 
   15244         startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
   15245 
   15246         try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
   15247                 "installPackageLI")) {
   15248             if (replace) {
   15249                 replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
   15250                         installerPackageName, res);
   15251             } else {
   15252                 installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
   15253                         args.user, installerPackageName, volumeUuid, res);
   15254             }
   15255         }
   15256         synchronized (mPackages) {
   15257             final PackageSetting ps = mSettings.mPackages.get(pkgName);
   15258             if (ps != null) {
   15259                 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
   15260             }
   15261 
   15262             final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
   15263             for (int i = 0; i < childCount; i++) {
   15264                 PackageParser.Package childPkg = pkg.childPackages.get(i);
   15265                 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
   15266                 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName);
   15267                 if (childPs != null) {
   15268                     childRes.newUsers = childPs.queryInstalledUsers(
   15269                             sUserManager.getUserIds(), true);
   15270                 }
   15271             }
   15272         }
   15273     }
   15274 
   15275     private void startIntentFilterVerifications(int userId, boolean replacing,
   15276             PackageParser.Package pkg) {
   15277         if (mIntentFilterVerifierComponent == null) {
   15278             Slog.w(TAG, "No IntentFilter verification will not be done as "
   15279                     + "there is no IntentFilterVerifier available!");
   15280             return;
   15281         }
   15282 
   15283         final int verifierUid = getPackageUid(
   15284                 mIntentFilterVerifierComponent.getPackageName(),
   15285                 MATCH_DEBUG_TRIAGED_MISSING,
   15286                 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
   15287 
   15288         Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
   15289         msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
   15290         mHandler.sendMessage(msg);
   15291 
   15292         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
   15293         for (int i = 0; i < childCount; i++) {
   15294             PackageParser.Package childPkg = pkg.childPackages.get(i);
   15295             msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
   15296             msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
   15297             mHandler.sendMessage(msg);
   15298         }
   15299     }
   15300 
   15301     private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
   15302             PackageParser.Package pkg) {
   15303         int size = pkg.activities.size();
   15304         if (size == 0) {
   15305             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
   15306                     "No activity, so no need to verify any IntentFilter!");
   15307             return;
   15308         }
   15309 
   15310         final boolean hasDomainURLs = hasDomainURLs(pkg);
   15311         if (!hasDomainURLs) {
   15312             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
   15313                     "No domain URLs, so no need to verify any IntentFilter!");
   15314             return;
   15315         }
   15316 
   15317         if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
   15318                 + " if any IntentFilter from the " + size
   15319                 + " Activities needs verification ...");
   15320 
   15321         int count = 0;
   15322         final String packageName = pkg.packageName;
   15323 
   15324         synchronized (mPackages) {
   15325             // If this is a new install and we see that we've already run verification for this
   15326             // package, we have nothing to do: it means the state was restored from backup.
   15327             if (!replacing) {
   15328                 IntentFilterVerificationInfo ivi =
   15329                         mSettings.getIntentFilterVerificationLPr(packageName);
   15330                 if (ivi != null) {
   15331                     if (DEBUG_DOMAIN_VERIFICATION) {
   15332                         Slog.i(TAG, "Package " + packageName+ " already verified: status="
   15333                                 + ivi.getStatusString());
   15334                     }
   15335                     return;
   15336                 }
   15337             }
   15338 
   15339             // If any filters need to be verified, then all need to be.
   15340             boolean needToVerify = false;
   15341             for (PackageParser.Activity a : pkg.activities) {
   15342                 for (ActivityIntentInfo filter : a.intents) {
   15343                     if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
   15344                         if (DEBUG_DOMAIN_VERIFICATION) {
   15345                             Slog.d(TAG, "Intent filter needs verification, so processing all filters");
   15346                         }
   15347                         needToVerify = true;
   15348                         break;
   15349                     }
   15350                 }
   15351             }
   15352 
   15353             if (needToVerify) {
   15354                 final int verificationId = mIntentFilterVerificationToken++;
   15355                 for (PackageParser.Activity a : pkg.activities) {
   15356                     for (ActivityIntentInfo filter : a.intents) {
   15357                         if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
   15358                             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
   15359                                     "Verification needed for IntentFilter:" + filter.toString());
   15360                             mIntentFilterVerifier.addOneIntentFilterVerification(
   15361                                     verifierUid, userId, verificationId, filter, packageName);
   15362                             count++;
   15363                         }
   15364                     }
   15365                 }
   15366             }
   15367         }
   15368 
   15369         if (count > 0) {
   15370             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
   15371                     + " IntentFilter verification" + (count > 1 ? "s" : "")
   15372                     +  " for userId:" + userId);
   15373             mIntentFilterVerifier.startVerifications(userId);
   15374         } else {
   15375             if (DEBUG_DOMAIN_VERIFICATION) {
   15376                 Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
   15377             }
   15378         }
   15379     }
   15380 
   15381     private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
   15382         final ComponentName cn  = filter.activity.getComponentName();
   15383         final String packageName = cn.getPackageName();
   15384 
   15385         IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
   15386                 packageName);
   15387         if (ivi == null) {
   15388             return true;
   15389         }
   15390         int status = ivi.getStatus();
   15391         switch (status) {
   15392             case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
   15393             case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
   15394                 return true;
   15395 
   15396             default:
   15397                 // Nothing to do
   15398                 return false;
   15399         }
   15400     }
   15401 
   15402     private static boolean isMultiArch(ApplicationInfo info) {
   15403         return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
   15404     }
   15405 
   15406     private static boolean isExternal(PackageParser.Package pkg) {
   15407         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
   15408     }
   15409 
   15410     private static boolean isExternal(PackageSetting ps) {
   15411         return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
   15412     }
   15413 
   15414     private static boolean isEphemeral(PackageParser.Package pkg) {
   15415         return pkg.applicationInfo.isEphemeralApp();
   15416     }
   15417 
   15418     private static boolean isEphemeral(PackageSetting ps) {
   15419         return ps.pkg != null && isEphemeral(ps.pkg);
   15420     }
   15421 
   15422     private static boolean isSystemApp(PackageParser.Package pkg) {
   15423         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
   15424     }
   15425 
   15426     private static boolean isPrivilegedApp(PackageParser.Package pkg) {
   15427         return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
   15428     }
   15429 
   15430     private static boolean hasDomainURLs(PackageParser.Package pkg) {
   15431         return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
   15432     }
   15433 
   15434     private static boolean isSystemApp(PackageSetting ps) {
   15435         return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
   15436     }
   15437 
   15438     private static boolean isUpdatedSystemApp(PackageSetting ps) {
   15439         return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
   15440     }
   15441 
   15442     private int packageFlagsToInstallFlags(PackageSetting ps) {
   15443         int installFlags = 0;
   15444         if (isEphemeral(ps)) {
   15445             installFlags |= PackageManager.INSTALL_EPHEMERAL;
   15446         }
   15447         if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
   15448             // This existing package was an external ASEC install when we have
   15449             // the external flag without a UUID
   15450             installFlags |= PackageManager.INSTALL_EXTERNAL;
   15451         }
   15452         if (ps.isForwardLocked()) {
   15453             installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
   15454         }
   15455         return installFlags;
   15456     }
   15457 
   15458     private String getVolumeUuidForPackage(PackageParser.Package pkg) {
   15459         if (isExternal(pkg)) {
   15460             if (TextUtils.isEmpty(pkg.volumeUuid)) {
   15461                 return StorageManager.UUID_PRIMARY_PHYSICAL;
   15462             } else {
   15463                 return pkg.volumeUuid;
   15464             }
   15465         } else {
   15466             return StorageManager.UUID_PRIVATE_INTERNAL;
   15467         }
   15468     }
   15469 
   15470     private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
   15471         if (isExternal(pkg)) {
   15472             if (TextUtils.isEmpty(pkg.volumeUuid)) {
   15473                 return mSettings.getExternalVersion();
   15474             } else {
   15475                 return mSettings.findOrCreateVersion(pkg.volumeUuid);
   15476             }
   15477         } else {
   15478             return mSettings.getInternalVersion();
   15479         }
   15480     }
   15481 
   15482     private void deleteTempPackageFiles() {
   15483         final FilenameFilter filter = new FilenameFilter() {
   15484             public boolean accept(File dir, String name) {
   15485                 return name.startsWith("vmdl") && name.endsWith(".tmp");
   15486             }
   15487         };
   15488         for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
   15489             file.delete();
   15490         }
   15491     }
   15492 
   15493     @Override
   15494     public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId,
   15495             int flags) {
   15496         deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId,
   15497                 flags);
   15498     }
   15499 
   15500     @Override
   15501     public void deletePackage(final String packageName,
   15502             final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
   15503         mContext.enforceCallingOrSelfPermission(
   15504                 android.Manifest.permission.DELETE_PACKAGES, null);
   15505         Preconditions.checkNotNull(packageName);
   15506         Preconditions.checkNotNull(observer);
   15507         final int uid = Binder.getCallingUid();
   15508         if (!isOrphaned(packageName)
   15509                 && !isCallerAllowedToSilentlyUninstall(uid, packageName)) {
   15510             try {
   15511                 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
   15512                 intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
   15513                 intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
   15514                 observer.onUserActionRequired(intent);
   15515             } catch (RemoteException re) {
   15516             }
   15517             return;
   15518         }
   15519         final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
   15520         final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
   15521         if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
   15522             mContext.enforceCallingOrSelfPermission(
   15523                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
   15524                     "deletePackage for user " + userId);
   15525         }
   15526 
   15527         if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
   15528             try {
   15529                 observer.onPackageDeleted(packageName,
   15530                         PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
   15531             } catch (RemoteException re) {
   15532             }
   15533             return;
   15534         }
   15535 
   15536         if (!deleteAllUsers && getBlockUninstallForUser(packageName, userId)) {
   15537             try {
   15538                 observer.onPackageDeleted(packageName,
   15539                         PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
   15540             } catch (RemoteException re) {
   15541             }
   15542             return;
   15543         }
   15544 
   15545         if (DEBUG_REMOVE) {
   15546             Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId
   15547                     + " deleteAllUsers: " + deleteAllUsers );
   15548         }
   15549         // Queue up an async operation since the package deletion may take a little while.
   15550         mHandler.post(new Runnable() {
   15551             public void run() {
   15552                 mHandler.removeCallbacks(this);
   15553                 int returnCode;
   15554                 if (!deleteAllUsers) {
   15555                     returnCode = deletePackageX(packageName, userId, deleteFlags);
   15556                 } else {
   15557                     int[] blockUninstallUserIds = getBlockUninstallForUsers(packageName, users);
   15558                     // If nobody is blocking uninstall, proceed with delete for all users
   15559                     if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
   15560                         returnCode = deletePackageX(packageName, userId, deleteFlags);
   15561                     } else {
   15562                         // Otherwise uninstall individually for users with blockUninstalls=false
   15563                         final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
   15564                         for (int userId : users) {
   15565                             if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
   15566                                 returnCode = deletePackageX(packageName, userId, userFlags);
   15567                                 if (returnCode != PackageManager.DELETE_SUCCEEDED) {
   15568                                     Slog.w(TAG, "Package delete failed for user " + userId
   15569                                             + ", returnCode " + returnCode);
   15570                                 }
   15571                             }
   15572                         }
   15573                         // The app has only been marked uninstalled for certain users.
   15574                         // We still need to report that delete was blocked
   15575                         returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
   15576                     }
   15577                 }
   15578                 try {
   15579                     observer.onPackageDeleted(packageName, returnCode, null);
   15580                 } catch (RemoteException e) {
   15581                     Log.i(TAG, "Observer no longer exists.");
   15582                 } //end catch
   15583             } //end run
   15584         });
   15585     }
   15586 
   15587     private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
   15588         if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
   15589               || callingUid == Process.SYSTEM_UID) {
   15590             return true;
   15591         }
   15592         final int callingUserId = UserHandle.getUserId(callingUid);
   15593         // If the caller installed the pkgName, then allow it to silently uninstall.
   15594         if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
   15595             return true;
   15596         }
   15597 
   15598         // Allow package verifier to silently uninstall.
   15599         if (mRequiredVerifierPackage != null &&
   15600                 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
   15601             return true;
   15602         }
   15603 
   15604         // Allow package uninstaller to silently uninstall.
   15605         if (mRequiredUninstallerPackage != null &&
   15606                 callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
   15607             return true;
   15608         }
   15609 
   15610         // Allow storage manager to silently uninstall.
   15611         if (mStorageManagerPackage != null &&
   15612                 callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
   15613             return true;
   15614         }
   15615         return false;
   15616     }
   15617 
   15618     private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
   15619         int[] result = EMPTY_INT_ARRAY;
   15620         for (int userId : userIds) {
   15621             if (getBlockUninstallForUser(packageName, userId)) {
   15622                 result = ArrayUtils.appendInt(result, userId);
   15623             }
   15624         }
   15625         return result;
   15626     }
   15627 
   15628     @Override
   15629     public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
   15630         return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
   15631     }
   15632 
   15633     private boolean isPackageDeviceAdmin(String packageName, int userId) {
   15634         IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
   15635                 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
   15636         try {
   15637             if (dpm != null) {
   15638                 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
   15639                         /* callingUserOnly =*/ false);
   15640                 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
   15641                         : deviceOwnerComponentName.getPackageName();
   15642                 // Does the package contains the device owner?
   15643                 // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
   15644                 // this check is probably not needed, since DO should be registered as a device
   15645                 // admin on some user too. (Original bug for this: b/17657954)
   15646                 if (packageName.equals(deviceOwnerPackageName)) {
   15647                     return true;
   15648                 }
   15649                 // Does it contain a device admin for any user?
   15650                 int[] users;
   15651                 if (userId == UserHandle.USER_ALL) {
   15652                     users = sUserManager.getUserIds();
   15653                 } else {
   15654                     users = new int[]{userId};
   15655                 }
   15656                 for (int i = 0; i < users.length; ++i) {
   15657                     if (dpm.packageHasActiveAdmins(packageName, users[i])) {
   15658                         return true;
   15659                     }
   15660                 }
   15661             }
   15662         } catch (RemoteException e) {
   15663         }
   15664         return false;
   15665     }
   15666 
   15667     private boolean shouldKeepUninstalledPackageLPr(String packageName) {
   15668         return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
   15669     }
   15670 
   15671     /**
   15672      *  This method is an internal method that could be get invoked either
   15673      *  to delete an installed package or to clean up a failed installation.
   15674      *  After deleting an installed package, a broadcast is sent to notify any
   15675      *  listeners that the package has been removed. For cleaning up a failed
   15676      *  installation, the broadcast is not necessary since the package's
   15677      *  installation wouldn't have sent the initial broadcast either
   15678      *  The key steps in deleting a package are
   15679      *  deleting the package information in internal structures like mPackages,
   15680      *  deleting the packages base directories through installd
   15681      *  updating mSettings to reflect current status
   15682      *  persisting settings for later use
   15683      *  sending a broadcast if necessary
   15684      */
   15685     private int deletePackageX(String packageName, int userId, int deleteFlags) {
   15686         final PackageRemovedInfo info = new PackageRemovedInfo();
   15687         final boolean res;
   15688 
   15689         final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
   15690                 ? UserHandle.USER_ALL : userId;
   15691 
   15692         if (isPackageDeviceAdmin(packageName, removeUser)) {
   15693             Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
   15694             return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
   15695         }
   15696 
   15697         PackageSetting uninstalledPs = null;
   15698 
   15699         // for the uninstall-updates case and restricted profiles, remember the per-
   15700         // user handle installed state
   15701         int[] allUsers;
   15702         synchronized (mPackages) {
   15703             uninstalledPs = mSettings.mPackages.get(packageName);
   15704             if (uninstalledPs == null) {
   15705                 Slog.w(TAG, "Not removing non-existent package " + packageName);
   15706                 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
   15707             }
   15708             allUsers = sUserManager.getUserIds();
   15709             info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
   15710         }
   15711 
   15712         final int freezeUser;
   15713         if (isUpdatedSystemApp(uninstalledPs)
   15714                 && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
   15715             // We're downgrading a system app, which will apply to all users, so
   15716             // freeze them all during the downgrade
   15717             freezeUser = UserHandle.USER_ALL;
   15718         } else {
   15719             freezeUser = removeUser;
   15720         }
   15721 
   15722         synchronized (mInstallLock) {
   15723             if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
   15724             try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
   15725                     deleteFlags, "deletePackageX")) {
   15726                 res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
   15727                         deleteFlags | REMOVE_CHATTY, info, true, null);
   15728             }
   15729             synchronized (mPackages) {
   15730                 if (res) {
   15731                     mEphemeralApplicationRegistry.onPackageUninstalledLPw(uninstalledPs.pkg);
   15732                 }
   15733             }
   15734         }
   15735 
   15736         if (res) {
   15737             final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
   15738             info.sendPackageRemovedBroadcasts(killApp);
   15739             info.sendSystemPackageUpdatedBroadcasts();
   15740             info.sendSystemPackageAppearedBroadcasts();
   15741         }
   15742         // Force a gc here.
   15743         Runtime.getRuntime().gc();
   15744         // Delete the resources here after sending the broadcast to let
   15745         // other processes clean up before deleting resources.
   15746         if (info.args != null) {
   15747             synchronized (mInstallLock) {
   15748                 info.args.doPostDeleteLI(true);
   15749             }
   15750         }
   15751 
   15752         return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
   15753     }
   15754 
   15755     class PackageRemovedInfo {
   15756         String removedPackage;
   15757         int uid = -1;
   15758         int removedAppId = -1;
   15759         int[] origUsers;
   15760         int[] removedUsers = null;
   15761         boolean isRemovedPackageSystemUpdate = false;
   15762         boolean isUpdate;
   15763         boolean dataRemoved;
   15764         boolean removedForAllUsers;
   15765         // Clean up resources deleted packages.
   15766         InstallArgs args = null;
   15767         ArrayMap<String, PackageRemovedInfo> removedChildPackages;
   15768         ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
   15769 
   15770         void sendPackageRemovedBroadcasts(boolean killApp) {
   15771             sendPackageRemovedBroadcastInternal(killApp);
   15772             final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
   15773             for (int i = 0; i < childCount; i++) {
   15774                 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
   15775                 childInfo.sendPackageRemovedBroadcastInternal(killApp);
   15776             }
   15777         }
   15778 
   15779         void sendSystemPackageUpdatedBroadcasts() {
   15780             if (isRemovedPackageSystemUpdate) {
   15781                 sendSystemPackageUpdatedBroadcastsInternal();
   15782                 final int childCount = (removedChildPackages != null)
   15783                         ? removedChildPackages.size() : 0;
   15784                 for (int i = 0; i < childCount; i++) {
   15785                     PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
   15786                     if (childInfo.isRemovedPackageSystemUpdate) {
   15787                         childInfo.sendSystemPackageUpdatedBroadcastsInternal();
   15788                     }
   15789                 }
   15790             }
   15791         }
   15792 
   15793         void sendSystemPackageAppearedBroadcasts() {
   15794             final int packageCount = (appearedChildPackages != null)
   15795                     ? appearedChildPackages.size() : 0;
   15796             for (int i = 0; i < packageCount; i++) {
   15797                 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
   15798                 for (int userId : installedInfo.newUsers) {
   15799                     sendPackageAddedForUser(installedInfo.name, true,
   15800                             UserHandle.getAppId(installedInfo.uid), userId);
   15801                 }
   15802             }
   15803         }
   15804 
   15805         private void sendSystemPackageUpdatedBroadcastsInternal() {
   15806             Bundle extras = new Bundle(2);
   15807             extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
   15808             extras.putBoolean(Intent.EXTRA_REPLACING, true);
   15809             sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage,
   15810                     extras, 0, null, null, null);
   15811             sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage,
   15812                     extras, 0, null, null, null);
   15813             sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
   15814                     null, 0, removedPackage, null, null);
   15815         }
   15816 
   15817         private void sendPackageRemovedBroadcastInternal(boolean killApp) {
   15818             Bundle extras = new Bundle(2);
   15819             extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
   15820             extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
   15821             extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
   15822             if (isUpdate || isRemovedPackageSystemUpdate) {
   15823                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
   15824             }
   15825             extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
   15826             if (removedPackage != null) {
   15827                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
   15828                         extras, 0, null, null, removedUsers);
   15829                 if (dataRemoved && !isRemovedPackageSystemUpdate) {
   15830                     sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
   15831                             removedPackage, extras, 0, null, null, removedUsers);
   15832                 }
   15833             }
   15834             if (removedAppId >= 0) {
   15835                 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, 0, null, null,
   15836                         removedUsers);
   15837             }
   15838         }
   15839     }
   15840 
   15841     /*
   15842      * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
   15843      * flag is not set, the data directory is removed as well.
   15844      * make sure this flag is set for partially installed apps. If not its meaningless to
   15845      * delete a partially installed application.
   15846      */
   15847     private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
   15848             PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
   15849         String packageName = ps.name;
   15850         if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
   15851         // Retrieve object to delete permissions for shared user later on
   15852         final PackageParser.Package deletedPkg;
   15853         final PackageSetting deletedPs;
   15854         // reader
   15855         synchronized (mPackages) {
   15856             deletedPkg = mPackages.get(packageName);
   15857             deletedPs = mSettings.mPackages.get(packageName);
   15858             if (outInfo != null) {
   15859                 outInfo.removedPackage = packageName;
   15860                 outInfo.removedUsers = deletedPs != null
   15861                         ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
   15862                         : null;
   15863             }
   15864         }
   15865 
   15866         removePackageLI(ps, (flags & REMOVE_CHATTY) != 0);
   15867 
   15868         if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
   15869             final PackageParser.Package resolvedPkg;
   15870             if (deletedPkg != null) {
   15871                 resolvedPkg = deletedPkg;
   15872             } else {
   15873                 // We don't have a parsed package when it lives on an ejected
   15874                 // adopted storage device, so fake something together
   15875                 resolvedPkg = new PackageParser.Package(ps.name);
   15876                 resolvedPkg.setVolumeUuid(ps.volumeUuid);
   15877             }
   15878             destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
   15879                     StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
   15880             destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
   15881             if (outInfo != null) {
   15882                 outInfo.dataRemoved = true;
   15883             }
   15884             schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
   15885         }
   15886 
   15887         // writer
   15888         synchronized (mPackages) {
   15889             if (deletedPs != null) {
   15890                 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
   15891                     clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
   15892                     clearDefaultBrowserIfNeeded(packageName);
   15893                     if (outInfo != null) {
   15894                         mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
   15895                         outInfo.removedAppId = mSettings.removePackageLPw(packageName);
   15896                     }
   15897                     updatePermissionsLPw(deletedPs.name, null, 0);
   15898                     if (deletedPs.sharedUser != null) {
   15899                         // Remove permissions associated with package. Since runtime
   15900                         // permissions are per user we have to kill the removed package
   15901                         // or packages running under the shared user of the removed
   15902                         // package if revoking the permissions requested only by the removed
   15903                         // package is successful and this causes a change in gids.
   15904                         for (int userId : UserManagerService.getInstance().getUserIds()) {
   15905                             final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
   15906                                     userId);
   15907                             if (userIdToKill == UserHandle.USER_ALL
   15908                                     || userIdToKill >= UserHandle.USER_SYSTEM) {
   15909                                 // If gids changed for this user, kill all affected packages.
   15910                                 mHandler.post(new Runnable() {
   15911                                     @Override
   15912                                     public void run() {
   15913                                         // This has to happen with no lock held.
   15914                                         killApplication(deletedPs.name, deletedPs.appId,
   15915                                                 KILL_APP_REASON_GIDS_CHANGED);
   15916                                     }
   15917                                 });
   15918                                 break;
   15919                             }
   15920                         }
   15921                     }
   15922                     clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
   15923                 }
   15924                 // make sure to preserve per-user disabled state if this removal was just
   15925                 // a downgrade of a system app to the factory package
   15926                 if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
   15927                     if (DEBUG_REMOVE) {
   15928                         Slog.d(TAG, "Propagating install state across downgrade");
   15929                     }
   15930                     for (int userId : allUserHandles) {
   15931                         final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
   15932                         if (DEBUG_REMOVE) {
   15933                             Slog.d(TAG, "    user " + userId + " => " + installed);
   15934                         }
   15935                         ps.setInstalled(installed, userId);
   15936                     }
   15937                 }
   15938             }
   15939             // can downgrade to reader
   15940             if (writeSettings) {
   15941                 // Save settings now
   15942                 mSettings.writeLPr();
   15943             }
   15944         }
   15945         if (outInfo != null) {
   15946             // A user ID was deleted here. Go through all users and remove it
   15947             // from KeyStore.
   15948             removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId);
   15949         }
   15950     }
   15951 
   15952     static boolean locationIsPrivileged(File path) {
   15953         try {
   15954             final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
   15955                     .getCanonicalPath();
   15956             return path.getCanonicalPath().startsWith(privilegedAppDir);
   15957         } catch (IOException e) {
   15958             Slog.e(TAG, "Unable to access code path " + path);
   15959         }
   15960         return false;
   15961     }
   15962 
   15963     /*
   15964      * Tries to delete system package.
   15965      */
   15966     private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
   15967             PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
   15968             boolean writeSettings) {
   15969         if (deletedPs.parentPackageName != null) {
   15970             Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
   15971             return false;
   15972         }
   15973 
   15974         final boolean applyUserRestrictions
   15975                 = (allUserHandles != null) && (outInfo.origUsers != null);
   15976         final PackageSetting disabledPs;
   15977         // Confirm if the system package has been updated
   15978         // An updated system app can be deleted. This will also have to restore
   15979         // the system pkg from system partition
   15980         // reader
   15981         synchronized (mPackages) {
   15982             disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
   15983         }
   15984 
   15985         if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
   15986                 + " disabledPs=" + disabledPs);
   15987 
   15988         if (disabledPs == null) {
   15989             Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
   15990             return false;
   15991         } else if (DEBUG_REMOVE) {
   15992             Slog.d(TAG, "Deleting system pkg from data partition");
   15993         }
   15994 
   15995         if (DEBUG_REMOVE) {
   15996             if (applyUserRestrictions) {
   15997                 Slog.d(TAG, "Remembering install states:");
   15998                 for (int userId : allUserHandles) {
   15999                     final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
   16000                     Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
   16001                 }
   16002             }
   16003         }
   16004 
   16005         // Delete the updated package
   16006         outInfo.isRemovedPackageSystemUpdate = true;
   16007         if (outInfo.removedChildPackages != null) {
   16008             final int childCount = (deletedPs.childPackageNames != null)
   16009                     ? deletedPs.childPackageNames.size() : 0;
   16010             for (int i = 0; i < childCount; i++) {
   16011                 String childPackageName = deletedPs.childPackageNames.get(i);
   16012                 if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
   16013                         .contains(childPackageName)) {
   16014                     PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
   16015                             childPackageName);
   16016                     if (childInfo != null) {
   16017                         childInfo.isRemovedPackageSystemUpdate = true;
   16018                     }
   16019                 }
   16020             }
   16021         }
   16022 
   16023         if (disabledPs.versionCode < deletedPs.versionCode) {
   16024             // Delete data for downgrades
   16025             flags &= ~PackageManager.DELETE_KEEP_DATA;
   16026         } else {
   16027             // Preserve data by setting flag
   16028             flags |= PackageManager.DELETE_KEEP_DATA;
   16029         }
   16030 
   16031         boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
   16032                 outInfo, writeSettings, disabledPs.pkg);
   16033         if (!ret) {
   16034             return false;
   16035         }
   16036 
   16037         // writer
   16038         synchronized (mPackages) {
   16039             // Reinstate the old system package
   16040             enableSystemPackageLPw(disabledPs.pkg);
   16041             // Remove any native libraries from the upgraded package.
   16042             removeNativeBinariesLI(deletedPs);
   16043         }
   16044 
   16045         // Install the system package
   16046         if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
   16047         int parseFlags = mDefParseFlags
   16048                 | PackageParser.PARSE_MUST_BE_APK
   16049                 | PackageParser.PARSE_IS_SYSTEM
   16050                 | PackageParser.PARSE_IS_SYSTEM_DIR;
   16051         if (locationIsPrivileged(disabledPs.codePath)) {
   16052             parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
   16053         }
   16054 
   16055         final PackageParser.Package newPkg;
   16056         try {
   16057             newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null);
   16058         } catch (PackageManagerException e) {
   16059             Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
   16060                     + e.getMessage());
   16061             return false;
   16062         }
   16063         try {
   16064             // update shared libraries for the newly re-installed system package
   16065             updateSharedLibrariesLPw(newPkg, null);
   16066         } catch (PackageManagerException e) {
   16067             Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
   16068         }
   16069 
   16070         prepareAppDataAfterInstallLIF(newPkg);
   16071 
   16072         // writer
   16073         synchronized (mPackages) {
   16074             PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
   16075 
   16076             // Propagate the permissions state as we do not want to drop on the floor
   16077             // runtime permissions. The update permissions method below will take
   16078             // care of removing obsolete permissions and grant install permissions.
   16079             ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState());
   16080             updatePermissionsLPw(newPkg.packageName, newPkg,
   16081                     UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
   16082 
   16083             if (applyUserRestrictions) {
   16084                 if (DEBUG_REMOVE) {
   16085                     Slog.d(TAG, "Propagating install state across reinstall");
   16086                 }
   16087                 for (int userId : allUserHandles) {
   16088                     final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
   16089                     if (DEBUG_REMOVE) {
   16090                         Slog.d(TAG, "    user " + userId + " => " + installed);
   16091                     }
   16092                     ps.setInstalled(installed, userId);
   16093 
   16094                     mSettings.writeRuntimePermissionsForUserLPr(userId, false);
   16095                 }
   16096                 // Regardless of writeSettings we need to ensure that this restriction
   16097                 // state propagation is persisted
   16098                 mSettings.writeAllUsersPackageRestrictionsLPr();
   16099             }
   16100             // can downgrade to reader here
   16101             if (writeSettings) {
   16102                 mSettings.writeLPr();
   16103             }
   16104         }
   16105         return true;
   16106     }
   16107 
   16108     private boolean deleteInstalledPackageLIF(PackageSetting ps,
   16109             boolean deleteCodeAndResources, int flags, int[] allUserHandles,
   16110             PackageRemovedInfo outInfo, boolean writeSettings,
   16111             PackageParser.Package replacingPackage) {
   16112         synchronized (mPackages) {
   16113             if (outInfo != null) {
   16114                 outInfo.uid = ps.appId;
   16115             }
   16116 
   16117             if (outInfo != null && outInfo.removedChildPackages != null) {
   16118                 final int childCount = (ps.childPackageNames != null)
   16119                         ? ps.childPackageNames.size() : 0;
   16120                 for (int i = 0; i < childCount; i++) {
   16121                     String childPackageName = ps.childPackageNames.get(i);
   16122                     PackageSetting childPs = mSettings.mPackages.get(childPackageName);
   16123                     if (childPs == null) {
   16124                         return false;
   16125                     }
   16126                     PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
   16127                             childPackageName);
   16128                     if (childInfo != null) {
   16129                         childInfo.uid = childPs.appId;
   16130                     }
   16131                 }
   16132             }
   16133         }
   16134 
   16135         // Delete package data from internal structures and also remove data if flag is set
   16136         removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
   16137 
   16138         // Delete the child packages data
   16139         final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
   16140         for (int i = 0; i < childCount; i++) {
   16141             PackageSetting childPs;
   16142             synchronized (mPackages) {
   16143                 childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i));
   16144             }
   16145             if (childPs != null) {
   16146                 PackageRemovedInfo childOutInfo = (outInfo != null
   16147                         && outInfo.removedChildPackages != null)
   16148                         ? outInfo.removedChildPackages.get(childPs.name) : null;
   16149                 final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
   16150                         && (replacingPackage != null
   16151                         && !replacingPackage.hasChildPackage(childPs.name))
   16152                         ? flags & ~DELETE_KEEP_DATA : flags;
   16153                 removePackageDataLIF(childPs, allUserHandles, childOutInfo,
   16154                         deleteFlags, writeSettings);
   16155             }
   16156         }
   16157 
   16158         // Delete application code and resources only for parent packages
   16159         if (ps.parentPackageName == null) {
   16160             if (deleteCodeAndResources && (outInfo != null)) {
   16161                 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
   16162                         ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
   16163                 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
   16164             }
   16165         }
   16166 
   16167         return true;
   16168     }
   16169 
   16170     @Override
   16171     public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
   16172             int userId) {
   16173         mContext.enforceCallingOrSelfPermission(
   16174                 android.Manifest.permission.DELETE_PACKAGES, null);
   16175         synchronized (mPackages) {
   16176             PackageSetting ps = mSettings.mPackages.get(packageName);
   16177             if (ps == null) {
   16178                 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName);
   16179                 return false;
   16180             }
   16181             if (!ps.getInstalled(userId)) {
   16182                 // Can't block uninstall for an app that is not installed or enabled.
   16183                 Log.i(TAG, "Package not installed in set block uninstall " + packageName);
   16184                 return false;
   16185             }
   16186             ps.setBlockUninstall(blockUninstall, userId);
   16187             mSettings.writePackageRestrictionsLPr(userId);
   16188         }
   16189         return true;
   16190     }
   16191 
   16192     @Override
   16193     public boolean getBlockUninstallForUser(String packageName, int userId) {
   16194         synchronized (mPackages) {
   16195             PackageSetting ps = mSettings.mPackages.get(packageName);
   16196             if (ps == null) {
   16197                 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName);
   16198                 return false;
   16199             }
   16200             return ps.getBlockUninstall(userId);
   16201         }
   16202     }
   16203 
   16204     @Override
   16205     public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
   16206         int callingUid = Binder.getCallingUid();
   16207         if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
   16208             throw new SecurityException(
   16209                     "setRequiredForSystemUser can only be run by the system or root");
   16210         }
   16211         synchronized (mPackages) {
   16212             PackageSetting ps = mSettings.mPackages.get(packageName);
   16213             if (ps == null) {
   16214                 Log.w(TAG, "Package doesn't exist: " + packageName);
   16215                 return false;
   16216             }
   16217             if (systemUserApp) {
   16218                 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
   16219             } else {
   16220                 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
   16221             }
   16222             mSettings.writeLPr();
   16223         }
   16224         return true;
   16225     }
   16226 
   16227     /*
   16228      * This method handles package deletion in general
   16229      */
   16230     private boolean deletePackageLIF(String packageName, UserHandle user,
   16231             boolean deleteCodeAndResources, int[] allUserHandles, int flags,
   16232             PackageRemovedInfo outInfo, boolean writeSettings,
   16233             PackageParser.Package replacingPackage) {
   16234         if (packageName == null) {
   16235             Slog.w(TAG, "Attempt to delete null packageName.");
   16236             return false;
   16237         }
   16238 
   16239         if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
   16240 
   16241         PackageSetting ps;
   16242 
   16243         synchronized (mPackages) {
   16244             ps = mSettings.mPackages.get(packageName);
   16245             if (ps == null) {
   16246                 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
   16247                 return false;
   16248             }
   16249 
   16250             if (ps.parentPackageName != null && (!isSystemApp(ps)
   16251                     || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
   16252                 if (DEBUG_REMOVE) {
   16253                     Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
   16254                             + ((user == null) ? UserHandle.USER_ALL : user));
   16255                 }
   16256                 final int removedUserId = (user != null) ? user.getIdentifier()
   16257                         : UserHandle.USER_ALL;
   16258                 if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
   16259                     return false;
   16260                 }
   16261                 markPackageUninstalledForUserLPw(ps, user);
   16262                 scheduleWritePackageRestrictionsLocked(user);
   16263                 return true;
   16264             }
   16265         }
   16266 
   16267         if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
   16268                 && user.getIdentifier() != UserHandle.USER_ALL)) {
   16269             // The caller is asking that the package only be deleted for a single
   16270             // user.  To do this, we just mark its uninstalled state and delete
   16271             // its data. If this is a system app, we only allow this to happen if
   16272             // they have set the special DELETE_SYSTEM_APP which requests different
   16273             // semantics than normal for uninstalling system apps.
   16274             markPackageUninstalledForUserLPw(ps, user);
   16275 
   16276             if (!isSystemApp(ps)) {
   16277                 // Do not uninstall the APK if an app should be cached
   16278                 boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
   16279                 if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
   16280                     // Other user still have this package installed, so all
   16281                     // we need to do is clear this user's data and save that
   16282                     // it is uninstalled.
   16283                     if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
   16284                     if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
   16285                         return false;
   16286                     }
   16287                     scheduleWritePackageRestrictionsLocked(user);
   16288                     return true;
   16289                 } else {
   16290                     // We need to set it back to 'installed' so the uninstall
   16291                     // broadcasts will be sent correctly.
   16292                     if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
   16293                     ps.setInstalled(true, user.getIdentifier());
   16294                 }
   16295             } else {
   16296                 // This is a system app, so we assume that the
   16297                 // other users still have this package installed, so all
   16298                 // we need to do is clear this user's data and save that
   16299                 // it is uninstalled.
   16300                 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
   16301                 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
   16302                     return false;
   16303                 }
   16304                 scheduleWritePackageRestrictionsLocked(user);
   16305                 return true;
   16306             }
   16307         }
   16308 
   16309         // If we are deleting a composite package for all users, keep track
   16310         // of result for each child.
   16311         if (ps.childPackageNames != null && outInfo != null) {
   16312             synchronized (mPackages) {
   16313                 final int childCount = ps.childPackageNames.size();
   16314                 outInfo.removedChildPackages = new ArrayMap<>(childCount);
   16315                 for (int i = 0; i < childCount; i++) {
   16316                     String childPackageName = ps.childPackageNames.get(i);
   16317                     PackageRemovedInfo childInfo = new PackageRemovedInfo();
   16318                     childInfo.removedPackage = childPackageName;
   16319                     outInfo.removedChildPackages.put(childPackageName, childInfo);
   16320                     PackageSetting childPs = mSettings.peekPackageLPr(childPackageName);
   16321                     if (childPs != null) {
   16322                         childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
   16323                     }
   16324                 }
   16325             }
   16326         }
   16327 
   16328         boolean ret = false;
   16329         if (isSystemApp(ps)) {
   16330             if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
   16331             // When an updated system application is deleted we delete the existing resources
   16332             // as well and fall back to existing code in system partition
   16333             ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
   16334         } else {
   16335             if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
   16336             ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
   16337                     outInfo, writeSettings, replacingPackage);
   16338         }
   16339 
   16340         // Take a note whether we deleted the package for all users
   16341         if (outInfo != null) {
   16342             outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
   16343             if (outInfo.removedChildPackages != null) {
   16344                 synchronized (mPackages) {
   16345                     final int childCount = outInfo.removedChildPackages.size();
   16346                     for (int i = 0; i < childCount; i++) {
   16347                         PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
   16348                         if (childInfo != null) {
   16349                             childInfo.removedForAllUsers = mPackages.get(
   16350                                     childInfo.removedPackage) == null;
   16351                         }
   16352                     }
   16353                 }
   16354             }
   16355             // If we uninstalled an update to a system app there may be some
   16356             // child packages that appeared as they are declared in the system
   16357             // app but were not declared in the update.
   16358             if (isSystemApp(ps)) {
   16359                 synchronized (mPackages) {
   16360                     PackageSetting updatedPs = mSettings.peekPackageLPr(ps.name);
   16361                     final int childCount = (updatedPs.childPackageNames != null)
   16362                             ? updatedPs.childPackageNames.size() : 0;
   16363                     for (int i = 0; i < childCount; i++) {
   16364                         String childPackageName = updatedPs.childPackageNames.get(i);
   16365                         if (outInfo.removedChildPackages == null
   16366                                 || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
   16367                             PackageSetting childPs = mSettings.peekPackageLPr(childPackageName);
   16368                             if (childPs == null) {
   16369                                 continue;
   16370                             }
   16371                             PackageInstalledInfo installRes = new PackageInstalledInfo();
   16372                             installRes.name = childPackageName;
   16373                             installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
   16374                             installRes.pkg = mPackages.get(childPackageName);
   16375                             installRes.uid = childPs.pkg.applicationInfo.uid;
   16376                             if (outInfo.appearedChildPackages == null) {
   16377                                 outInfo.appearedChildPackages = new ArrayMap<>();
   16378                             }
   16379                             outInfo.appearedChildPackages.put(childPackageName, installRes);
   16380                         }
   16381                     }
   16382                 }
   16383             }
   16384         }
   16385 
   16386         return ret;
   16387     }
   16388 
   16389     private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
   16390         final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
   16391                 ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
   16392         for (int nextUserId : userIds) {
   16393             if (DEBUG_REMOVE) {
   16394                 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
   16395             }
   16396             ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
   16397                     false /*installed*/, true /*stopped*/, true /*notLaunched*/,
   16398                     false /*hidden*/, false /*suspended*/, null, null, null,
   16399                     false /*blockUninstall*/,
   16400                     ps.readUserState(nextUserId).domainVerificationStatus, 0);
   16401         }
   16402     }
   16403 
   16404     private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
   16405             PackageRemovedInfo outInfo) {
   16406         final PackageParser.Package pkg;
   16407         synchronized (mPackages) {
   16408             pkg = mPackages.get(ps.name);
   16409         }
   16410 
   16411         final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
   16412                 : new int[] {userId};
   16413         for (int nextUserId : userIds) {
   16414             if (DEBUG_REMOVE) {
   16415                 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
   16416                         + nextUserId);
   16417             }
   16418 
   16419             destroyAppDataLIF(pkg, userId,
   16420                     StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
   16421             destroyAppProfilesLIF(pkg, userId);
   16422             removeKeystoreDataIfNeeded(nextUserId, ps.appId);
   16423             schedulePackageCleaning(ps.name, nextUserId, false);
   16424             synchronized (mPackages) {
   16425                 if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
   16426                     scheduleWritePackageRestrictionsLocked(nextUserId);
   16427                 }
   16428                 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
   16429             }
   16430         }
   16431 
   16432         if (outInfo != null) {
   16433             outInfo.removedPackage = ps.name;
   16434             outInfo.removedAppId = ps.appId;
   16435             outInfo.removedUsers = userIds;
   16436         }
   16437 
   16438         return true;
   16439     }
   16440 
   16441     private final class ClearStorageConnection implements ServiceConnection {
   16442         IMediaContainerService mContainerService;
   16443 
   16444         @Override
   16445         public void onServiceConnected(ComponentName name, IBinder service) {
   16446             synchronized (this) {
   16447                 mContainerService = IMediaContainerService.Stub.asInterface(service);
   16448                 notifyAll();
   16449             }
   16450         }
   16451 
   16452         @Override
   16453         public void onServiceDisconnected(ComponentName name) {
   16454         }
   16455     }
   16456 
   16457     private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
   16458         if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
   16459 
   16460         final boolean mounted;
   16461         if (Environment.isExternalStorageEmulated()) {
   16462             mounted = true;
   16463         } else {
   16464             final String status = Environment.getExternalStorageState();
   16465 
   16466             mounted = status.equals(Environment.MEDIA_MOUNTED)
   16467                     || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
   16468         }
   16469 
   16470         if (!mounted) {
   16471             return;
   16472         }
   16473 
   16474         final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
   16475         int[] users;
   16476         if (userId == UserHandle.USER_ALL) {
   16477             users = sUserManager.getUserIds();
   16478         } else {
   16479             users = new int[] { userId };
   16480         }
   16481         final ClearStorageConnection conn = new ClearStorageConnection();
   16482         if (mContext.bindServiceAsUser(
   16483                 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
   16484             try {
   16485                 for (int curUser : users) {
   16486                     long timeout = SystemClock.uptimeMillis() + 5000;
   16487                     synchronized (conn) {
   16488                         long now;
   16489                         while (conn.mContainerService == null &&
   16490                                 (now = SystemClock.uptimeMillis()) < timeout) {
   16491                             try {
   16492                                 conn.wait(timeout - now);
   16493                             } catch (InterruptedException e) {
   16494                             }
   16495                         }
   16496                     }
   16497                     if (conn.mContainerService == null) {
   16498                         return;
   16499                     }
   16500 
   16501                     final UserEnvironment userEnv = new UserEnvironment(curUser);
   16502                     clearDirectory(conn.mContainerService,
   16503                             userEnv.buildExternalStorageAppCacheDirs(packageName));
   16504                     if (allData) {
   16505                         clearDirectory(conn.mContainerService,
   16506                                 userEnv.buildExternalStorageAppDataDirs(packageName));
   16507                         clearDirectory(conn.mContainerService,
   16508                                 userEnv.buildExternalStorageAppMediaDirs(packageName));
   16509                     }
   16510                 }
   16511             } finally {
   16512                 mContext.unbindService(conn);
   16513             }
   16514         }
   16515     }
   16516 
   16517     @Override
   16518     public void clearApplicationProfileData(String packageName) {
   16519         enforceSystemOrRoot("Only the system can clear all profile data");
   16520 
   16521         final PackageParser.Package pkg;
   16522         synchronized (mPackages) {
   16523             pkg = mPackages.get(packageName);
   16524         }
   16525 
   16526         try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
   16527             synchronized (mInstallLock) {
   16528                 clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
   16529                 destroyAppReferenceProfileLeafLIF(pkg, UserHandle.USER_ALL,
   16530                         true /* removeBaseMarker */);
   16531             }
   16532         }
   16533     }
   16534 
   16535     @Override
   16536     public void clearApplicationUserData(final String packageName,
   16537             final IPackageDataObserver observer, final int userId) {
   16538         mContext.enforceCallingOrSelfPermission(
   16539                 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
   16540 
   16541         enforceCrossUserPermission(Binder.getCallingUid(), userId,
   16542                 true /* requireFullPermission */, false /* checkShell */, "clear application data");
   16543 
   16544         if (mProtectedPackages.isPackageDataProtected(userId, packageName)) {
   16545             throw new SecurityException("Cannot clear data for a protected package: "
   16546                     + packageName);
   16547         }
   16548         // Queue up an async operation since the package deletion may take a little while.
   16549         mHandler.post(new Runnable() {
   16550             public void run() {
   16551                 mHandler.removeCallbacks(this);
   16552                 final boolean succeeded;
   16553                 try (PackageFreezer freezer = freezePackage(packageName,
   16554                         "clearApplicationUserData")) {
   16555                     synchronized (mInstallLock) {
   16556                         succeeded = clearApplicationUserDataLIF(packageName, userId);
   16557                     }
   16558                     clearExternalStorageDataSync(packageName, userId, true);
   16559                 }
   16560                 if (succeeded) {
   16561                     // invoke DeviceStorageMonitor's update method to clear any notifications
   16562                     DeviceStorageMonitorInternal dsm = LocalServices
   16563                             .getService(DeviceStorageMonitorInternal.class);
   16564                     if (dsm != null) {
   16565                         dsm.checkMemory();
   16566                     }
   16567                 }
   16568                 if(observer != null) {
   16569                     try {
   16570                         observer.onRemoveCompleted(packageName, succeeded);
   16571                     } catch (RemoteException e) {
   16572                         Log.i(TAG, "Observer no longer exists.");
   16573                     }
   16574                 } //end if observer
   16575             } //end run
   16576         });
   16577     }
   16578 
   16579     private boolean clearApplicationUserDataLIF(String packageName, int userId) {
   16580         if (packageName == null) {
   16581             Slog.w(TAG, "Attempt to delete null packageName.");
   16582             return false;
   16583         }
   16584 
   16585         // Try finding details about the requested package
   16586         PackageParser.Package pkg;
   16587         synchronized (mPackages) {
   16588             pkg = mPackages.get(packageName);
   16589             if (pkg == null) {
   16590                 final PackageSetting ps = mSettings.mPackages.get(packageName);
   16591                 if (ps != null) {
   16592                     pkg = ps.pkg;
   16593                 }
   16594             }
   16595 
   16596             if (pkg == null) {
   16597                 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
   16598                 return false;
   16599             }
   16600 
   16601             PackageSetting ps = (PackageSetting) pkg.mExtras;
   16602             resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
   16603         }
   16604 
   16605         clearAppDataLIF(pkg, userId,
   16606                 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
   16607 
   16608         final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
   16609         removeKeystoreDataIfNeeded(userId, appId);
   16610 
   16611         UserManagerInternal umInternal = getUserManagerInternal();
   16612         final int flags;
   16613         if (umInternal.isUserUnlockingOrUnlocked(userId)) {
   16614             flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
   16615         } else if (umInternal.isUserRunning(userId)) {
   16616             flags = StorageManager.FLAG_STORAGE_DE;
   16617         } else {
   16618             flags = 0;
   16619         }
   16620         prepareAppDataContentsLIF(pkg, userId, flags);
   16621 
   16622         return true;
   16623     }
   16624 
   16625     /**
   16626      * Reverts user permission state changes (permissions and flags) in
   16627      * all packages for a given user.
   16628      *
   16629      * @param userId The device user for which to do a reset.
   16630      */
   16631     private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
   16632         final int packageCount = mPackages.size();
   16633         for (int i = 0; i < packageCount; i++) {
   16634             PackageParser.Package pkg = mPackages.valueAt(i);
   16635             PackageSetting ps = (PackageSetting) pkg.mExtras;
   16636             resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
   16637         }
   16638     }
   16639 
   16640     private void resetNetworkPolicies(int userId) {
   16641         LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
   16642     }
   16643 
   16644     /**
   16645      * Reverts user permission state changes (permissions and flags).
   16646      *
   16647      * @param ps The package for which to reset.
   16648      * @param userId The device user for which to do a reset.
   16649      */
   16650     private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
   16651             final PackageSetting ps, final int userId) {
   16652         if (ps.pkg == null) {
   16653             return;
   16654         }
   16655 
   16656         // These are flags that can change base on user actions.
   16657         final int userSettableMask = FLAG_PERMISSION_USER_SET
   16658                 | FLAG_PERMISSION_USER_FIXED
   16659                 | FLAG_PERMISSION_REVOKE_ON_UPGRADE
   16660                 | FLAG_PERMISSION_REVIEW_REQUIRED;
   16661 
   16662         final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
   16663                 | FLAG_PERMISSION_POLICY_FIXED;
   16664 
   16665         boolean writeInstallPermissions = false;
   16666         boolean writeRuntimePermissions = false;
   16667 
   16668         final int permissionCount = ps.pkg.requestedPermissions.size();
   16669         for (int i = 0; i < permissionCount; i++) {
   16670             String permission = ps.pkg.requestedPermissions.get(i);
   16671 
   16672             BasePermission bp = mSettings.mPermissions.get(permission);
   16673             if (bp == null) {
   16674                 continue;
   16675             }
   16676 
   16677             // If shared user we just reset the state to which only this app contributed.
   16678             if (ps.sharedUser != null) {
   16679                 boolean used = false;
   16680                 final int packageCount = ps.sharedUser.packages.size();
   16681                 for (int j = 0; j < packageCount; j++) {
   16682                     PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
   16683                     if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
   16684                             && pkg.pkg.requestedPermissions.contains(permission)) {
   16685                         used = true;
   16686                         break;
   16687                     }
   16688                 }
   16689                 if (used) {
   16690                     continue;
   16691                 }
   16692             }
   16693 
   16694             PermissionsState permissionsState = ps.getPermissionsState();
   16695 
   16696             final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
   16697 
   16698             // Always clear the user settable flags.
   16699             final boolean hasInstallState = permissionsState.getInstallPermissionState(
   16700                     bp.name) != null;
   16701             // If permission review is enabled and this is a legacy app, mark the
   16702             // permission as requiring a review as this is the initial state.
   16703             int flags = 0;
   16704             if (Build.PERMISSIONS_REVIEW_REQUIRED
   16705                     && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
   16706                 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
   16707             }
   16708             if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
   16709                 if (hasInstallState) {
   16710                     writeInstallPermissions = true;
   16711                 } else {
   16712                     writeRuntimePermissions = true;
   16713                 }
   16714             }
   16715 
   16716             // Below is only runtime permission handling.
   16717             if (!bp.isRuntime()) {
   16718                 continue;
   16719             }
   16720 
   16721             // Never clobber system or policy.
   16722             if ((oldFlags & policyOrSystemFlags) != 0) {
   16723                 continue;
   16724             }
   16725 
   16726             // If this permission was granted by default, make sure it is.
   16727             if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
   16728                 if (permissionsState.grantRuntimePermission(bp, userId)
   16729                         != PERMISSION_OPERATION_FAILURE) {
   16730                     writeRuntimePermissions = true;
   16731                 }
   16732             // If permission review is enabled the permissions for a legacy apps
   16733             // are represented as constantly granted runtime ones, so don't revoke.
   16734             } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
   16735                 // Otherwise, reset the permission.
   16736                 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
   16737                 switch (revokeResult) {
   16738                     case PERMISSION_OPERATION_SUCCESS:
   16739                     case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
   16740                         writeRuntimePermissions = true;
   16741                         final int appId = ps.appId;
   16742                         mHandler.post(new Runnable() {
   16743                             @Override
   16744                             public void run() {
   16745                                 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
   16746                             }
   16747                         });
   16748                     } break;
   16749                 }
   16750             }
   16751         }
   16752 
   16753         // Synchronously write as we are taking permissions away.
   16754         if (writeRuntimePermissions) {
   16755             mSettings.writeRuntimePermissionsForUserLPr(userId, true);
   16756         }
   16757 
   16758         // Synchronously write as we are taking permissions away.
   16759         if (writeInstallPermissions) {
   16760             mSettings.writeLPr();
   16761         }
   16762     }
   16763 
   16764     /**
   16765      * Remove entries from the keystore daemon. Will only remove it if the
   16766      * {@code appId} is valid.
   16767      */
   16768     private static void removeKeystoreDataIfNeeded(int userId, int appId) {
   16769         if (appId < 0) {
   16770             return;
   16771         }
   16772 
   16773         final KeyStore keyStore = KeyStore.getInstance();
   16774         if (keyStore != null) {
   16775             if (userId == UserHandle.USER_ALL) {
   16776                 for (final int individual : sUserManager.getUserIds()) {
   16777                     keyStore.clearUid(UserHandle.getUid(individual, appId));
   16778                 }
   16779             } else {
   16780                 keyStore.clearUid(UserHandle.getUid(userId, appId));
   16781             }
   16782         } else {
   16783             Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
   16784         }
   16785     }
   16786 
   16787     @Override
   16788     public void deleteApplicationCacheFiles(final String packageName,
   16789             final IPackageDataObserver observer) {
   16790         final int userId = UserHandle.getCallingUserId();
   16791         deleteApplicationCacheFilesAsUser(packageName, userId, observer);
   16792     }
   16793 
   16794     @Override
   16795     public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
   16796             final IPackageDataObserver observer) {
   16797         mContext.enforceCallingOrSelfPermission(
   16798                 android.Manifest.permission.DELETE_CACHE_FILES, null);
   16799         enforceCrossUserPermission(Binder.getCallingUid(), userId,
   16800                 /* requireFullPermission= */ true, /* checkShell= */ false,
   16801                 "delete application cache files");
   16802 
   16803         final PackageParser.Package pkg;
   16804         synchronized (mPackages) {
   16805             pkg = mPackages.get(packageName);
   16806         }
   16807 
   16808         // Queue up an async operation since the package deletion may take a little while.
   16809         mHandler.post(new Runnable() {
   16810             public void run() {
   16811                 synchronized (mInstallLock) {
   16812                     final int flags = StorageManager.FLAG_STORAGE_DE
   16813                             | StorageManager.FLAG_STORAGE_CE;
   16814                     // We're only clearing cache files, so we don't care if the
   16815                     // app is unfrozen and still able to run
   16816                     clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
   16817                     clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
   16818                 }
   16819                 clearExternalStorageDataSync(packageName, userId, false);
   16820                 if (observer != null) {
   16821                     try {
   16822                         observer.onRemoveCompleted(packageName, true);
   16823                     } catch (RemoteException e) {
   16824                         Log.i(TAG, "Observer no longer exists.");
   16825                     }
   16826                 }
   16827             }
   16828         });
   16829     }
   16830 
   16831     @Override
   16832     public void getPackageSizeInfo(final String packageName, int userHandle,
   16833             final IPackageStatsObserver observer) {
   16834         mContext.enforceCallingOrSelfPermission(
   16835                 android.Manifest.permission.GET_PACKAGE_SIZE, null);
   16836         if (packageName == null) {
   16837             throw new IllegalArgumentException("Attempt to get size of null packageName");
   16838         }
   16839 
   16840         PackageStats stats = new PackageStats(packageName, userHandle);
   16841 
   16842         /*
   16843          * Queue up an async operation since the package measurement may take a
   16844          * little while.
   16845          */
   16846         Message msg = mHandler.obtainMessage(INIT_COPY);
   16847         msg.obj = new MeasureParams(stats, observer);
   16848         mHandler.sendMessage(msg);
   16849     }
   16850 
   16851     private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
   16852         final PackageSetting ps;
   16853         synchronized (mPackages) {
   16854             ps = mSettings.mPackages.get(packageName);
   16855             if (ps == null) {
   16856                 Slog.w(TAG, "Failed to find settings for " + packageName);
   16857                 return false;
   16858             }
   16859         }
   16860         try {
   16861             mInstaller.getAppSize(ps.volumeUuid, packageName, userId,
   16862                     StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE,
   16863                     ps.getCeDataInode(userId), ps.codePathString, stats);
   16864         } catch (InstallerException e) {
   16865             Slog.w(TAG, String.valueOf(e));
   16866             return false;
   16867         }
   16868 
   16869         // For now, ignore code size of packages on system partition
   16870         if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
   16871             stats.codeSize = 0;
   16872         }
   16873 
   16874         return true;
   16875     }
   16876 
   16877     private int getUidTargetSdkVersionLockedLPr(int uid) {
   16878         Object obj = mSettings.getUserIdLPr(uid);
   16879         if (obj instanceof SharedUserSetting) {
   16880             final SharedUserSetting sus = (SharedUserSetting) obj;
   16881             int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
   16882             final Iterator<PackageSetting> it = sus.packages.iterator();
   16883             while (it.hasNext()) {
   16884                 final PackageSetting ps = it.next();
   16885                 if (ps.pkg != null) {
   16886                     int v = ps.pkg.applicationInfo.targetSdkVersion;
   16887                     if (v < vers) vers = v;
   16888                 }
   16889             }
   16890             return vers;
   16891         } else if (obj instanceof PackageSetting) {
   16892             final PackageSetting ps = (PackageSetting) obj;
   16893             if (ps.pkg != null) {
   16894                 return ps.pkg.applicationInfo.targetSdkVersion;
   16895             }
   16896         }
   16897         return Build.VERSION_CODES.CUR_DEVELOPMENT;
   16898     }
   16899 
   16900     @Override
   16901     public void addPreferredActivity(IntentFilter filter, int match,
   16902             ComponentName[] set, ComponentName activity, int userId) {
   16903         addPreferredActivityInternal(filter, match, set, activity, true, userId,
   16904                 "Adding preferred");
   16905     }
   16906 
   16907     private void addPreferredActivityInternal(IntentFilter filter, int match,
   16908             ComponentName[] set, ComponentName activity, boolean always, int userId,
   16909             String opname) {
   16910         // writer
   16911         int callingUid = Binder.getCallingUid();
   16912         enforceCrossUserPermission(callingUid, userId,
   16913                 true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
   16914         if (filter.countActions() == 0) {
   16915             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
   16916             return;
   16917         }
   16918         synchronized (mPackages) {
   16919             if (mContext.checkCallingOrSelfPermission(
   16920                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
   16921                     != PackageManager.PERMISSION_GRANTED) {
   16922                 if (getUidTargetSdkVersionLockedLPr(callingUid)
   16923                         < Build.VERSION_CODES.FROYO) {
   16924                     Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
   16925                             + callingUid);
   16926                     return;
   16927                 }
   16928                 mContext.enforceCallingOrSelfPermission(
   16929                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
   16930             }
   16931 
   16932             PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
   16933             Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
   16934                     + userId + ":");
   16935             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
   16936             pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
   16937             scheduleWritePackageRestrictionsLocked(userId);
   16938             postPreferredActivityChangedBroadcast(userId);
   16939         }
   16940     }
   16941 
   16942     private void postPreferredActivityChangedBroadcast(int userId) {
   16943         mHandler.post(() -> {
   16944             final IActivityManager am = ActivityManagerNative.getDefault();
   16945             if (am == null) {
   16946                 return;
   16947             }
   16948 
   16949             final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
   16950             intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   16951             try {
   16952                 am.broadcastIntent(null, intent, null, null,
   16953                         0, null, null, null, android.app.AppOpsManager.OP_NONE,
   16954                         null, false, false, userId);
   16955             } catch (RemoteException e) {
   16956             }
   16957         });
   16958     }
   16959 
   16960     @Override
   16961     public void replacePreferredActivity(IntentFilter filter, int match,
   16962             ComponentName[] set, ComponentName activity, int userId) {
   16963         if (filter.countActions() != 1) {
   16964             throw new IllegalArgumentException(
   16965                     "replacePreferredActivity expects filter to have only 1 action.");
   16966         }
   16967         if (filter.countDataAuthorities() != 0
   16968                 || filter.countDataPaths() != 0
   16969                 || filter.countDataSchemes() > 1
   16970                 || filter.countDataTypes() != 0) {
   16971             throw new IllegalArgumentException(
   16972                     "replacePreferredActivity expects filter to have no data authorities, " +
   16973                     "paths, or types; and at most one scheme.");
   16974         }
   16975 
   16976         final int callingUid = Binder.getCallingUid();
   16977         enforceCrossUserPermission(callingUid, userId,
   16978                 true /* requireFullPermission */, false /* checkShell */,
   16979                 "replace preferred activity");
   16980         synchronized (mPackages) {
   16981             if (mContext.checkCallingOrSelfPermission(
   16982                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
   16983                     != PackageManager.PERMISSION_GRANTED) {
   16984                 if (getUidTargetSdkVersionLockedLPr(callingUid)
   16985                         < Build.VERSION_CODES.FROYO) {
   16986                     Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
   16987                             + Binder.getCallingUid());
   16988                     return;
   16989                 }
   16990                 mContext.enforceCallingOrSelfPermission(
   16991                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
   16992             }
   16993 
   16994             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
   16995             if (pir != null) {
   16996                 // Get all of the existing entries that exactly match this filter.
   16997                 ArrayList<PreferredActivity> existing = pir.findFilters(filter);
   16998                 if (existing != null && existing.size() == 1) {
   16999                     PreferredActivity cur = existing.get(0);
   17000                     if (DEBUG_PREFERRED) {
   17001                         Slog.i(TAG, "Checking replace of preferred:");
   17002                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
   17003                         if (!cur.mPref.mAlways) {
   17004                             Slog.i(TAG, "  -- CUR; not mAlways!");
   17005                         } else {
   17006                             Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
   17007                             Slog.i(TAG, "  -- CUR: mSet="
   17008                                     + Arrays.toString(cur.mPref.mSetComponents));
   17009                             Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
   17010                             Slog.i(TAG, "  -- NEW: mMatch="
   17011                                     + (match&IntentFilter.MATCH_CATEGORY_MASK));
   17012                             Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
   17013                             Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
   17014                         }
   17015                     }
   17016                     if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
   17017                             && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
   17018                             && cur.mPref.sameSet(set)) {
   17019                         // Setting the preferred activity to what it happens to be already
   17020                         if (DEBUG_PREFERRED) {
   17021                             Slog.i(TAG, "Replacing with same preferred activity "
   17022                                     + cur.mPref.mShortComponent + " for user "
   17023                                     + userId + ":");
   17024                             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
   17025                         }
   17026                         return;
   17027                     }
   17028                 }
   17029 
   17030                 if (existing != null) {
   17031                     if (DEBUG_PREFERRED) {
   17032                         Slog.i(TAG, existing.size() + " existing preferred matches for:");
   17033                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
   17034                     }
   17035                     for (int i = 0; i < existing.size(); i++) {
   17036                         PreferredActivity pa = existing.get(i);
   17037                         if (DEBUG_PREFERRED) {
   17038                             Slog.i(TAG, "Removing existing preferred activity "
   17039                                     + pa.mPref.mComponent + ":");
   17040                             pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
   17041                         }
   17042                         pir.removeFilter(pa);
   17043                     }
   17044                 }
   17045             }
   17046             addPreferredActivityInternal(filter, match, set, activity, true, userId,
   17047                     "Replacing preferred");
   17048         }
   17049     }
   17050 
   17051     @Override
   17052     public void clearPackagePreferredActivities(String packageName) {
   17053         final int uid = Binder.getCallingUid();
   17054         // writer
   17055         synchronized (mPackages) {
   17056             PackageParser.Package pkg = mPackages.get(packageName);
   17057             if (pkg == null || pkg.applicationInfo.uid != uid) {
   17058                 if (mContext.checkCallingOrSelfPermission(
   17059                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
   17060                         != PackageManager.PERMISSION_GRANTED) {
   17061                     if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
   17062                             < Build.VERSION_CODES.FROYO) {
   17063                         Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
   17064                                 + Binder.getCallingUid());
   17065                         return;
   17066                     }
   17067                     mContext.enforceCallingOrSelfPermission(
   17068                             android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
   17069                 }
   17070             }
   17071 
   17072             int user = UserHandle.getCallingUserId();
   17073             if (clearPackagePreferredActivitiesLPw(packageName, user)) {
   17074                 scheduleWritePackageRestrictionsLocked(user);
   17075             }
   17076         }
   17077     }
   17078 
   17079     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
   17080     boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
   17081         ArrayList<PreferredActivity> removed = null;
   17082         boolean changed = false;
   17083         for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
   17084             final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
   17085             PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
   17086             if (userId != UserHandle.USER_ALL && userId != thisUserId) {
   17087                 continue;
   17088             }
   17089             Iterator<PreferredActivity> it = pir.filterIterator();
   17090             while (it.hasNext()) {
   17091                 PreferredActivity pa = it.next();
   17092                 // Mark entry for removal only if it matches the package name
   17093                 // and the entry is of type "always".
   17094                 if (packageName == null ||
   17095                         (pa.mPref.mComponent.getPackageName().equals(packageName)
   17096                                 && pa.mPref.mAlways)) {
   17097                     if (removed == null) {
   17098                         removed = new ArrayList<PreferredActivity>();
   17099                     }
   17100                     removed.add(pa);
   17101                 }
   17102             }
   17103             if (removed != null) {
   17104                 for (int j=0; j<removed.size(); j++) {
   17105                     PreferredActivity pa = removed.get(j);
   17106                     pir.removeFilter(pa);
   17107                 }
   17108                 changed = true;
   17109             }
   17110         }
   17111         if (changed) {
   17112             postPreferredActivityChangedBroadcast(userId);
   17113         }
   17114         return changed;
   17115     }
   17116 
   17117     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
   17118     private void clearIntentFilterVerificationsLPw(int userId) {
   17119         final int packageCount = mPackages.size();
   17120         for (int i = 0; i < packageCount; i++) {
   17121             PackageParser.Package pkg = mPackages.valueAt(i);
   17122             clearIntentFilterVerificationsLPw(pkg.packageName, userId);
   17123         }
   17124     }
   17125 
   17126     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
   17127     void clearIntentFilterVerificationsLPw(String packageName, int userId) {
   17128         if (userId == UserHandle.USER_ALL) {
   17129             if (mSettings.removeIntentFilterVerificationLPw(packageName,
   17130                     sUserManager.getUserIds())) {
   17131                 for (int oneUserId : sUserManager.getUserIds()) {
   17132                     scheduleWritePackageRestrictionsLocked(oneUserId);
   17133                 }
   17134             }
   17135         } else {
   17136             if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
   17137                 scheduleWritePackageRestrictionsLocked(userId);
   17138             }
   17139         }
   17140     }
   17141 
   17142     void clearDefaultBrowserIfNeeded(String packageName) {
   17143         for (int oneUserId : sUserManager.getUserIds()) {
   17144             String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId);
   17145             if (TextUtils.isEmpty(defaultBrowserPackageName)) continue;
   17146             if (packageName.equals(defaultBrowserPackageName)) {
   17147                 setDefaultBrowserPackageName(null, oneUserId);
   17148             }
   17149         }
   17150     }
   17151 
   17152     @Override
   17153     public void resetApplicationPreferences(int userId) {
   17154         mContext.enforceCallingOrSelfPermission(
   17155                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
   17156         final long identity = Binder.clearCallingIdentity();
   17157         // writer
   17158         try {
   17159             synchronized (mPackages) {
   17160                 clearPackagePreferredActivitiesLPw(null, userId);
   17161                 mSettings.applyDefaultPreferredAppsLPw(this, userId);
   17162                 // TODO: We have to reset the default SMS and Phone. This requires
   17163                 // significant refactoring to keep all default apps in the package
   17164                 // manager (cleaner but more work) or have the services provide
   17165                 // callbacks to the package manager to request a default app reset.
   17166                 applyFactoryDefaultBrowserLPw(userId);
   17167                 clearIntentFilterVerificationsLPw(userId);
   17168                 primeDomainVerificationsLPw(userId);
   17169                 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
   17170                 scheduleWritePackageRestrictionsLocked(userId);
   17171             }
   17172             resetNetworkPolicies(userId);
   17173         } finally {
   17174             Binder.restoreCallingIdentity(identity);
   17175         }
   17176     }
   17177 
   17178     @Override
   17179     public int getPreferredActivities(List<IntentFilter> outFilters,
   17180             List<ComponentName> outActivities, String packageName) {
   17181 
   17182         int num = 0;
   17183         final int userId = UserHandle.getCallingUserId();
   17184         // reader
   17185         synchronized (mPackages) {
   17186             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
   17187             if (pir != null) {
   17188                 final Iterator<PreferredActivity> it = pir.filterIterator();
   17189                 while (it.hasNext()) {
   17190                     final PreferredActivity pa = it.next();
   17191                     if (packageName == null
   17192                             || (pa.mPref.mComponent.getPackageName().equals(packageName)
   17193                                     && pa.mPref.mAlways)) {
   17194                         if (outFilters != null) {
   17195                             outFilters.add(new IntentFilter(pa));
   17196                         }
   17197                         if (outActivities != null) {
   17198                             outActivities.add(pa.mPref.mComponent);
   17199                         }
   17200                     }
   17201                 }
   17202             }
   17203         }
   17204 
   17205         return num;
   17206     }
   17207 
   17208     @Override
   17209     public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
   17210             int userId) {
   17211         int callingUid = Binder.getCallingUid();
   17212         if (callingUid != Process.SYSTEM_UID) {
   17213             throw new SecurityException(
   17214                     "addPersistentPreferredActivity can only be run by the system");
   17215         }
   17216         if (filter.countActions() == 0) {
   17217             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
   17218             return;
   17219         }
   17220         synchronized (mPackages) {
   17221             Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
   17222                     ":");
   17223             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
   17224             mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
   17225                     new PersistentPreferredActivity(filter, activity));
   17226             scheduleWritePackageRestrictionsLocked(userId);
   17227             postPreferredActivityChangedBroadcast(userId);
   17228         }
   17229     }
   17230 
   17231     @Override
   17232     public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
   17233         int callingUid = Binder.getCallingUid();
   17234         if (callingUid != Process.SYSTEM_UID) {
   17235             throw new SecurityException(
   17236                     "clearPackagePersistentPreferredActivities can only be run by the system");
   17237         }
   17238         ArrayList<PersistentPreferredActivity> removed = null;
   17239         boolean changed = false;
   17240         synchronized (mPackages) {
   17241             for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
   17242                 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
   17243                 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
   17244                         .valueAt(i);
   17245                 if (userId != thisUserId) {
   17246                     continue;
   17247                 }
   17248                 Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
   17249                 while (it.hasNext()) {
   17250                     PersistentPreferredActivity ppa = it.next();
   17251                     // Mark entry for removal only if it matches the package name.
   17252                     if (ppa.mComponent.getPackageName().equals(packageName)) {
   17253                         if (removed == null) {
   17254                             removed = new ArrayList<PersistentPreferredActivity>();
   17255                         }
   17256                         removed.add(ppa);
   17257                     }
   17258                 }
   17259                 if (removed != null) {
   17260                     for (int j=0; j<removed.size(); j++) {
   17261                         PersistentPreferredActivity ppa = removed.get(j);
   17262                         ppir.removeFilter(ppa);
   17263                     }
   17264                     changed = true;
   17265                 }
   17266             }
   17267 
   17268             if (changed) {
   17269                 scheduleWritePackageRestrictionsLocked(userId);
   17270                 postPreferredActivityChangedBroadcast(userId);
   17271             }
   17272         }
   17273     }
   17274 
   17275     /**
   17276      * Common machinery for picking apart a restored XML blob and passing
   17277      * it to a caller-supplied functor to be applied to the running system.
   17278      */
   17279     private void restoreFromXml(XmlPullParser parser, int userId,
   17280             String expectedStartTag, BlobXmlRestorer functor)
   17281             throws IOException, XmlPullParserException {
   17282         int type;
   17283         while ((type = parser.next()) != XmlPullParser.START_TAG
   17284                 && type != XmlPullParser.END_DOCUMENT) {
   17285         }
   17286         if (type != XmlPullParser.START_TAG) {
   17287             // oops didn't find a start tag?!
   17288             if (DEBUG_BACKUP) {
   17289                 Slog.e(TAG, "Didn't find start tag during restore");
   17290             }
   17291             return;
   17292         }
   17293 Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
   17294         // this is supposed to be TAG_PREFERRED_BACKUP
   17295         if (!expectedStartTag.equals(parser.getName())) {
   17296             if (DEBUG_BACKUP) {
   17297                 Slog.e(TAG, "Found unexpected tag " + parser.getName());
   17298             }
   17299             return;
   17300         }
   17301 
   17302         // skip interfering stuff, then we're aligned with the backing implementation
   17303         while ((type = parser.next()) == XmlPullParser.TEXT) { }
   17304 Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
   17305         functor.apply(parser, userId);
   17306     }
   17307 
   17308     private interface BlobXmlRestorer {
   17309         public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
   17310     }
   17311 
   17312     /**
   17313      * Non-Binder method, support for the backup/restore mechanism: write the
   17314      * full set of preferred activities in its canonical XML format.  Returns the
   17315      * XML output as a byte array, or null if there is none.
   17316      */
   17317     @Override
   17318     public byte[] getPreferredActivityBackup(int userId) {
   17319         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   17320             throw new SecurityException("Only the system may call getPreferredActivityBackup()");
   17321         }
   17322 
   17323         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
   17324         try {
   17325             final XmlSerializer serializer = new FastXmlSerializer();
   17326             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
   17327             serializer.startDocument(null, true);
   17328             serializer.startTag(null, TAG_PREFERRED_BACKUP);
   17329 
   17330             synchronized (mPackages) {
   17331                 mSettings.writePreferredActivitiesLPr(serializer, userId, true);
   17332             }
   17333 
   17334             serializer.endTag(null, TAG_PREFERRED_BACKUP);
   17335             serializer.endDocument();
   17336             serializer.flush();
   17337         } catch (Exception e) {
   17338             if (DEBUG_BACKUP) {
   17339                 Slog.e(TAG, "Unable to write preferred activities for backup", e);
   17340             }
   17341             return null;
   17342         }
   17343 
   17344         return dataStream.toByteArray();
   17345     }
   17346 
   17347     @Override
   17348     public void restorePreferredActivities(byte[] backup, int userId) {
   17349         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   17350             throw new SecurityException("Only the system may call restorePreferredActivities()");
   17351         }
   17352 
   17353         try {
   17354             final XmlPullParser parser = Xml.newPullParser();
   17355             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
   17356             restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
   17357                     new BlobXmlRestorer() {
   17358                         @Override
   17359                         public void apply(XmlPullParser parser, int userId)
   17360                                 throws XmlPullParserException, IOException {
   17361                             synchronized (mPackages) {
   17362                                 mSettings.readPreferredActivitiesLPw(parser, userId);
   17363                             }
   17364                         }
   17365                     } );
   17366         } catch (Exception e) {
   17367             if (DEBUG_BACKUP) {
   17368                 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
   17369             }
   17370         }
   17371     }
   17372 
   17373     /**
   17374      * Non-Binder method, support for the backup/restore mechanism: write the
   17375      * default browser (etc) settings in its canonical XML format.  Returns the default
   17376      * browser XML representation as a byte array, or null if there is none.
   17377      */
   17378     @Override
   17379     public byte[] getDefaultAppsBackup(int userId) {
   17380         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   17381             throw new SecurityException("Only the system may call getDefaultAppsBackup()");
   17382         }
   17383 
   17384         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
   17385         try {
   17386             final XmlSerializer serializer = new FastXmlSerializer();
   17387             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
   17388             serializer.startDocument(null, true);
   17389             serializer.startTag(null, TAG_DEFAULT_APPS);
   17390 
   17391             synchronized (mPackages) {
   17392                 mSettings.writeDefaultAppsLPr(serializer, userId);
   17393             }
   17394 
   17395             serializer.endTag(null, TAG_DEFAULT_APPS);
   17396             serializer.endDocument();
   17397             serializer.flush();
   17398         } catch (Exception e) {
   17399             if (DEBUG_BACKUP) {
   17400                 Slog.e(TAG, "Unable to write default apps for backup", e);
   17401             }
   17402             return null;
   17403         }
   17404 
   17405         return dataStream.toByteArray();
   17406     }
   17407 
   17408     @Override
   17409     public void restoreDefaultApps(byte[] backup, int userId) {
   17410         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   17411             throw new SecurityException("Only the system may call restoreDefaultApps()");
   17412         }
   17413 
   17414         try {
   17415             final XmlPullParser parser = Xml.newPullParser();
   17416             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
   17417             restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
   17418                     new BlobXmlRestorer() {
   17419                         @Override
   17420                         public void apply(XmlPullParser parser, int userId)
   17421                                 throws XmlPullParserException, IOException {
   17422                             synchronized (mPackages) {
   17423                                 mSettings.readDefaultAppsLPw(parser, userId);
   17424                             }
   17425                         }
   17426                     } );
   17427         } catch (Exception e) {
   17428             if (DEBUG_BACKUP) {
   17429                 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
   17430             }
   17431         }
   17432     }
   17433 
   17434     @Override
   17435     public byte[] getIntentFilterVerificationBackup(int userId) {
   17436         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   17437             throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
   17438         }
   17439 
   17440         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
   17441         try {
   17442             final XmlSerializer serializer = new FastXmlSerializer();
   17443             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
   17444             serializer.startDocument(null, true);
   17445             serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
   17446 
   17447             synchronized (mPackages) {
   17448                 mSettings.writeAllDomainVerificationsLPr(serializer, userId);
   17449             }
   17450 
   17451             serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
   17452             serializer.endDocument();
   17453             serializer.flush();
   17454         } catch (Exception e) {
   17455             if (DEBUG_BACKUP) {
   17456                 Slog.e(TAG, "Unable to write default apps for backup", e);
   17457             }
   17458             return null;
   17459         }
   17460 
   17461         return dataStream.toByteArray();
   17462     }
   17463 
   17464     @Override
   17465     public void restoreIntentFilterVerification(byte[] backup, int userId) {
   17466         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   17467             throw new SecurityException("Only the system may call restorePreferredActivities()");
   17468         }
   17469 
   17470         try {
   17471             final XmlPullParser parser = Xml.newPullParser();
   17472             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
   17473             restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
   17474                     new BlobXmlRestorer() {
   17475                         @Override
   17476                         public void apply(XmlPullParser parser, int userId)
   17477                                 throws XmlPullParserException, IOException {
   17478                             synchronized (mPackages) {
   17479                                 mSettings.readAllDomainVerificationsLPr(parser, userId);
   17480                                 mSettings.writeLPr();
   17481                             }
   17482                         }
   17483                     } );
   17484         } catch (Exception e) {
   17485             if (DEBUG_BACKUP) {
   17486                 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
   17487             }
   17488         }
   17489     }
   17490 
   17491     @Override
   17492     public byte[] getPermissionGrantBackup(int userId) {
   17493         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   17494             throw new SecurityException("Only the system may call getPermissionGrantBackup()");
   17495         }
   17496 
   17497         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
   17498         try {
   17499             final XmlSerializer serializer = new FastXmlSerializer();
   17500             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
   17501             serializer.startDocument(null, true);
   17502             serializer.startTag(null, TAG_PERMISSION_BACKUP);
   17503 
   17504             synchronized (mPackages) {
   17505                 serializeRuntimePermissionGrantsLPr(serializer, userId);
   17506             }
   17507 
   17508             serializer.endTag(null, TAG_PERMISSION_BACKUP);
   17509             serializer.endDocument();
   17510             serializer.flush();
   17511         } catch (Exception e) {
   17512             if (DEBUG_BACKUP) {
   17513                 Slog.e(TAG, "Unable to write default apps for backup", e);
   17514             }
   17515             return null;
   17516         }
   17517 
   17518         return dataStream.toByteArray();
   17519     }
   17520 
   17521     @Override
   17522     public void restorePermissionGrants(byte[] backup, int userId) {
   17523         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   17524             throw new SecurityException("Only the system may call restorePermissionGrants()");
   17525         }
   17526 
   17527         try {
   17528             final XmlPullParser parser = Xml.newPullParser();
   17529             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
   17530             restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
   17531                     new BlobXmlRestorer() {
   17532                         @Override
   17533                         public void apply(XmlPullParser parser, int userId)
   17534                                 throws XmlPullParserException, IOException {
   17535                             synchronized (mPackages) {
   17536                                 processRestoredPermissionGrantsLPr(parser, userId);
   17537                             }
   17538                         }
   17539                     } );
   17540         } catch (Exception e) {
   17541             if (DEBUG_BACKUP) {
   17542                 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
   17543             }
   17544         }
   17545     }
   17546 
   17547     private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
   17548             throws IOException {
   17549         serializer.startTag(null, TAG_ALL_GRANTS);
   17550 
   17551         final int N = mSettings.mPackages.size();
   17552         for (int i = 0; i < N; i++) {
   17553             final PackageSetting ps = mSettings.mPackages.valueAt(i);
   17554             boolean pkgGrantsKnown = false;
   17555 
   17556             PermissionsState packagePerms = ps.getPermissionsState();
   17557 
   17558             for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
   17559                 final int grantFlags = state.getFlags();
   17560                 // only look at grants that are not system/policy fixed
   17561                 if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
   17562                     final boolean isGranted = state.isGranted();
   17563                     // And only back up the user-twiddled state bits
   17564                     if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
   17565                         final String packageName = mSettings.mPackages.keyAt(i);
   17566                         if (!pkgGrantsKnown) {
   17567                             serializer.startTag(null, TAG_GRANT);
   17568                             serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
   17569                             pkgGrantsKnown = true;
   17570                         }
   17571 
   17572                         final boolean userSet =
   17573                                 (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
   17574                         final boolean userFixed =
   17575                                 (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
   17576                         final boolean revoke =
   17577                                 (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
   17578 
   17579                         serializer.startTag(null, TAG_PERMISSION);
   17580                         serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
   17581                         if (isGranted) {
   17582                             serializer.attribute(null, ATTR_IS_GRANTED, "true");
   17583                         }
   17584                         if (userSet) {
   17585                             serializer.attribute(null, ATTR_USER_SET, "true");
   17586                         }
   17587                         if (userFixed) {
   17588                             serializer.attribute(null, ATTR_USER_FIXED, "true");
   17589                         }
   17590                         if (revoke) {
   17591                             serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
   17592                         }
   17593                         serializer.endTag(null, TAG_PERMISSION);
   17594                     }
   17595                 }
   17596             }
   17597 
   17598             if (pkgGrantsKnown) {
   17599                 serializer.endTag(null, TAG_GRANT);
   17600             }
   17601         }
   17602 
   17603         serializer.endTag(null, TAG_ALL_GRANTS);
   17604     }
   17605 
   17606     private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
   17607             throws XmlPullParserException, IOException {
   17608         String pkgName = null;
   17609         int outerDepth = parser.getDepth();
   17610         int type;
   17611         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
   17612                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
   17613             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
   17614                 continue;
   17615             }
   17616 
   17617             final String tagName = parser.getName();
   17618             if (tagName.equals(TAG_GRANT)) {
   17619                 pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
   17620                 if (DEBUG_BACKUP) {
   17621                     Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
   17622                 }
   17623             } else if (tagName.equals(TAG_PERMISSION)) {
   17624 
   17625                 final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
   17626                 final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
   17627 
   17628                 int newFlagSet = 0;
   17629                 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
   17630                     newFlagSet |= FLAG_PERMISSION_USER_SET;
   17631                 }
   17632                 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
   17633                     newFlagSet |= FLAG_PERMISSION_USER_FIXED;
   17634                 }
   17635                 if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
   17636                     newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
   17637                 }
   17638                 if (DEBUG_BACKUP) {
   17639                     Slog.v(TAG, "  + Restoring grant: pkg=" + pkgName + " perm=" + permName
   17640                             + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet));
   17641                 }
   17642                 final PackageSetting ps = mSettings.mPackages.get(pkgName);
   17643                 if (ps != null) {
   17644                     // Already installed so we apply the grant immediately
   17645                     if (DEBUG_BACKUP) {
   17646                         Slog.v(TAG, "        + already installed; applying");
   17647                     }
   17648                     PermissionsState perms = ps.getPermissionsState();
   17649                     BasePermission bp = mSettings.mPermissions.get(permName);
   17650                     if (bp != null) {
   17651                         if (isGranted) {
   17652                             perms.grantRuntimePermission(bp, userId);
   17653                         }
   17654                         if (newFlagSet != 0) {
   17655                             perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
   17656                         }
   17657                     }
   17658                 } else {
   17659                     // Need to wait for post-restore install to apply the grant
   17660                     if (DEBUG_BACKUP) {
   17661                         Slog.v(TAG, "        - not yet installed; saving for later");
   17662                     }
   17663                     mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
   17664                             isGranted, newFlagSet, userId);
   17665                 }
   17666             } else {
   17667                 PackageManagerService.reportSettingsProblem(Log.WARN,
   17668                         "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
   17669                 XmlUtils.skipCurrentTag(parser);
   17670             }
   17671         }
   17672 
   17673         scheduleWriteSettingsLocked();
   17674         mSettings.writeRuntimePermissionsForUserLPr(userId, false);
   17675     }
   17676 
   17677     @Override
   17678     public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
   17679             int sourceUserId, int targetUserId, int flags) {
   17680         mContext.enforceCallingOrSelfPermission(
   17681                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
   17682         int callingUid = Binder.getCallingUid();
   17683         enforceOwnerRights(ownerPackage, callingUid);
   17684         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
   17685         if (intentFilter.countActions() == 0) {
   17686             Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
   17687             return;
   17688         }
   17689         synchronized (mPackages) {
   17690             CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
   17691                     ownerPackage, targetUserId, flags);
   17692             CrossProfileIntentResolver resolver =
   17693                     mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
   17694             ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
   17695             // We have all those whose filter is equal. Now checking if the rest is equal as well.
   17696             if (existing != null) {
   17697                 int size = existing.size();
   17698                 for (int i = 0; i < size; i++) {
   17699                     if (newFilter.equalsIgnoreFilter(existing.get(i))) {
   17700                         return;
   17701                     }
   17702                 }
   17703             }
   17704             resolver.addFilter(newFilter);
   17705             scheduleWritePackageRestrictionsLocked(sourceUserId);
   17706         }
   17707     }
   17708 
   17709     @Override
   17710     public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
   17711         mContext.enforceCallingOrSelfPermission(
   17712                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
   17713         int callingUid = Binder.getCallingUid();
   17714         enforceOwnerRights(ownerPackage, callingUid);
   17715         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
   17716         synchronized (mPackages) {
   17717             CrossProfileIntentResolver resolver =
   17718                     mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
   17719             ArraySet<CrossProfileIntentFilter> set =
   17720                     new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
   17721             for (CrossProfileIntentFilter filter : set) {
   17722                 if (filter.getOwnerPackage().equals(ownerPackage)) {
   17723                     resolver.removeFilter(filter);
   17724                 }
   17725             }
   17726             scheduleWritePackageRestrictionsLocked(sourceUserId);
   17727         }
   17728     }
   17729 
   17730     // Enforcing that callingUid is owning pkg on userId
   17731     private void enforceOwnerRights(String pkg, int callingUid) {
   17732         // The system owns everything.
   17733         if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
   17734             return;
   17735         }
   17736         int callingUserId = UserHandle.getUserId(callingUid);
   17737         PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
   17738         if (pi == null) {
   17739             throw new IllegalArgumentException("Unknown package " + pkg + " on user "
   17740                     + callingUserId);
   17741         }
   17742         if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
   17743             throw new SecurityException("Calling uid " + callingUid
   17744                     + " does not own package " + pkg);
   17745         }
   17746     }
   17747 
   17748     @Override
   17749     public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
   17750         return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
   17751     }
   17752 
   17753     private Intent getHomeIntent() {
   17754         Intent intent = new Intent(Intent.ACTION_MAIN);
   17755         intent.addCategory(Intent.CATEGORY_HOME);
   17756         intent.addCategory(Intent.CATEGORY_DEFAULT);
   17757         return intent;
   17758     }
   17759 
   17760     private IntentFilter getHomeFilter() {
   17761         IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
   17762         filter.addCategory(Intent.CATEGORY_HOME);
   17763         filter.addCategory(Intent.CATEGORY_DEFAULT);
   17764         return filter;
   17765     }
   17766 
   17767     ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
   17768             int userId) {
   17769         Intent intent  = getHomeIntent();
   17770         List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
   17771                 PackageManager.GET_META_DATA, userId);
   17772         ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
   17773                 true, false, false, userId);
   17774 
   17775         allHomeCandidates.clear();
   17776         if (list != null) {
   17777             for (ResolveInfo ri : list) {
   17778                 allHomeCandidates.add(ri);
   17779             }
   17780         }
   17781         return (preferred == null || preferred.activityInfo == null)
   17782                 ? null
   17783                 : new ComponentName(preferred.activityInfo.packageName,
   17784                         preferred.activityInfo.name);
   17785     }
   17786 
   17787     @Override
   17788     public void setHomeActivity(ComponentName comp, int userId) {
   17789         ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
   17790         getHomeActivitiesAsUser(homeActivities, userId);
   17791 
   17792         boolean found = false;
   17793 
   17794         final int size = homeActivities.size();
   17795         final ComponentName[] set = new ComponentName[size];
   17796         for (int i = 0; i < size; i++) {
   17797             final ResolveInfo candidate = homeActivities.get(i);
   17798             final ActivityInfo info = candidate.activityInfo;
   17799             final ComponentName activityName = new ComponentName(info.packageName, info.name);
   17800             set[i] = activityName;
   17801             if (!found && activityName.equals(comp)) {
   17802                 found = true;
   17803             }
   17804         }
   17805         if (!found) {
   17806             throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
   17807                     + userId);
   17808         }
   17809         replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
   17810                 set, comp, userId);
   17811     }
   17812 
   17813     private @Nullable String getSetupWizardPackageName() {
   17814         final Intent intent = new Intent(Intent.ACTION_MAIN);
   17815         intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
   17816 
   17817         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
   17818                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
   17819                         | MATCH_DISABLED_COMPONENTS,
   17820                 UserHandle.myUserId());
   17821         if (matches.size() == 1) {
   17822             return matches.get(0).getComponentInfo().packageName;
   17823         } else {
   17824             Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
   17825                     + ": matches=" + matches);
   17826             return null;
   17827         }
   17828     }
   17829 
   17830     private @Nullable String getStorageManagerPackageName() {
   17831         final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
   17832 
   17833         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
   17834                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
   17835                         | MATCH_DISABLED_COMPONENTS,
   17836                 UserHandle.myUserId());
   17837         if (matches.size() == 1) {
   17838             return matches.get(0).getComponentInfo().packageName;
   17839         } else {
   17840             Slog.e(TAG, "There should probably be exactly one storage manager; found "
   17841                     + matches.size() + ": matches=" + matches);
   17842             return null;
   17843         }
   17844     }
   17845 
   17846     @Override
   17847     public void setApplicationEnabledSetting(String appPackageName,
   17848             int newState, int flags, int userId, String callingPackage) {
   17849         if (!sUserManager.exists(userId)) return;
   17850         if (callingPackage == null) {
   17851             callingPackage = Integer.toString(Binder.getCallingUid());
   17852         }
   17853         setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
   17854     }
   17855 
   17856     @Override
   17857     public void setComponentEnabledSetting(ComponentName componentName,
   17858             int newState, int flags, int userId) {
   17859         if (!sUserManager.exists(userId)) return;
   17860         setEnabledSetting(componentName.getPackageName(),
   17861                 componentName.getClassName(), newState, flags, userId, null);
   17862     }
   17863 
   17864     private void setEnabledSetting(final String packageName, String className, int newState,
   17865             final int flags, int userId, String callingPackage) {
   17866         if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
   17867               || newState == COMPONENT_ENABLED_STATE_ENABLED
   17868               || newState == COMPONENT_ENABLED_STATE_DISABLED
   17869               || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
   17870               || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
   17871             throw new IllegalArgumentException("Invalid new component state: "
   17872                     + newState);
   17873         }
   17874         PackageSetting pkgSetting;
   17875         final int uid = Binder.getCallingUid();
   17876         final int permission;
   17877         if (uid == Process.SYSTEM_UID) {
   17878             permission = PackageManager.PERMISSION_GRANTED;
   17879         } else {
   17880             permission = mContext.checkCallingOrSelfPermission(
   17881                     android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
   17882         }
   17883         enforceCrossUserPermission(uid, userId,
   17884                 false /* requireFullPermission */, true /* checkShell */, "set enabled");
   17885         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
   17886         boolean sendNow = false;
   17887         boolean isApp = (className == null);
   17888         String componentName = isApp ? packageName : className;
   17889         int packageUid = -1;
   17890         ArrayList<String> components;
   17891 
   17892         // writer
   17893         synchronized (mPackages) {
   17894             pkgSetting = mSettings.mPackages.get(packageName);
   17895             if (pkgSetting == null) {
   17896                 if (className == null) {
   17897                     throw new IllegalArgumentException("Unknown package: " + packageName);
   17898                 }
   17899                 throw new IllegalArgumentException(
   17900                         "Unknown component: " + packageName + "/" + className);
   17901             }
   17902         }
   17903 
   17904         // Limit who can change which apps
   17905         if (!UserHandle.isSameApp(uid, pkgSetting.appId)) {
   17906             // Don't allow apps that don't have permission to modify other apps
   17907             if (!allowedByPermission) {
   17908                 throw new SecurityException(
   17909                         "Permission Denial: attempt to change component state from pid="
   17910                         + Binder.getCallingPid()
   17911                         + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
   17912             }
   17913             // Don't allow changing protected packages.
   17914             if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
   17915                 throw new SecurityException("Cannot disable a protected package: " + packageName);
   17916             }
   17917         }
   17918 
   17919         synchronized (mPackages) {
   17920             if (uid == Process.SHELL_UID) {
   17921                 // Shell can only change whole packages between ENABLED and DISABLED_USER states
   17922                 int oldState = pkgSetting.getEnabled(userId);
   17923                 if (className == null
   17924                     &&
   17925                     (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
   17926                      || oldState == COMPONENT_ENABLED_STATE_DEFAULT
   17927                      || oldState == COMPONENT_ENABLED_STATE_ENABLED)
   17928                     &&
   17929                     (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
   17930                      || newState == COMPONENT_ENABLED_STATE_DEFAULT
   17931                      || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
   17932                     // ok
   17933                 } else {
   17934                     throw new SecurityException(
   17935                             "Shell cannot change component state for " + packageName + "/"
   17936                             + className + " to " + newState);
   17937                 }
   17938             }
   17939             if (className == null) {
   17940                 // We're dealing with an application/package level state change
   17941                 if (pkgSetting.getEnabled(userId) == newState) {
   17942                     // Nothing to do
   17943                     return;
   17944                 }
   17945                 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
   17946                     || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
   17947                     // Don't care about who enables an app.
   17948                     callingPackage = null;
   17949                 }
   17950                 pkgSetting.setEnabled(newState, userId, callingPackage);
   17951                 // pkgSetting.pkg.mSetEnabled = newState;
   17952             } else {
   17953                 // We're dealing with a component level state change
   17954                 // First, verify that this is a valid class name.
   17955                 PackageParser.Package pkg = pkgSetting.pkg;
   17956                 if (pkg == null || !pkg.hasComponentClassName(className)) {
   17957                     if (pkg != null &&
   17958                             pkg.applicationInfo.targetSdkVersion >=
   17959                                     Build.VERSION_CODES.JELLY_BEAN) {
   17960                         throw new IllegalArgumentException("Component class " + className
   17961                                 + " does not exist in " + packageName);
   17962                     } else {
   17963                         Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
   17964                                 + className + " does not exist in " + packageName);
   17965                     }
   17966                 }
   17967                 switch (newState) {
   17968                 case COMPONENT_ENABLED_STATE_ENABLED:
   17969                     if (!pkgSetting.enableComponentLPw(className, userId)) {
   17970                         return;
   17971                     }
   17972                     break;
   17973                 case COMPONENT_ENABLED_STATE_DISABLED:
   17974                     if (!pkgSetting.disableComponentLPw(className, userId)) {
   17975                         return;
   17976                     }
   17977                     break;
   17978                 case COMPONENT_ENABLED_STATE_DEFAULT:
   17979                     if (!pkgSetting.restoreComponentLPw(className, userId)) {
   17980                         return;
   17981                     }
   17982                     break;
   17983                 default:
   17984                     Slog.e(TAG, "Invalid new component state: " + newState);
   17985                     return;
   17986                 }
   17987             }
   17988             scheduleWritePackageRestrictionsLocked(userId);
   17989             components = mPendingBroadcasts.get(userId, packageName);
   17990             final boolean newPackage = components == null;
   17991             if (newPackage) {
   17992                 components = new ArrayList<String>();
   17993             }
   17994             if (!components.contains(componentName)) {
   17995                 components.add(componentName);
   17996             }
   17997             if ((flags&PackageManager.DONT_KILL_APP) == 0) {
   17998                 sendNow = true;
   17999                 // Purge entry from pending broadcast list if another one exists already
   18000                 // since we are sending one right away.
   18001                 mPendingBroadcasts.remove(userId, packageName);
   18002             } else {
   18003                 if (newPackage) {
   18004                     mPendingBroadcasts.put(userId, packageName, components);
   18005                 }
   18006                 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
   18007                     // Schedule a message
   18008                     mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
   18009                 }
   18010             }
   18011         }
   18012 
   18013         long callingId = Binder.clearCallingIdentity();
   18014         try {
   18015             if (sendNow) {
   18016                 packageUid = UserHandle.getUid(userId, pkgSetting.appId);
   18017                 sendPackageChangedBroadcast(packageName,
   18018                         (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
   18019             }
   18020         } finally {
   18021             Binder.restoreCallingIdentity(callingId);
   18022         }
   18023     }
   18024 
   18025     @Override
   18026     public void flushPackageRestrictionsAsUser(int userId) {
   18027         if (!sUserManager.exists(userId)) {
   18028             return;
   18029         }
   18030         enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
   18031                 false /* checkShell */, "flushPackageRestrictions");
   18032         synchronized (mPackages) {
   18033             mSettings.writePackageRestrictionsLPr(userId);
   18034             mDirtyUsers.remove(userId);
   18035             if (mDirtyUsers.isEmpty()) {
   18036                 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
   18037             }
   18038         }
   18039     }
   18040 
   18041     private void sendPackageChangedBroadcast(String packageName,
   18042             boolean killFlag, ArrayList<String> componentNames, int packageUid) {
   18043         if (DEBUG_INSTALL)
   18044             Log.v(TAG, "Sending package changed: package=" + packageName + " components="
   18045                     + componentNames);
   18046         Bundle extras = new Bundle(4);
   18047         extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
   18048         String nameList[] = new String[componentNames.size()];
   18049         componentNames.toArray(nameList);
   18050         extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
   18051         extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
   18052         extras.putInt(Intent.EXTRA_UID, packageUid);
   18053         // If this is not reporting a change of the overall package, then only send it
   18054         // to registered receivers.  We don't want to launch a swath of apps for every
   18055         // little component state change.
   18056         final int flags = !componentNames.contains(packageName)
   18057                 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
   18058         sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
   18059                 new int[] {UserHandle.getUserId(packageUid)});
   18060     }
   18061 
   18062     @Override
   18063     public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
   18064         if (!sUserManager.exists(userId)) return;
   18065         final int uid = Binder.getCallingUid();
   18066         final int permission = mContext.checkCallingOrSelfPermission(
   18067                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
   18068         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
   18069         enforceCrossUserPermission(uid, userId,
   18070                 true /* requireFullPermission */, true /* checkShell */, "stop package");
   18071         // writer
   18072         synchronized (mPackages) {
   18073             if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
   18074                     allowedByPermission, uid, userId)) {
   18075                 scheduleWritePackageRestrictionsLocked(userId);
   18076             }
   18077         }
   18078     }
   18079 
   18080     @Override
   18081     public String getInstallerPackageName(String packageName) {
   18082         // reader
   18083         synchronized (mPackages) {
   18084             return mSettings.getInstallerPackageNameLPr(packageName);
   18085         }
   18086     }
   18087 
   18088     public boolean isOrphaned(String packageName) {
   18089         // reader
   18090         synchronized (mPackages) {
   18091             return mSettings.isOrphaned(packageName);
   18092         }
   18093     }
   18094 
   18095     @Override
   18096     public int getApplicationEnabledSetting(String packageName, int userId) {
   18097         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
   18098         int uid = Binder.getCallingUid();
   18099         enforceCrossUserPermission(uid, userId,
   18100                 false /* requireFullPermission */, false /* checkShell */, "get enabled");
   18101         // reader
   18102         synchronized (mPackages) {
   18103             return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
   18104         }
   18105     }
   18106 
   18107     @Override
   18108     public int getComponentEnabledSetting(ComponentName componentName, int userId) {
   18109         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
   18110         int uid = Binder.getCallingUid();
   18111         enforceCrossUserPermission(uid, userId,
   18112                 false /* requireFullPermission */, false /* checkShell */, "get component enabled");
   18113         // reader
   18114         synchronized (mPackages) {
   18115             return mSettings.getComponentEnabledSettingLPr(componentName, userId);
   18116         }
   18117     }
   18118 
   18119     @Override
   18120     public void enterSafeMode() {
   18121         enforceSystemOrRoot("Only the system can request entering safe mode");
   18122 
   18123         if (!mSystemReady) {
   18124             mSafeMode = true;
   18125         }
   18126     }
   18127 
   18128     @Override
   18129     public void systemReady() {
   18130         mSystemReady = true;
   18131 
   18132         // Disable any carrier apps. We do this very early in boot to prevent the apps from being
   18133         // disabled after already being started.
   18134         CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
   18135                 mContext.getContentResolver(), UserHandle.USER_SYSTEM);
   18136 
   18137         // Read the compatibilty setting when the system is ready.
   18138         boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
   18139                 mContext.getContentResolver(),
   18140                 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
   18141         PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
   18142         if (DEBUG_SETTINGS) {
   18143             Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
   18144         }
   18145 
   18146         int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
   18147 
   18148         synchronized (mPackages) {
   18149             // Verify that all of the preferred activity components actually
   18150             // exist.  It is possible for applications to be updated and at
   18151             // that point remove a previously declared activity component that
   18152             // had been set as a preferred activity.  We try to clean this up
   18153             // the next time we encounter that preferred activity, but it is
   18154             // possible for the user flow to never be able to return to that
   18155             // situation so here we do a sanity check to make sure we haven't
   18156             // left any junk around.
   18157             ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
   18158             for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
   18159                 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
   18160                 removed.clear();
   18161                 for (PreferredActivity pa : pir.filterSet()) {
   18162                     if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
   18163                         removed.add(pa);
   18164                     }
   18165                 }
   18166                 if (removed.size() > 0) {
   18167                     for (int r=0; r<removed.size(); r++) {
   18168                         PreferredActivity pa = removed.get(r);
   18169                         Slog.w(TAG, "Removing dangling preferred activity: "
   18170                                 + pa.mPref.mComponent);
   18171                         pir.removeFilter(pa);
   18172                     }
   18173                     mSettings.writePackageRestrictionsLPr(
   18174                             mSettings.mPreferredActivities.keyAt(i));
   18175                 }
   18176             }
   18177 
   18178             for (int userId : UserManagerService.getInstance().getUserIds()) {
   18179                 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
   18180                     grantPermissionsUserIds = ArrayUtils.appendInt(
   18181                             grantPermissionsUserIds, userId);
   18182                 }
   18183             }
   18184         }
   18185         sUserManager.systemReady();
   18186 
   18187         // If we upgraded grant all default permissions before kicking off.
   18188         for (int userId : grantPermissionsUserIds) {
   18189             mDefaultPermissionPolicy.grantDefaultPermissions(userId);
   18190         }
   18191 
   18192         // If we did not grant default permissions, we preload from this the
   18193         // default permission exceptions lazily to ensure we don't hit the
   18194         // disk on a new user creation.
   18195         if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
   18196             mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
   18197         }
   18198 
   18199         // Kick off any messages waiting for system ready
   18200         if (mPostSystemReadyMessages != null) {
   18201             for (Message msg : mPostSystemReadyMessages) {
   18202                 msg.sendToTarget();
   18203             }
   18204             mPostSystemReadyMessages = null;
   18205         }
   18206 
   18207         // Watch for external volumes that come and go over time
   18208         final StorageManager storage = mContext.getSystemService(StorageManager.class);
   18209         storage.registerListener(mStorageListener);
   18210 
   18211         mInstallerService.systemReady();
   18212         mPackageDexOptimizer.systemReady();
   18213 
   18214         MountServiceInternal mountServiceInternal = LocalServices.getService(
   18215                 MountServiceInternal.class);
   18216         mountServiceInternal.addExternalStoragePolicy(
   18217                 new MountServiceInternal.ExternalStorageMountPolicy() {
   18218             @Override
   18219             public int getMountMode(int uid, String packageName) {
   18220                 if (Process.isIsolated(uid)) {
   18221                     return Zygote.MOUNT_EXTERNAL_NONE;
   18222                 }
   18223                 if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
   18224                     return Zygote.MOUNT_EXTERNAL_DEFAULT;
   18225                 }
   18226                 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
   18227                     return Zygote.MOUNT_EXTERNAL_DEFAULT;
   18228                 }
   18229                 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
   18230                     return Zygote.MOUNT_EXTERNAL_READ;
   18231                 }
   18232                 return Zygote.MOUNT_EXTERNAL_WRITE;
   18233             }
   18234 
   18235             @Override
   18236             public boolean hasExternalStorage(int uid, String packageName) {
   18237                 return true;
   18238             }
   18239         });
   18240 
   18241         // Now that we're mostly running, clean up stale users and apps
   18242         reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
   18243         reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
   18244     }
   18245 
   18246     @Override
   18247     public boolean isSafeMode() {
   18248         return mSafeMode;
   18249     }
   18250 
   18251     @Override
   18252     public boolean hasSystemUidErrors() {
   18253         return mHasSystemUidErrors;
   18254     }
   18255 
   18256     static String arrayToString(int[] array) {
   18257         StringBuffer buf = new StringBuffer(128);
   18258         buf.append('[');
   18259         if (array != null) {
   18260             for (int i=0; i<array.length; i++) {
   18261                 if (i > 0) buf.append(", ");
   18262                 buf.append(array[i]);
   18263             }
   18264         }
   18265         buf.append(']');
   18266         return buf.toString();
   18267     }
   18268 
   18269     static class DumpState {
   18270         public static final int DUMP_LIBS = 1 << 0;
   18271         public static final int DUMP_FEATURES = 1 << 1;
   18272         public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2;
   18273         public static final int DUMP_SERVICE_RESOLVERS = 1 << 3;
   18274         public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4;
   18275         public static final int DUMP_CONTENT_RESOLVERS = 1 << 5;
   18276         public static final int DUMP_PERMISSIONS = 1 << 6;
   18277         public static final int DUMP_PACKAGES = 1 << 7;
   18278         public static final int DUMP_SHARED_USERS = 1 << 8;
   18279         public static final int DUMP_MESSAGES = 1 << 9;
   18280         public static final int DUMP_PROVIDERS = 1 << 10;
   18281         public static final int DUMP_VERIFIERS = 1 << 11;
   18282         public static final int DUMP_PREFERRED = 1 << 12;
   18283         public static final int DUMP_PREFERRED_XML = 1 << 13;
   18284         public static final int DUMP_KEYSETS = 1 << 14;
   18285         public static final int DUMP_VERSION = 1 << 15;
   18286         public static final int DUMP_INSTALLS = 1 << 16;
   18287         public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17;
   18288         public static final int DUMP_DOMAIN_PREFERRED = 1 << 18;
   18289         public static final int DUMP_FROZEN = 1 << 19;
   18290         public static final int DUMP_DEXOPT = 1 << 20;
   18291         public static final int DUMP_COMPILER_STATS = 1 << 21;
   18292 
   18293         public static final int OPTION_SHOW_FILTERS = 1 << 0;
   18294 
   18295         private int mTypes;
   18296 
   18297         private int mOptions;
   18298 
   18299         private boolean mTitlePrinted;
   18300 
   18301         private SharedUserSetting mSharedUser;
   18302 
   18303         public boolean isDumping(int type) {
   18304             if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
   18305                 return true;
   18306             }
   18307 
   18308             return (mTypes & type) != 0;
   18309         }
   18310 
   18311         public void setDump(int type) {
   18312             mTypes |= type;
   18313         }
   18314 
   18315         public boolean isOptionEnabled(int option) {
   18316             return (mOptions & option) != 0;
   18317         }
   18318 
   18319         public void setOptionEnabled(int option) {
   18320             mOptions |= option;
   18321         }
   18322 
   18323         public boolean onTitlePrinted() {
   18324             final boolean printed = mTitlePrinted;
   18325             mTitlePrinted = true;
   18326             return printed;
   18327         }
   18328 
   18329         public boolean getTitlePrinted() {
   18330             return mTitlePrinted;
   18331         }
   18332 
   18333         public void setTitlePrinted(boolean enabled) {
   18334             mTitlePrinted = enabled;
   18335         }
   18336 
   18337         public SharedUserSetting getSharedUser() {
   18338             return mSharedUser;
   18339         }
   18340 
   18341         public void setSharedUser(SharedUserSetting user) {
   18342             mSharedUser = user;
   18343         }
   18344     }
   18345 
   18346     @Override
   18347     public void onShellCommand(FileDescriptor in, FileDescriptor out,
   18348             FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
   18349         (new PackageManagerShellCommand(this)).exec(
   18350                 this, in, out, err, args, resultReceiver);
   18351     }
   18352 
   18353     @Override
   18354     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   18355         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
   18356                 != PackageManager.PERMISSION_GRANTED) {
   18357             pw.println("Permission Denial: can't dump ActivityManager from from pid="
   18358                     + Binder.getCallingPid()
   18359                     + ", uid=" + Binder.getCallingUid()
   18360                     + " without permission "
   18361                     + android.Manifest.permission.DUMP);
   18362             return;
   18363         }
   18364 
   18365         DumpState dumpState = new DumpState();
   18366         boolean fullPreferred = false;
   18367         boolean checkin = false;
   18368 
   18369         String packageName = null;
   18370         ArraySet<String> permissionNames = null;
   18371 
   18372         int opti = 0;
   18373         while (opti < args.length) {
   18374             String opt = args[opti];
   18375             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   18376                 break;
   18377             }
   18378             opti++;
   18379 
   18380             if ("-a".equals(opt)) {
   18381                 // Right now we only know how to print all.
   18382             } else if ("-h".equals(opt)) {
   18383                 pw.println("Package manager dump options:");
   18384                 pw.println("  [-h] [-f] [--checkin] [cmd] ...");
   18385                 pw.println("    --checkin: dump for a checkin");
   18386                 pw.println("    -f: print details of intent filters");
   18387                 pw.println("    -h: print this help");
   18388                 pw.println("  cmd may be one of:");
   18389                 pw.println("    l[ibraries]: list known shared libraries");
   18390                 pw.println("    f[eatures]: list device features");
   18391                 pw.println("    k[eysets]: print known keysets");
   18392                 pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
   18393                 pw.println("    perm[issions]: dump permissions");
   18394                 pw.println("    permission [name ...]: dump declaration and use of given permission");
   18395                 pw.println("    pref[erred]: print preferred package settings");
   18396                 pw.println("    preferred-xml [--full]: print preferred package settings as xml");
   18397                 pw.println("    prov[iders]: dump content providers");
   18398                 pw.println("    p[ackages]: dump installed packages");
   18399                 pw.println("    s[hared-users]: dump shared user IDs");
   18400                 pw.println("    m[essages]: print collected runtime messages");
   18401                 pw.println("    v[erifiers]: print package verifier info");
   18402                 pw.println("    d[omain-preferred-apps]: print domains preferred apps");
   18403                 pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
   18404                 pw.println("    version: print database version info");
   18405                 pw.println("    write: write current settings now");
   18406                 pw.println("    installs: details about install sessions");
   18407                 pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
   18408                 pw.println("    dexopt: dump dexopt state");
   18409                 pw.println("    compiler-stats: dump compiler statistics");
   18410                 pw.println("    <package.name>: info about given package");
   18411                 return;
   18412             } else if ("--checkin".equals(opt)) {
   18413                 checkin = true;
   18414             } else if ("-f".equals(opt)) {
   18415                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
   18416             } else {
   18417                 pw.println("Unknown argument: " + opt + "; use -h for help");
   18418             }
   18419         }
   18420 
   18421         // Is the caller requesting to dump a particular piece of data?
   18422         if (opti < args.length) {
   18423             String cmd = args[opti];
   18424             opti++;
   18425             // Is this a package name?
   18426             if ("android".equals(cmd) || cmd.contains(".")) {
   18427                 packageName = cmd;
   18428                 // When dumping a single package, we always dump all of its
   18429                 // filter information since the amount of data will be reasonable.
   18430                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
   18431             } else if ("check-permission".equals(cmd)) {
   18432                 if (opti >= args.length) {
   18433                     pw.println("Error: check-permission missing permission argument");
   18434                     return;
   18435                 }
   18436                 String perm = args[opti];
   18437                 opti++;
   18438                 if (opti >= args.length) {
   18439                     pw.println("Error: check-permission missing package argument");
   18440                     return;
   18441                 }
   18442                 String pkg = args[opti];
   18443                 opti++;
   18444                 int user = UserHandle.getUserId(Binder.getCallingUid());
   18445                 if (opti < args.length) {
   18446                     try {
   18447                         user = Integer.parseInt(args[opti]);
   18448                     } catch (NumberFormatException e) {
   18449                         pw.println("Error: check-permission user argument is not a number: "
   18450                                 + args[opti]);
   18451                         return;
   18452                     }
   18453                 }
   18454                 pw.println(checkPermission(perm, pkg, user));
   18455                 return;
   18456             } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
   18457                 dumpState.setDump(DumpState.DUMP_LIBS);
   18458             } else if ("f".equals(cmd) || "features".equals(cmd)) {
   18459                 dumpState.setDump(DumpState.DUMP_FEATURES);
   18460             } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
   18461                 if (opti >= args.length) {
   18462                     dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
   18463                             | DumpState.DUMP_SERVICE_RESOLVERS
   18464                             | DumpState.DUMP_RECEIVER_RESOLVERS
   18465                             | DumpState.DUMP_CONTENT_RESOLVERS);
   18466                 } else {
   18467                     while (opti < args.length) {
   18468                         String name = args[opti];
   18469                         if ("a".equals(name) || "activity".equals(name)) {
   18470                             dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
   18471                         } else if ("s".equals(name) || "service".equals(name)) {
   18472                             dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
   18473                         } else if ("r".equals(name) || "receiver".equals(name)) {
   18474                             dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
   18475                         } else if ("c".equals(name) || "content".equals(name)) {
   18476                             dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
   18477                         } else {
   18478                             pw.println("Error: unknown resolver table type: " + name);
   18479                             return;
   18480                         }
   18481                         opti++;
   18482                     }
   18483                 }
   18484             } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
   18485                 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
   18486             } else if ("permission".equals(cmd)) {
   18487                 if (opti >= args.length) {
   18488                     pw.println("Error: permission requires permission name");
   18489                     return;
   18490                 }
   18491                 permissionNames = new ArraySet<>();
   18492                 while (opti < args.length) {
   18493                     permissionNames.add(args[opti]);
   18494                     opti++;
   18495                 }
   18496                 dumpState.setDump(DumpState.DUMP_PERMISSIONS
   18497                         | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
   18498             } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
   18499                 dumpState.setDump(DumpState.DUMP_PREFERRED);
   18500             } else if ("preferred-xml".equals(cmd)) {
   18501                 dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
   18502                 if (opti < args.length && "--full".equals(args[opti])) {
   18503                     fullPreferred = true;
   18504                     opti++;
   18505                 }
   18506             } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
   18507                 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
   18508             } else if ("p".equals(cmd) || "packages".equals(cmd)) {
   18509                 dumpState.setDump(DumpState.DUMP_PACKAGES);
   18510             } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
   18511                 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
   18512             } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
   18513                 dumpState.setDump(DumpState.DUMP_PROVIDERS);
   18514             } else if ("m".equals(cmd) || "messages".equals(cmd)) {
   18515                 dumpState.setDump(DumpState.DUMP_MESSAGES);
   18516             } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
   18517                 dumpState.setDump(DumpState.DUMP_VERIFIERS);
   18518             } else if ("i".equals(cmd) || "ifv".equals(cmd)
   18519                     || "intent-filter-verifiers".equals(cmd)) {
   18520                 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
   18521             } else if ("version".equals(cmd)) {
   18522                 dumpState.setDump(DumpState.DUMP_VERSION);
   18523             } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
   18524                 dumpState.setDump(DumpState.DUMP_KEYSETS);
   18525             } else if ("installs".equals(cmd)) {
   18526                 dumpState.setDump(DumpState.DUMP_INSTALLS);
   18527             } else if ("frozen".equals(cmd)) {
   18528                 dumpState.setDump(DumpState.DUMP_FROZEN);
   18529             } else if ("dexopt".equals(cmd)) {
   18530                 dumpState.setDump(DumpState.DUMP_DEXOPT);
   18531             } else if ("compiler-stats".equals(cmd)) {
   18532                 dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
   18533             } else if ("write".equals(cmd)) {
   18534                 synchronized (mPackages) {
   18535                     mSettings.writeLPr();
   18536                     pw.println("Settings written.");
   18537                     return;
   18538                 }
   18539             }
   18540         }
   18541 
   18542         if (checkin) {
   18543             pw.println("vers,1");
   18544         }
   18545 
   18546         // reader
   18547         synchronized (mPackages) {
   18548             if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
   18549                 if (!checkin) {
   18550                     if (dumpState.onTitlePrinted())
   18551                         pw.println();
   18552                     pw.println("Database versions:");
   18553                     mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
   18554                 }
   18555             }
   18556 
   18557             if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
   18558                 if (!checkin) {
   18559                     if (dumpState.onTitlePrinted())
   18560                         pw.println();
   18561                     pw.println("Verifiers:");
   18562                     pw.print("  Required: ");
   18563                     pw.print(mRequiredVerifierPackage);
   18564                     pw.print(" (uid=");
   18565                     pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
   18566                             UserHandle.USER_SYSTEM));
   18567                     pw.println(")");
   18568                 } else if (mRequiredVerifierPackage != null) {
   18569                     pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
   18570                     pw.print(",");
   18571                     pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
   18572                             UserHandle.USER_SYSTEM));
   18573                 }
   18574             }
   18575 
   18576             if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
   18577                     packageName == null) {
   18578                 if (mIntentFilterVerifierComponent != null) {
   18579                     String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
   18580                     if (!checkin) {
   18581                         if (dumpState.onTitlePrinted())
   18582                             pw.println();
   18583                         pw.println("Intent Filter Verifier:");
   18584                         pw.print("  Using: ");
   18585                         pw.print(verifierPackageName);
   18586                         pw.print(" (uid=");
   18587                         pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
   18588                                 UserHandle.USER_SYSTEM));
   18589                         pw.println(")");
   18590                     } else if (verifierPackageName != null) {
   18591                         pw.print("ifv,"); pw.print(verifierPackageName);
   18592                         pw.print(",");
   18593                         pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
   18594                                 UserHandle.USER_SYSTEM));
   18595                     }
   18596                 } else {
   18597                     pw.println();
   18598                     pw.println("No Intent Filter Verifier available!");
   18599                 }
   18600             }
   18601 
   18602             if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
   18603                 boolean printedHeader = false;
   18604                 final Iterator<String> it = mSharedLibraries.keySet().iterator();
   18605                 while (it.hasNext()) {
   18606                     String name = it.next();
   18607                     SharedLibraryEntry ent = mSharedLibraries.get(name);
   18608                     if (!checkin) {
   18609                         if (!printedHeader) {
   18610                             if (dumpState.onTitlePrinted())
   18611                                 pw.println();
   18612                             pw.println("Libraries:");
   18613                             printedHeader = true;
   18614                         }
   18615                         pw.print("  ");
   18616                     } else {
   18617                         pw.print("lib,");
   18618                     }
   18619                     pw.print(name);
   18620                     if (!checkin) {
   18621                         pw.print(" -> ");
   18622                     }
   18623                     if (ent.path != null) {
   18624                         if (!checkin) {
   18625                             pw.print("(jar) ");
   18626                             pw.print(ent.path);
   18627                         } else {
   18628                             pw.print(",jar,");
   18629                             pw.print(ent.path);
   18630                         }
   18631                     } else {
   18632                         if (!checkin) {
   18633                             pw.print("(apk) ");
   18634                             pw.print(ent.apk);
   18635                         } else {
   18636                             pw.print(",apk,");
   18637                             pw.print(ent.apk);
   18638                         }
   18639                     }
   18640                     pw.println();
   18641                 }
   18642             }
   18643 
   18644             if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
   18645                 if (dumpState.onTitlePrinted())
   18646                     pw.println();
   18647                 if (!checkin) {
   18648                     pw.println("Features:");
   18649                 }
   18650 
   18651                 for (FeatureInfo feat : mAvailableFeatures.values()) {
   18652                     if (checkin) {
   18653                         pw.print("feat,");
   18654                         pw.print(feat.name);
   18655                         pw.print(",");
   18656                         pw.println(feat.version);
   18657                     } else {
   18658                         pw.print("  ");
   18659                         pw.print(feat.name);
   18660                         if (feat.version > 0) {
   18661                             pw.print(" version=");
   18662                             pw.print(feat.version);
   18663                         }
   18664                         pw.println();
   18665                     }
   18666                 }
   18667             }
   18668 
   18669             if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
   18670                 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
   18671                         : "Activity Resolver Table:", "  ", packageName,
   18672                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
   18673                     dumpState.setTitlePrinted(true);
   18674                 }
   18675             }
   18676             if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
   18677                 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
   18678                         : "Receiver Resolver Table:", "  ", packageName,
   18679                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
   18680                     dumpState.setTitlePrinted(true);
   18681                 }
   18682             }
   18683             if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
   18684                 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
   18685                         : "Service Resolver Table:", "  ", packageName,
   18686                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
   18687                     dumpState.setTitlePrinted(true);
   18688                 }
   18689             }
   18690             if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
   18691                 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
   18692                         : "Provider Resolver Table:", "  ", packageName,
   18693                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
   18694                     dumpState.setTitlePrinted(true);
   18695                 }
   18696             }
   18697 
   18698             if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
   18699                 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
   18700                     PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
   18701                     int user = mSettings.mPreferredActivities.keyAt(i);
   18702                     if (pir.dump(pw,
   18703                             dumpState.getTitlePrinted()
   18704                                 ? "\nPreferred Activities User " + user + ":"
   18705                                 : "Preferred Activities User " + user + ":", "  ",
   18706                             packageName, true, false)) {
   18707                         dumpState.setTitlePrinted(true);
   18708                     }
   18709                 }
   18710             }
   18711 
   18712             if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
   18713                 pw.flush();
   18714                 FileOutputStream fout = new FileOutputStream(fd);
   18715                 BufferedOutputStream str = new BufferedOutputStream(fout);
   18716                 XmlSerializer serializer = new FastXmlSerializer();
   18717                 try {
   18718                     serializer.setOutput(str, StandardCharsets.UTF_8.name());
   18719                     serializer.startDocument(null, true);
   18720                     serializer.setFeature(
   18721                             "http://xmlpull.org/v1/doc/features.html#indent-output", true);
   18722                     mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
   18723                     serializer.endDocument();
   18724                     serializer.flush();
   18725                 } catch (IllegalArgumentException e) {
   18726                     pw.println("Failed writing: " + e);
   18727                 } catch (IllegalStateException e) {
   18728                     pw.println("Failed writing: " + e);
   18729                 } catch (IOException e) {
   18730                     pw.println("Failed writing: " + e);
   18731                 }
   18732             }
   18733 
   18734             if (!checkin
   18735                     && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
   18736                     && packageName == null) {
   18737                 pw.println();
   18738                 int count = mSettings.mPackages.size();
   18739                 if (count == 0) {
   18740                     pw.println("No applications!");
   18741                     pw.println();
   18742                 } else {
   18743                     final String prefix = "  ";
   18744                     Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
   18745                     if (allPackageSettings.size() == 0) {
   18746                         pw.println("No domain preferred apps!");
   18747                         pw.println();
   18748                     } else {
   18749                         pw.println("App verification status:");
   18750                         pw.println();
   18751                         count = 0;
   18752                         for (PackageSetting ps : allPackageSettings) {
   18753                             IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
   18754                             if (ivi == null || ivi.getPackageName() == null) continue;
   18755                             pw.println(prefix + "Package: " + ivi.getPackageName());
   18756                             pw.println(prefix + "Domains: " + ivi.getDomainsString());
   18757                             pw.println(prefix + "Status:  " + ivi.getStatusString());
   18758                             pw.println();
   18759                             count++;
   18760                         }
   18761                         if (count == 0) {
   18762                             pw.println(prefix + "No app verification established.");
   18763                             pw.println();
   18764                         }
   18765                         for (int userId : sUserManager.getUserIds()) {
   18766                             pw.println("App linkages for user " + userId + ":");
   18767                             pw.println();
   18768                             count = 0;
   18769                             for (PackageSetting ps : allPackageSettings) {
   18770                                 final long status = ps.getDomainVerificationStatusForUser(userId);
   18771                                 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
   18772                                     continue;
   18773                                 }
   18774                                 pw.println(prefix + "Package: " + ps.name);
   18775                                 pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
   18776                                 String statusStr = IntentFilterVerificationInfo.
   18777                                         getStatusStringFromValue(status);
   18778                                 pw.println(prefix + "Status:  " + statusStr);
   18779                                 pw.println();
   18780                                 count++;
   18781                             }
   18782                             if (count == 0) {
   18783                                 pw.println(prefix + "No configured app linkages.");
   18784                                 pw.println();
   18785                             }
   18786                         }
   18787                     }
   18788                 }
   18789             }
   18790 
   18791             if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
   18792                 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
   18793                 if (packageName == null && permissionNames == null) {
   18794                     for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
   18795                         if (iperm == 0) {
   18796                             if (dumpState.onTitlePrinted())
   18797                                 pw.println();
   18798                             pw.println("AppOp Permissions:");
   18799                         }
   18800                         pw.print("  AppOp Permission ");
   18801                         pw.print(mAppOpPermissionPackages.keyAt(iperm));
   18802                         pw.println(":");
   18803                         ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
   18804                         for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
   18805                             pw.print("    "); pw.println(pkgs.valueAt(ipkg));
   18806                         }
   18807                     }
   18808                 }
   18809             }
   18810 
   18811             if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
   18812                 boolean printedSomething = false;
   18813                 for (PackageParser.Provider p : mProviders.mProviders.values()) {
   18814                     if (packageName != null && !packageName.equals(p.info.packageName)) {
   18815                         continue;
   18816                     }
   18817                     if (!printedSomething) {
   18818                         if (dumpState.onTitlePrinted())
   18819                             pw.println();
   18820                         pw.println("Registered ContentProviders:");
   18821                         printedSomething = true;
   18822                     }
   18823                     pw.print("  "); p.printComponentShortName(pw); pw.println(":");
   18824                     pw.print("    "); pw.println(p.toString());
   18825                 }
   18826                 printedSomething = false;
   18827                 for (Map.Entry<String, PackageParser.Provider> entry :
   18828                         mProvidersByAuthority.entrySet()) {
   18829                     PackageParser.Provider p = entry.getValue();
   18830                     if (packageName != null && !packageName.equals(p.info.packageName)) {
   18831                         continue;
   18832                     }
   18833                     if (!printedSomething) {
   18834                         if (dumpState.onTitlePrinted())
   18835                             pw.println();
   18836                         pw.println("ContentProvider Authorities:");
   18837                         printedSomething = true;
   18838                     }
   18839                     pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
   18840                     pw.print("    "); pw.println(p.toString());
   18841                     if (p.info != null && p.info.applicationInfo != null) {
   18842                         final String appInfo = p.info.applicationInfo.toString();
   18843                         pw.print("      applicationInfo="); pw.println(appInfo);
   18844                     }
   18845                 }
   18846             }
   18847 
   18848             if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
   18849                 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
   18850             }
   18851 
   18852             if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
   18853                 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
   18854             }
   18855 
   18856             if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
   18857                 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
   18858             }
   18859 
   18860             if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
   18861                 mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
   18862             }
   18863 
   18864             if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
   18865                 // XXX should handle packageName != null by dumping only install data that
   18866                 // the given package is involved with.
   18867                 if (dumpState.onTitlePrinted()) pw.println();
   18868                 mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
   18869             }
   18870 
   18871             if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
   18872                 // XXX should handle packageName != null by dumping only install data that
   18873                 // the given package is involved with.
   18874                 if (dumpState.onTitlePrinted()) pw.println();
   18875 
   18876                 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
   18877                 ipw.println();
   18878                 ipw.println("Frozen packages:");
   18879                 ipw.increaseIndent();
   18880                 if (mFrozenPackages.size() == 0) {
   18881                     ipw.println("(none)");
   18882                 } else {
   18883                     for (int i = 0; i < mFrozenPackages.size(); i++) {
   18884                         ipw.println(mFrozenPackages.valueAt(i));
   18885                     }
   18886                 }
   18887                 ipw.decreaseIndent();
   18888             }
   18889 
   18890             if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
   18891                 if (dumpState.onTitlePrinted()) pw.println();
   18892                 dumpDexoptStateLPr(pw, packageName);
   18893             }
   18894 
   18895             if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
   18896                 if (dumpState.onTitlePrinted()) pw.println();
   18897                 dumpCompilerStatsLPr(pw, packageName);
   18898             }
   18899 
   18900             if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
   18901                 if (dumpState.onTitlePrinted()) pw.println();
   18902                 mSettings.dumpReadMessagesLPr(pw, dumpState);
   18903 
   18904                 pw.println();
   18905                 pw.println("Package warning messages:");
   18906                 BufferedReader in = null;
   18907                 String line = null;
   18908                 try {
   18909                     in = new BufferedReader(new FileReader(getSettingsProblemFile()));
   18910                     while ((line = in.readLine()) != null) {
   18911                         if (line.contains("ignored: updated version")) continue;
   18912                         pw.println(line);
   18913                     }
   18914                 } catch (IOException ignored) {
   18915                 } finally {
   18916                     IoUtils.closeQuietly(in);
   18917                 }
   18918             }
   18919 
   18920             if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
   18921                 BufferedReader in = null;
   18922                 String line = null;
   18923                 try {
   18924                     in = new BufferedReader(new FileReader(getSettingsProblemFile()));
   18925                     while ((line = in.readLine()) != null) {
   18926                         if (line.contains("ignored: updated version")) continue;
   18927                         pw.print("msg,");
   18928                         pw.println(line);
   18929                     }
   18930                 } catch (IOException ignored) {
   18931                 } finally {
   18932                     IoUtils.closeQuietly(in);
   18933                 }
   18934             }
   18935         }
   18936     }
   18937 
   18938     private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
   18939         final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
   18940         ipw.println();
   18941         ipw.println("Dexopt state:");
   18942         ipw.increaseIndent();
   18943         Collection<PackageParser.Package> packages = null;
   18944         if (packageName != null) {
   18945             PackageParser.Package targetPackage = mPackages.get(packageName);
   18946             if (targetPackage != null) {
   18947                 packages = Collections.singletonList(targetPackage);
   18948             } else {
   18949                 ipw.println("Unable to find package: " + packageName);
   18950                 return;
   18951             }
   18952         } else {
   18953             packages = mPackages.values();
   18954         }
   18955 
   18956         for (PackageParser.Package pkg : packages) {
   18957             ipw.println("[" + pkg.packageName + "]");
   18958             ipw.increaseIndent();
   18959             mPackageDexOptimizer.dumpDexoptState(ipw, pkg);
   18960             ipw.decreaseIndent();
   18961         }
   18962     }
   18963 
   18964     private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
   18965         final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
   18966         ipw.println();
   18967         ipw.println("Compiler stats:");
   18968         ipw.increaseIndent();
   18969         Collection<PackageParser.Package> packages = null;
   18970         if (packageName != null) {
   18971             PackageParser.Package targetPackage = mPackages.get(packageName);
   18972             if (targetPackage != null) {
   18973                 packages = Collections.singletonList(targetPackage);
   18974             } else {
   18975                 ipw.println("Unable to find package: " + packageName);
   18976                 return;
   18977             }
   18978         } else {
   18979             packages = mPackages.values();
   18980         }
   18981 
   18982         for (PackageParser.Package pkg : packages) {
   18983             ipw.println("[" + pkg.packageName + "]");
   18984             ipw.increaseIndent();
   18985 
   18986             CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
   18987             if (stats == null) {
   18988                 ipw.println("(No recorded stats)");
   18989             } else {
   18990                 stats.dump(ipw);
   18991             }
   18992             ipw.decreaseIndent();
   18993         }
   18994     }
   18995 
   18996     private String dumpDomainString(String packageName) {
   18997         List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
   18998                 .getList();
   18999         List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
   19000 
   19001         ArraySet<String> result = new ArraySet<>();
   19002         if (iviList.size() > 0) {
   19003             for (IntentFilterVerificationInfo ivi : iviList) {
   19004                 for (String host : ivi.getDomains()) {
   19005                     result.add(host);
   19006                 }
   19007             }
   19008         }
   19009         if (filters != null && filters.size() > 0) {
   19010             for (IntentFilter filter : filters) {
   19011                 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
   19012                         && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
   19013                                 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
   19014                     result.addAll(filter.getHostsList());
   19015                 }
   19016             }
   19017         }
   19018 
   19019         StringBuilder sb = new StringBuilder(result.size() * 16);
   19020         for (String domain : result) {
   19021             if (sb.length() > 0) sb.append(" ");
   19022             sb.append(domain);
   19023         }
   19024         return sb.toString();
   19025     }
   19026 
   19027     // ------- apps on sdcard specific code -------
   19028     static final boolean DEBUG_SD_INSTALL = false;
   19029 
   19030     private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
   19031 
   19032     private static final String SD_ENCRYPTION_ALGORITHM = "AES";
   19033 
   19034     private boolean mMediaMounted = false;
   19035 
   19036     static String getEncryptKey() {
   19037         try {
   19038             String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
   19039                     SD_ENCRYPTION_KEYSTORE_NAME);
   19040             if (sdEncKey == null) {
   19041                 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
   19042                         SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
   19043                 if (sdEncKey == null) {
   19044                     Slog.e(TAG, "Failed to create encryption keys");
   19045                     return null;
   19046                 }
   19047             }
   19048             return sdEncKey;
   19049         } catch (NoSuchAlgorithmException nsae) {
   19050             Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
   19051             return null;
   19052         } catch (IOException ioe) {
   19053             Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
   19054             return null;
   19055         }
   19056     }
   19057 
   19058     /*
   19059      * Update media status on PackageManager.
   19060      */
   19061     @Override
   19062     public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
   19063         int callingUid = Binder.getCallingUid();
   19064         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   19065             throw new SecurityException("Media status can only be updated by the system");
   19066         }
   19067         // reader; this apparently protects mMediaMounted, but should probably
   19068         // be a different lock in that case.
   19069         synchronized (mPackages) {
   19070             Log.i(TAG, "Updating external media status from "
   19071                     + (mMediaMounted ? "mounted" : "unmounted") + " to "
   19072                     + (mediaStatus ? "mounted" : "unmounted"));
   19073             if (DEBUG_SD_INSTALL)
   19074                 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
   19075                         + ", mMediaMounted=" + mMediaMounted);
   19076             if (mediaStatus == mMediaMounted) {
   19077                 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
   19078                         : 0, -1);
   19079                 mHandler.sendMessage(msg);
   19080                 return;
   19081             }
   19082             mMediaMounted = mediaStatus;
   19083         }
   19084         // Queue up an async operation since the package installation may take a
   19085         // little while.
   19086         mHandler.post(new Runnable() {
   19087             public void run() {
   19088                 updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
   19089             }
   19090         });
   19091     }
   19092 
   19093     /**
   19094      * Called by MountService when the initial ASECs to scan are available.
   19095      * Should block until all the ASEC containers are finished being scanned.
   19096      */
   19097     public void scanAvailableAsecs() {
   19098         updateExternalMediaStatusInner(true, false, false);
   19099     }
   19100 
   19101     /*
   19102      * Collect information of applications on external media, map them against
   19103      * existing containers and update information based on current mount status.
   19104      * Please note that we always have to report status if reportStatus has been
   19105      * set to true especially when unloading packages.
   19106      */
   19107     private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
   19108             boolean externalStorage) {
   19109         ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
   19110         int[] uidArr = EmptyArray.INT;
   19111 
   19112         final String[] list = PackageHelper.getSecureContainerList();
   19113         if (ArrayUtils.isEmpty(list)) {
   19114             Log.i(TAG, "No secure containers found");
   19115         } else {
   19116             // Process list of secure containers and categorize them
   19117             // as active or stale based on their package internal state.
   19118 
   19119             // reader
   19120             synchronized (mPackages) {
   19121                 for (String cid : list) {
   19122                     // Leave stages untouched for now; installer service owns them
   19123                     if (PackageInstallerService.isStageName(cid)) continue;
   19124 
   19125                     if (DEBUG_SD_INSTALL)
   19126                         Log.i(TAG, "Processing container " + cid);
   19127                     String pkgName = getAsecPackageName(cid);
   19128                     if (pkgName == null) {
   19129                         Slog.i(TAG, "Found stale container " + cid + " with no package name");
   19130                         continue;
   19131                     }
   19132                     if (DEBUG_SD_INSTALL)
   19133                         Log.i(TAG, "Looking for pkg : " + pkgName);
   19134 
   19135                     final PackageSetting ps = mSettings.mPackages.get(pkgName);
   19136                     if (ps == null) {
   19137                         Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
   19138                         continue;
   19139                     }
   19140 
   19141                     /*
   19142                      * Skip packages that are not external if we're unmounting
   19143                      * external storage.
   19144                      */
   19145                     if (externalStorage && !isMounted && !isExternal(ps)) {
   19146                         continue;
   19147                     }
   19148 
   19149                     final AsecInstallArgs args = new AsecInstallArgs(cid,
   19150                             getAppDexInstructionSets(ps), ps.isForwardLocked());
   19151                     // The package status is changed only if the code path
   19152                     // matches between settings and the container id.
   19153                     if (ps.codePathString != null
   19154                             && ps.codePathString.startsWith(args.getCodePath())) {
   19155                         if (DEBUG_SD_INSTALL) {
   19156                             Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
   19157                                     + " at code path: " + ps.codePathString);
   19158                         }
   19159 
   19160                         // We do have a valid package installed on sdcard
   19161                         processCids.put(args, ps.codePathString);
   19162                         final int uid = ps.appId;
   19163                         if (uid != -1) {
   19164                             uidArr = ArrayUtils.appendInt(uidArr, uid);
   19165                         }
   19166                     } else {
   19167                         Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
   19168                                 + ps.codePathString);
   19169                     }
   19170                 }
   19171             }
   19172 
   19173             Arrays.sort(uidArr);
   19174         }
   19175 
   19176         // Process packages with valid entries.
   19177         if (isMounted) {
   19178             if (DEBUG_SD_INSTALL)
   19179                 Log.i(TAG, "Loading packages");
   19180             loadMediaPackages(processCids, uidArr, externalStorage);
   19181             startCleaningPackages();
   19182             mInstallerService.onSecureContainersAvailable();
   19183         } else {
   19184             if (DEBUG_SD_INSTALL)
   19185                 Log.i(TAG, "Unloading packages");
   19186             unloadMediaPackages(processCids, uidArr, reportStatus);
   19187         }
   19188     }
   19189 
   19190     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
   19191             ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
   19192         final int size = infos.size();
   19193         final String[] packageNames = new String[size];
   19194         final int[] packageUids = new int[size];
   19195         for (int i = 0; i < size; i++) {
   19196             final ApplicationInfo info = infos.get(i);
   19197             packageNames[i] = info.packageName;
   19198             packageUids[i] = info.uid;
   19199         }
   19200         sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
   19201                 finishedReceiver);
   19202     }
   19203 
   19204     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
   19205             ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
   19206         sendResourcesChangedBroadcast(mediaStatus, replacing,
   19207                 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
   19208     }
   19209 
   19210     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
   19211             String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
   19212         int size = pkgList.length;
   19213         if (size > 0) {
   19214             // Send broadcasts here
   19215             Bundle extras = new Bundle();
   19216             extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
   19217             if (uidArr != null) {
   19218                 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
   19219             }
   19220             if (replacing) {
   19221                 extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
   19222             }
   19223             String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
   19224                     : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
   19225             sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null);
   19226         }
   19227     }
   19228 
   19229    /*
   19230      * Look at potentially valid container ids from processCids If package
   19231      * information doesn't match the one on record or package scanning fails,
   19232      * the cid is added to list of removeCids. We currently don't delete stale
   19233      * containers.
   19234      */
   19235     private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr,
   19236             boolean externalStorage) {
   19237         ArrayList<String> pkgList = new ArrayList<String>();
   19238         Set<AsecInstallArgs> keys = processCids.keySet();
   19239 
   19240         for (AsecInstallArgs args : keys) {
   19241             String codePath = processCids.get(args);
   19242             if (DEBUG_SD_INSTALL)
   19243                 Log.i(TAG, "Loading container : " + args.cid);
   19244             int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
   19245             try {
   19246                 // Make sure there are no container errors first.
   19247                 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
   19248                     Slog.e(TAG, "Failed to mount cid : " + args.cid
   19249                             + " when installing from sdcard");
   19250                     continue;
   19251                 }
   19252                 // Check code path here.
   19253                 if (codePath == null || !codePath.startsWith(args.getCodePath())) {
   19254                     Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
   19255                             + " does not match one in settings " + codePath);
   19256                     continue;
   19257                 }
   19258                 // Parse package
   19259                 int parseFlags = mDefParseFlags;
   19260                 if (args.isExternalAsec()) {
   19261                     parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
   19262                 }
   19263                 if (args.isFwdLocked()) {
   19264                     parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
   19265                 }
   19266 
   19267                 synchronized (mInstallLock) {
   19268                     PackageParser.Package pkg = null;
   19269                     try {
   19270                         // Sadly we don't know the package name yet to freeze it
   19271                         pkg = scanPackageTracedLI(new File(codePath), parseFlags,
   19272                                 SCAN_IGNORE_FROZEN, 0, null);
   19273                     } catch (PackageManagerException e) {
   19274                         Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
   19275                     }
   19276                     // Scan the package
   19277                     if (pkg != null) {
   19278                         /*
   19279                          * TODO why is the lock being held? doPostInstall is
   19280                          * called in other places without the lock. This needs
   19281                          * to be straightened out.
   19282                          */
   19283                         // writer
   19284                         synchronized (mPackages) {
   19285                             retCode = PackageManager.INSTALL_SUCCEEDED;
   19286                             pkgList.add(pkg.packageName);
   19287                             // Post process args
   19288                             args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
   19289                                     pkg.applicationInfo.uid);
   19290                         }
   19291                     } else {
   19292                         Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
   19293                     }
   19294                 }
   19295 
   19296             } finally {
   19297                 if (retCode != PackageManager.INSTALL_SUCCEEDED) {
   19298                     Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
   19299                 }
   19300             }
   19301         }
   19302         // writer
   19303         synchronized (mPackages) {
   19304             // If the platform SDK has changed since the last time we booted,
   19305             // we need to re-grant app permission to catch any new ones that
   19306             // appear. This is really a hack, and means that apps can in some
   19307             // cases get permissions that the user didn't initially explicitly
   19308             // allow... it would be nice to have some better way to handle
   19309             // this situation.
   19310             final VersionInfo ver = externalStorage ? mSettings.getExternalVersion()
   19311                     : mSettings.getInternalVersion();
   19312             final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL
   19313                     : StorageManager.UUID_PRIVATE_INTERNAL;
   19314 
   19315             int updateFlags = UPDATE_PERMISSIONS_ALL;
   19316             if (ver.sdkVersion != mSdkVersion) {
   19317                 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
   19318                         + mSdkVersion + "; regranting permissions for external");
   19319                 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
   19320             }
   19321             updatePermissionsLPw(null, null, volumeUuid, updateFlags);
   19322 
   19323             // Yay, everything is now upgraded
   19324             ver.forceCurrent();
   19325 
   19326             // can downgrade to reader
   19327             // Persist settings
   19328             mSettings.writeLPr();
   19329         }
   19330         // Send a broadcast to let everyone know we are done processing
   19331         if (pkgList.size() > 0) {
   19332             sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
   19333         }
   19334     }
   19335 
   19336    /*
   19337      * Utility method to unload a list of specified containers
   19338      */
   19339     private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
   19340         // Just unmount all valid containers.
   19341         for (AsecInstallArgs arg : cidArgs) {
   19342             synchronized (mInstallLock) {
   19343                 arg.doPostDeleteLI(false);
   19344            }
   19345        }
   19346    }
   19347 
   19348     /*
   19349      * Unload packages mounted on external media. This involves deleting package
   19350      * data from internal structures, sending broadcasts about disabled packages,
   19351      * gc'ing to free up references, unmounting all secure containers
   19352      * corresponding to packages on external media, and posting a
   19353      * UPDATED_MEDIA_STATUS message if status has been requested. Please note
   19354      * that we always have to post this message if status has been requested no
   19355      * matter what.
   19356      */
   19357     private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
   19358             final boolean reportStatus) {
   19359         if (DEBUG_SD_INSTALL)
   19360             Log.i(TAG, "unloading media packages");
   19361         ArrayList<String> pkgList = new ArrayList<String>();
   19362         ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
   19363         final Set<AsecInstallArgs> keys = processCids.keySet();
   19364         for (AsecInstallArgs args : keys) {
   19365             String pkgName = args.getPackageName();
   19366             if (DEBUG_SD_INSTALL)
   19367                 Log.i(TAG, "Trying to unload pkg : " + pkgName);
   19368             // Delete package internally
   19369             PackageRemovedInfo outInfo = new PackageRemovedInfo();
   19370             synchronized (mInstallLock) {
   19371                 final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
   19372                 final boolean res;
   19373                 try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags,
   19374                         "unloadMediaPackages")) {
   19375                     res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false,
   19376                             null);
   19377                 }
   19378                 if (res) {
   19379                     pkgList.add(pkgName);
   19380                 } else {
   19381                     Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
   19382                     failedList.add(args);
   19383                 }
   19384             }
   19385         }
   19386 
   19387         // reader
   19388         synchronized (mPackages) {
   19389             // We didn't update the settings after removing each package;
   19390             // write them now for all packages.
   19391             mSettings.writeLPr();
   19392         }
   19393 
   19394         // We have to absolutely send UPDATED_MEDIA_STATUS only
   19395         // after confirming that all the receivers processed the ordered
   19396         // broadcast when packages get disabled, force a gc to clean things up.
   19397         // and unload all the containers.
   19398         if (pkgList.size() > 0) {
   19399             sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
   19400                     new IIntentReceiver.Stub() {
   19401                 public void performReceive(Intent intent, int resultCode, String data,
   19402                         Bundle extras, boolean ordered, boolean sticky,
   19403                         int sendingUser) throws RemoteException {
   19404                     Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
   19405                             reportStatus ? 1 : 0, 1, keys);
   19406                     mHandler.sendMessage(msg);
   19407                 }
   19408             });
   19409         } else {
   19410             Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
   19411                     keys);
   19412             mHandler.sendMessage(msg);
   19413         }
   19414     }
   19415 
   19416     private void loadPrivatePackages(final VolumeInfo vol) {
   19417         mHandler.post(new Runnable() {
   19418             @Override
   19419             public void run() {
   19420                 loadPrivatePackagesInner(vol);
   19421             }
   19422         });
   19423     }
   19424 
   19425     private void loadPrivatePackagesInner(VolumeInfo vol) {
   19426         final String volumeUuid = vol.fsUuid;
   19427         if (TextUtils.isEmpty(volumeUuid)) {
   19428             Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
   19429             return;
   19430         }
   19431 
   19432         final ArrayList<PackageFreezer> freezers = new ArrayList<>();
   19433         final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
   19434         final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
   19435 
   19436         final VersionInfo ver;
   19437         final List<PackageSetting> packages;
   19438         synchronized (mPackages) {
   19439             ver = mSettings.findOrCreateVersion(volumeUuid);
   19440             packages = mSettings.getVolumePackagesLPr(volumeUuid);
   19441         }
   19442 
   19443         for (PackageSetting ps : packages) {
   19444             freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
   19445             synchronized (mInstallLock) {
   19446                 final PackageParser.Package pkg;
   19447                 try {
   19448                     pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
   19449                     loaded.add(pkg.applicationInfo);
   19450 
   19451                 } catch (PackageManagerException e) {
   19452                     Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
   19453                 }
   19454 
   19455                 if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
   19456                     clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
   19457                             StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
   19458                                     | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
   19459                 }
   19460             }
   19461         }
   19462 
   19463         // Reconcile app data for all started/unlocked users
   19464         final StorageManager sm = mContext.getSystemService(StorageManager.class);
   19465         final UserManager um = mContext.getSystemService(UserManager.class);
   19466         UserManagerInternal umInternal = getUserManagerInternal();
   19467         for (UserInfo user : um.getUsers()) {
   19468             final int flags;
   19469             if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
   19470                 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
   19471             } else if (umInternal.isUserRunning(user.id)) {
   19472                 flags = StorageManager.FLAG_STORAGE_DE;
   19473             } else {
   19474                 continue;
   19475             }
   19476 
   19477             try {
   19478                 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
   19479                 synchronized (mInstallLock) {
   19480                     reconcileAppsDataLI(volumeUuid, user.id, flags);
   19481                 }
   19482             } catch (IllegalStateException e) {
   19483                 // Device was probably ejected, and we'll process that event momentarily
   19484                 Slog.w(TAG, "Failed to prepare storage: " + e);
   19485             }
   19486         }
   19487 
   19488         synchronized (mPackages) {
   19489             int updateFlags = UPDATE_PERMISSIONS_ALL;
   19490             if (ver.sdkVersion != mSdkVersion) {
   19491                 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
   19492                         + mSdkVersion + "; regranting permissions for " + volumeUuid);
   19493                 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
   19494             }
   19495             updatePermissionsLPw(null, null, volumeUuid, updateFlags);
   19496 
   19497             // Yay, everything is now upgraded
   19498             ver.forceCurrent();
   19499 
   19500             mSettings.writeLPr();
   19501         }
   19502 
   19503         for (PackageFreezer freezer : freezers) {
   19504             freezer.close();
   19505         }
   19506 
   19507         if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
   19508         sendResourcesChangedBroadcast(true, false, loaded, null);
   19509     }
   19510 
   19511     private void unloadPrivatePackages(final VolumeInfo vol) {
   19512         mHandler.post(new Runnable() {
   19513             @Override
   19514             public void run() {
   19515                 unloadPrivatePackagesInner(vol);
   19516             }
   19517         });
   19518     }
   19519 
   19520     private void unloadPrivatePackagesInner(VolumeInfo vol) {
   19521         final String volumeUuid = vol.fsUuid;
   19522         if (TextUtils.isEmpty(volumeUuid)) {
   19523             Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
   19524             return;
   19525         }
   19526 
   19527         final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
   19528         synchronized (mInstallLock) {
   19529         synchronized (mPackages) {
   19530             final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
   19531             for (PackageSetting ps : packages) {
   19532                 if (ps.pkg == null) continue;
   19533 
   19534                 final ApplicationInfo info = ps.pkg.applicationInfo;
   19535                 final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
   19536                 final PackageRemovedInfo outInfo = new PackageRemovedInfo();
   19537 
   19538                 try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
   19539                         "unloadPrivatePackagesInner")) {
   19540                     if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
   19541                             false, null)) {
   19542                         unloaded.add(info);
   19543                     } else {
   19544                         Slog.w(TAG, "Failed to unload " + ps.codePath);
   19545                     }
   19546                 }
   19547 
   19548                 // Try very hard to release any references to this package
   19549                 // so we don't risk the system server being killed due to
   19550                 // open FDs
   19551                 AttributeCache.instance().removePackage(ps.name);
   19552             }
   19553 
   19554             mSettings.writeLPr();
   19555         }
   19556         }
   19557 
   19558         if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
   19559         sendResourcesChangedBroadcast(false, false, unloaded, null);
   19560 
   19561         // Try very hard to release any references to this path so we don't risk
   19562         // the system server being killed due to open FDs
   19563         ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
   19564 
   19565         for (int i = 0; i < 3; i++) {
   19566             System.gc();
   19567             System.runFinalization();
   19568         }
   19569     }
   19570 
   19571     /**
   19572      * Prepare storage areas for given user on all mounted devices.
   19573      */
   19574     void prepareUserData(int userId, int userSerial, int flags) {
   19575         synchronized (mInstallLock) {
   19576             final StorageManager storage = mContext.getSystemService(StorageManager.class);
   19577             for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
   19578                 final String volumeUuid = vol.getFsUuid();
   19579                 prepareUserDataLI(volumeUuid, userId, userSerial, flags, true);
   19580             }
   19581         }
   19582     }
   19583 
   19584     private void prepareUserDataLI(String volumeUuid, int userId, int userSerial, int flags,
   19585             boolean allowRecover) {
   19586         // Prepare storage and verify that serial numbers are consistent; if
   19587         // there's a mismatch we need to destroy to avoid leaking data
   19588         final StorageManager storage = mContext.getSystemService(StorageManager.class);
   19589         try {
   19590             storage.prepareUserStorage(volumeUuid, userId, userSerial, flags);
   19591 
   19592             if ((flags & StorageManager.FLAG_STORAGE_DE) != 0 && !mOnlyCore) {
   19593                 UserManagerService.enforceSerialNumber(
   19594                         Environment.getDataUserDeDirectory(volumeUuid, userId), userSerial);
   19595                 if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) {
   19596                     UserManagerService.enforceSerialNumber(
   19597                             Environment.getDataSystemDeDirectory(userId), userSerial);
   19598                 }
   19599             }
   19600             if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && !mOnlyCore) {
   19601                 UserManagerService.enforceSerialNumber(
   19602                         Environment.getDataUserCeDirectory(volumeUuid, userId), userSerial);
   19603                 if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) {
   19604                     UserManagerService.enforceSerialNumber(
   19605                             Environment.getDataSystemCeDirectory(userId), userSerial);
   19606                 }
   19607             }
   19608 
   19609             synchronized (mInstallLock) {
   19610                 mInstaller.createUserData(volumeUuid, userId, userSerial, flags);
   19611             }
   19612         } catch (Exception e) {
   19613             logCriticalInfo(Log.WARN, "Destroying user " + userId + " on volume " + volumeUuid
   19614                     + " because we failed to prepare: " + e);
   19615             destroyUserDataLI(volumeUuid, userId,
   19616                     StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
   19617 
   19618             if (allowRecover) {
   19619                 // Try one last time; if we fail again we're really in trouble
   19620                 prepareUserDataLI(volumeUuid, userId, userSerial, flags, false);
   19621             }
   19622         }
   19623     }
   19624 
   19625     /**
   19626      * Destroy storage areas for given user on all mounted devices.
   19627      */
   19628     void destroyUserData(int userId, int flags) {
   19629         synchronized (mInstallLock) {
   19630             final StorageManager storage = mContext.getSystemService(StorageManager.class);
   19631             for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
   19632                 final String volumeUuid = vol.getFsUuid();
   19633                 destroyUserDataLI(volumeUuid, userId, flags);
   19634             }
   19635         }
   19636     }
   19637 
   19638     private void destroyUserDataLI(String volumeUuid, int userId, int flags) {
   19639         final StorageManager storage = mContext.getSystemService(StorageManager.class);
   19640         try {
   19641             // Clean up app data, profile data, and media data
   19642             mInstaller.destroyUserData(volumeUuid, userId, flags);
   19643 
   19644             // Clean up system data
   19645             if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) {
   19646                 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
   19647                     FileUtils.deleteContentsAndDir(Environment.getUserSystemDirectory(userId));
   19648                     FileUtils.deleteContentsAndDir(Environment.getDataSystemDeDirectory(userId));
   19649                 }
   19650                 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
   19651                     FileUtils.deleteContentsAndDir(Environment.getDataSystemCeDirectory(userId));
   19652                 }
   19653             }
   19654 
   19655             // Data with special labels is now gone, so finish the job
   19656             storage.destroyUserStorage(volumeUuid, userId, flags);
   19657 
   19658         } catch (Exception e) {
   19659             logCriticalInfo(Log.WARN,
   19660                     "Failed to destroy user " + userId + " on volume " + volumeUuid + ": " + e);
   19661         }
   19662     }
   19663 
   19664     /**
   19665      * Examine all users present on given mounted volume, and destroy data
   19666      * belonging to users that are no longer valid, or whose user ID has been
   19667      * recycled.
   19668      */
   19669     private void reconcileUsers(String volumeUuid) {
   19670         final List<File> files = new ArrayList<>();
   19671         Collections.addAll(files, FileUtils
   19672                 .listFilesOrEmpty(Environment.getDataUserDeDirectory(volumeUuid)));
   19673         Collections.addAll(files, FileUtils
   19674                 .listFilesOrEmpty(Environment.getDataUserCeDirectory(volumeUuid)));
   19675         Collections.addAll(files, FileUtils
   19676                 .listFilesOrEmpty(Environment.getDataSystemDeDirectory()));
   19677         Collections.addAll(files, FileUtils
   19678                 .listFilesOrEmpty(Environment.getDataSystemCeDirectory()));
   19679         for (File file : files) {
   19680             if (!file.isDirectory()) continue;
   19681 
   19682             final int userId;
   19683             final UserInfo info;
   19684             try {
   19685                 userId = Integer.parseInt(file.getName());
   19686                 info = sUserManager.getUserInfo(userId);
   19687             } catch (NumberFormatException e) {
   19688                 Slog.w(TAG, "Invalid user directory " + file);
   19689                 continue;
   19690             }
   19691 
   19692             boolean destroyUser = false;
   19693             if (info == null) {
   19694                 logCriticalInfo(Log.WARN, "Destroying user directory " + file
   19695                         + " because no matching user was found");
   19696                 destroyUser = true;
   19697             } else if (!mOnlyCore) {
   19698                 try {
   19699                     UserManagerService.enforceSerialNumber(file, info.serialNumber);
   19700                 } catch (IOException e) {
   19701                     logCriticalInfo(Log.WARN, "Destroying user directory " + file
   19702                             + " because we failed to enforce serial number: " + e);
   19703                     destroyUser = true;
   19704                 }
   19705             }
   19706 
   19707             if (destroyUser) {
   19708                 synchronized (mInstallLock) {
   19709                     destroyUserDataLI(volumeUuid, userId,
   19710                             StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
   19711                 }
   19712             }
   19713         }
   19714     }
   19715 
   19716     private void assertPackageKnown(String volumeUuid, String packageName)
   19717             throws PackageManagerException {
   19718         synchronized (mPackages) {
   19719             // Normalize package name to handle renamed packages
   19720             packageName = normalizePackageNameLPr(packageName);
   19721 
   19722             final PackageSetting ps = mSettings.mPackages.get(packageName);
   19723             if (ps == null) {
   19724                 throw new PackageManagerException("Package " + packageName + " is unknown");
   19725             } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
   19726                 throw new PackageManagerException(
   19727                         "Package " + packageName + " found on unknown volume " + volumeUuid
   19728                                 + "; expected volume " + ps.volumeUuid);
   19729             }
   19730         }
   19731     }
   19732 
   19733     private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
   19734             throws PackageManagerException {
   19735         synchronized (mPackages) {
   19736             // Normalize package name to handle renamed packages
   19737             packageName = normalizePackageNameLPr(packageName);
   19738 
   19739             final PackageSetting ps = mSettings.mPackages.get(packageName);
   19740             if (ps == null) {
   19741                 throw new PackageManagerException("Package " + packageName + " is unknown");
   19742             } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
   19743                 throw new PackageManagerException(
   19744                         "Package " + packageName + " found on unknown volume " + volumeUuid
   19745                                 + "; expected volume " + ps.volumeUuid);
   19746             } else if (!ps.getInstalled(userId)) {
   19747                 throw new PackageManagerException(
   19748                         "Package " + packageName + " not installed for user " + userId);
   19749             }
   19750         }
   19751     }
   19752 
   19753     /**
   19754      * Examine all apps present on given mounted volume, and destroy apps that
   19755      * aren't expected, either due to uninstallation or reinstallation on
   19756      * another volume.
   19757      */
   19758     private void reconcileApps(String volumeUuid) {
   19759         final File[] files = FileUtils
   19760                 .listFilesOrEmpty(Environment.getDataAppDirectory(volumeUuid));
   19761         for (File file : files) {
   19762             final boolean isPackage = (isApkFile(file) || file.isDirectory())
   19763                     && !PackageInstallerService.isStageName(file.getName());
   19764             if (!isPackage) {
   19765                 // Ignore entries which are not packages
   19766                 continue;
   19767             }
   19768 
   19769             try {
   19770                 final PackageLite pkg = PackageParser.parsePackageLite(file,
   19771                         PackageParser.PARSE_MUST_BE_APK);
   19772                 assertPackageKnown(volumeUuid, pkg.packageName);
   19773 
   19774             } catch (PackageParserException | PackageManagerException e) {
   19775                 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
   19776                 synchronized (mInstallLock) {
   19777                     removeCodePathLI(file);
   19778                 }
   19779             }
   19780         }
   19781     }
   19782 
   19783     /**
   19784      * Reconcile all app data for the given user.
   19785      * <p>
   19786      * Verifies that directories exist and that ownership and labeling is
   19787      * correct for all installed apps on all mounted volumes.
   19788      */
   19789     void reconcileAppsData(int userId, int flags) {
   19790         final StorageManager storage = mContext.getSystemService(StorageManager.class);
   19791         for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
   19792             final String volumeUuid = vol.getFsUuid();
   19793             synchronized (mInstallLock) {
   19794                 reconcileAppsDataLI(volumeUuid, userId, flags);
   19795             }
   19796         }
   19797     }
   19798 
   19799     /**
   19800      * Reconcile all app data on given mounted volume.
   19801      * <p>
   19802      * Destroys app data that isn't expected, either due to uninstallation or
   19803      * reinstallation on another volume.
   19804      * <p>
   19805      * Verifies that directories exist and that ownership and labeling is
   19806      * correct for all installed apps.
   19807      */
   19808     private void reconcileAppsDataLI(String volumeUuid, int userId, int flags) {
   19809         Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
   19810                 + Integer.toHexString(flags));
   19811 
   19812         final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
   19813         final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
   19814 
   19815         // First look for stale data that doesn't belong, and check if things
   19816         // have changed since we did our last restorecon
   19817         if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
   19818             if (StorageManager.isFileEncryptedNativeOrEmulated()
   19819                     && !StorageManager.isUserKeyUnlocked(userId)) {
   19820                 throw new RuntimeException(
   19821                         "Yikes, someone asked us to reconcile CE storage while " + userId
   19822                                 + " was still locked; this would have caused massive data loss!");
   19823             }
   19824 
   19825             final File[] files = FileUtils.listFilesOrEmpty(ceDir);
   19826             for (File file : files) {
   19827                 final String packageName = file.getName();
   19828                 try {
   19829                     assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
   19830                 } catch (PackageManagerException e) {
   19831                     logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
   19832                     try {
   19833                         mInstaller.destroyAppData(volumeUuid, packageName, userId,
   19834                                 StorageManager.FLAG_STORAGE_CE, 0);
   19835                     } catch (InstallerException e2) {
   19836                         logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
   19837                     }
   19838                 }
   19839             }
   19840         }
   19841         if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
   19842             final File[] files = FileUtils.listFilesOrEmpty(deDir);
   19843             for (File file : files) {
   19844                 final String packageName = file.getName();
   19845                 try {
   19846                     assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
   19847                 } catch (PackageManagerException e) {
   19848                     logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
   19849                     try {
   19850                         mInstaller.destroyAppData(volumeUuid, packageName, userId,
   19851                                 StorageManager.FLAG_STORAGE_DE, 0);
   19852                     } catch (InstallerException e2) {
   19853                         logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
   19854                     }
   19855                 }
   19856             }
   19857         }
   19858 
   19859         // Ensure that data directories are ready to roll for all packages
   19860         // installed for this volume and user
   19861         final List<PackageSetting> packages;
   19862         synchronized (mPackages) {
   19863             packages = mSettings.getVolumePackagesLPr(volumeUuid);
   19864         }
   19865         int preparedCount = 0;
   19866         for (PackageSetting ps : packages) {
   19867             final String packageName = ps.name;
   19868             if (ps.pkg == null) {
   19869                 Slog.w(TAG, "Odd, missing scanned package " + packageName);
   19870                 // TODO: might be due to legacy ASEC apps; we should circle back
   19871                 // and reconcile again once they're scanned
   19872                 continue;
   19873             }
   19874 
   19875             if (ps.getInstalled(userId)) {
   19876                 prepareAppDataLIF(ps.pkg, userId, flags);
   19877 
   19878                 if (maybeMigrateAppDataLIF(ps.pkg, userId)) {
   19879                     // We may have just shuffled around app data directories, so
   19880                     // prepare them one more time
   19881                     prepareAppDataLIF(ps.pkg, userId, flags);
   19882                 }
   19883 
   19884                 preparedCount++;
   19885             }
   19886         }
   19887 
   19888         Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
   19889     }
   19890 
   19891     /**
   19892      * Prepare app data for the given app just after it was installed or
   19893      * upgraded. This method carefully only touches users that it's installed
   19894      * for, and it forces a restorecon to handle any seinfo changes.
   19895      * <p>
   19896      * Verifies that directories exist and that ownership and labeling is
   19897      * correct for all installed apps. If there is an ownership mismatch, it
   19898      * will try recovering system apps by wiping data; third-party app data is
   19899      * left intact.
   19900      * <p>
   19901      * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
   19902      */
   19903     private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
   19904         final PackageSetting ps;
   19905         synchronized (mPackages) {
   19906             ps = mSettings.mPackages.get(pkg.packageName);
   19907             mSettings.writeKernelMappingLPr(ps);
   19908         }
   19909 
   19910         final UserManager um = mContext.getSystemService(UserManager.class);
   19911         UserManagerInternal umInternal = getUserManagerInternal();
   19912         for (UserInfo user : um.getUsers()) {
   19913             final int flags;
   19914             if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
   19915                 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
   19916             } else if (umInternal.isUserRunning(user.id)) {
   19917                 flags = StorageManager.FLAG_STORAGE_DE;
   19918             } else {
   19919                 continue;
   19920             }
   19921 
   19922             if (ps.getInstalled(user.id)) {
   19923                 // TODO: when user data is locked, mark that we're still dirty
   19924                 prepareAppDataLIF(pkg, user.id, flags);
   19925             }
   19926         }
   19927     }
   19928 
   19929     /**
   19930      * Prepare app data for the given app.
   19931      * <p>
   19932      * Verifies that directories exist and that ownership and labeling is
   19933      * correct for all installed apps. If there is an ownership mismatch, this
   19934      * will try recovering system apps by wiping data; third-party app data is
   19935      * left intact.
   19936      */
   19937     private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
   19938         if (pkg == null) {
   19939             Slog.wtf(TAG, "Package was null!", new Throwable());
   19940             return;
   19941         }
   19942         prepareAppDataLeafLIF(pkg, userId, flags);
   19943         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
   19944         for (int i = 0; i < childCount; i++) {
   19945             prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
   19946         }
   19947     }
   19948 
   19949     private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
   19950         if (DEBUG_APP_DATA) {
   19951             Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
   19952                     + Integer.toHexString(flags));
   19953         }
   19954 
   19955         final String volumeUuid = pkg.volumeUuid;
   19956         final String packageName = pkg.packageName;
   19957         final ApplicationInfo app = pkg.applicationInfo;
   19958         final int appId = UserHandle.getAppId(app.uid);
   19959 
   19960         Preconditions.checkNotNull(app.seinfo);
   19961 
   19962         try {
   19963             mInstaller.createAppData(volumeUuid, packageName, userId, flags,
   19964                     appId, app.seinfo, app.targetSdkVersion);
   19965         } catch (InstallerException e) {
   19966             if (app.isSystemApp()) {
   19967                 logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
   19968                         + ", but trying to recover: " + e);
   19969                 destroyAppDataLeafLIF(pkg, userId, flags);
   19970                 try {
   19971                     mInstaller.createAppData(volumeUuid, packageName, userId, flags,
   19972                             appId, app.seinfo, app.targetSdkVersion);
   19973                     logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
   19974                 } catch (InstallerException e2) {
   19975                     logCriticalInfo(Log.DEBUG, "Recovery failed!");
   19976                 }
   19977             } else {
   19978                 Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
   19979             }
   19980         }
   19981 
   19982         if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
   19983             try {
   19984                 // CE storage is unlocked right now, so read out the inode and
   19985                 // remember for use later when it's locked
   19986                 // TODO: mark this structure as dirty so we persist it!
   19987                 final long ceDataInode = mInstaller.getAppDataInode(volumeUuid, packageName, userId,
   19988                         StorageManager.FLAG_STORAGE_CE);
   19989                 synchronized (mPackages) {
   19990                     final PackageSetting ps = mSettings.mPackages.get(packageName);
   19991                     if (ps != null) {
   19992                         ps.setCeDataInode(ceDataInode, userId);
   19993                     }
   19994                 }
   19995             } catch (InstallerException e) {
   19996                 Slog.e(TAG, "Failed to find inode for " + packageName + ": " + e);
   19997             }
   19998         }
   19999 
   20000         prepareAppDataContentsLeafLIF(pkg, userId, flags);
   20001     }
   20002 
   20003     private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
   20004         if (pkg == null) {
   20005             Slog.wtf(TAG, "Package was null!", new Throwable());
   20006             return;
   20007         }
   20008         prepareAppDataContentsLeafLIF(pkg, userId, flags);
   20009         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
   20010         for (int i = 0; i < childCount; i++) {
   20011             prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
   20012         }
   20013     }
   20014 
   20015     private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
   20016         final String volumeUuid = pkg.volumeUuid;
   20017         final String packageName = pkg.packageName;
   20018         final ApplicationInfo app = pkg.applicationInfo;
   20019 
   20020         if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
   20021             // Create a native library symlink only if we have native libraries
   20022             // and if the native libraries are 32 bit libraries. We do not provide
   20023             // this symlink for 64 bit libraries.
   20024             if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
   20025                 final String nativeLibPath = app.nativeLibraryDir;
   20026                 try {
   20027                     mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
   20028                             nativeLibPath, userId);
   20029                 } catch (InstallerException e) {
   20030                     Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
   20031                 }
   20032             }
   20033         }
   20034     }
   20035 
   20036     /**
   20037      * For system apps on non-FBE devices, this method migrates any existing
   20038      * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
   20039      * requested by the app.
   20040      */
   20041     private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
   20042         if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated()
   20043                 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
   20044             final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
   20045                     ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
   20046             try {
   20047                 mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
   20048                         storageTarget);
   20049             } catch (InstallerException e) {
   20050                 logCriticalInfo(Log.WARN,
   20051                         "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
   20052             }
   20053             return true;
   20054         } else {
   20055             return false;
   20056         }
   20057     }
   20058 
   20059     public PackageFreezer freezePackage(String packageName, String killReason) {
   20060         return freezePackage(packageName, UserHandle.USER_ALL, killReason);
   20061     }
   20062 
   20063     public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
   20064         return new PackageFreezer(packageName, userId, killReason);
   20065     }
   20066 
   20067     public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
   20068             String killReason) {
   20069         return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
   20070     }
   20071 
   20072     public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
   20073             String killReason) {
   20074         if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
   20075             return new PackageFreezer();
   20076         } else {
   20077             return freezePackage(packageName, userId, killReason);
   20078         }
   20079     }
   20080 
   20081     public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
   20082             String killReason) {
   20083         return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
   20084     }
   20085 
   20086     public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
   20087             String killReason) {
   20088         if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
   20089             return new PackageFreezer();
   20090         } else {
   20091             return freezePackage(packageName, userId, killReason);
   20092         }
   20093     }
   20094 
   20095     /**
   20096      * Class that freezes and kills the given package upon creation, and
   20097      * unfreezes it upon closing. This is typically used when doing surgery on
   20098      * app code/data to prevent the app from running while you're working.
   20099      */
   20100     private class PackageFreezer implements AutoCloseable {
   20101         private final String mPackageName;
   20102         private final PackageFreezer[] mChildren;
   20103 
   20104         private final boolean mWeFroze;
   20105 
   20106         private final AtomicBoolean mClosed = new AtomicBoolean();
   20107         private final CloseGuard mCloseGuard = CloseGuard.get();
   20108 
   20109         /**
   20110          * Create and return a stub freezer that doesn't actually do anything,
   20111          * typically used when someone requested
   20112          * {@link PackageManager#INSTALL_DONT_KILL_APP} or
   20113          * {@link PackageManager#DELETE_DONT_KILL_APP}.
   20114          */
   20115         public PackageFreezer() {
   20116             mPackageName = null;
   20117             mChildren = null;
   20118             mWeFroze = false;
   20119             mCloseGuard.open("close");
   20120         }
   20121 
   20122         public PackageFreezer(String packageName, int userId, String killReason) {
   20123             synchronized (mPackages) {
   20124                 mPackageName = packageName;
   20125                 mWeFroze = mFrozenPackages.add(mPackageName);
   20126 
   20127                 final PackageSetting ps = mSettings.mPackages.get(mPackageName);
   20128                 if (ps != null) {
   20129                     killApplication(ps.name, ps.appId, userId, killReason);
   20130                 }
   20131 
   20132                 final PackageParser.Package p = mPackages.get(packageName);
   20133                 if (p != null && p.childPackages != null) {
   20134                     final int N = p.childPackages.size();
   20135                     mChildren = new PackageFreezer[N];
   20136                     for (int i = 0; i < N; i++) {
   20137                         mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
   20138                                 userId, killReason);
   20139                     }
   20140                 } else {
   20141                     mChildren = null;
   20142                 }
   20143             }
   20144             mCloseGuard.open("close");
   20145         }
   20146 
   20147         @Override
   20148         protected void finalize() throws Throwable {
   20149             try {
   20150                 mCloseGuard.warnIfOpen();
   20151                 close();
   20152             } finally {
   20153                 super.finalize();
   20154             }
   20155         }
   20156 
   20157         @Override
   20158         public void close() {
   20159             mCloseGuard.close();
   20160             if (mClosed.compareAndSet(false, true)) {
   20161                 synchronized (mPackages) {
   20162                     if (mWeFroze) {
   20163                         mFrozenPackages.remove(mPackageName);
   20164                     }
   20165 
   20166                     if (mChildren != null) {
   20167                         for (PackageFreezer freezer : mChildren) {
   20168                             freezer.close();
   20169                         }
   20170                     }
   20171                 }
   20172             }
   20173         }
   20174     }
   20175 
   20176     /**
   20177      * Verify that given package is currently frozen.
   20178      */
   20179     private void checkPackageFrozen(String packageName) {
   20180         synchronized (mPackages) {
   20181             if (!mFrozenPackages.contains(packageName)) {
   20182                 Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
   20183             }
   20184         }
   20185     }
   20186 
   20187     @Override
   20188     public int movePackage(final String packageName, final String volumeUuid) {
   20189         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
   20190 
   20191         final UserHandle user = new UserHandle(UserHandle.getCallingUserId());
   20192         final int moveId = mNextMoveId.getAndIncrement();
   20193         mHandler.post(new Runnable() {
   20194             @Override
   20195             public void run() {
   20196                 try {
   20197                     movePackageInternal(packageName, volumeUuid, moveId, user);
   20198                 } catch (PackageManagerException e) {
   20199                     Slog.w(TAG, "Failed to move " + packageName, e);
   20200                     mMoveCallbacks.notifyStatusChanged(moveId,
   20201                             PackageManager.MOVE_FAILED_INTERNAL_ERROR);
   20202                 }
   20203             }
   20204         });
   20205         return moveId;
   20206     }
   20207 
   20208     private void movePackageInternal(final String packageName, final String volumeUuid,
   20209             final int moveId, UserHandle user) throws PackageManagerException {
   20210         final StorageManager storage = mContext.getSystemService(StorageManager.class);
   20211         final PackageManager pm = mContext.getPackageManager();
   20212 
   20213         final boolean currentAsec;
   20214         final String currentVolumeUuid;
   20215         final File codeFile;
   20216         final String installerPackageName;
   20217         final String packageAbiOverride;
   20218         final int appId;
   20219         final String seinfo;
   20220         final String label;
   20221         final int targetSdkVersion;
   20222         final PackageFreezer freezer;
   20223         final int[] installedUserIds;
   20224 
   20225         // reader
   20226         synchronized (mPackages) {
   20227             final PackageParser.Package pkg = mPackages.get(packageName);
   20228             final PackageSetting ps = mSettings.mPackages.get(packageName);
   20229             if (pkg == null || ps == null) {
   20230                 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
   20231             }
   20232 
   20233             if (pkg.applicationInfo.isSystemApp()) {
   20234                 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
   20235                         "Cannot move system application");
   20236             }
   20237 
   20238             if (pkg.applicationInfo.isExternalAsec()) {
   20239                 currentAsec = true;
   20240                 currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
   20241             } else if (pkg.applicationInfo.isForwardLocked()) {
   20242                 currentAsec = true;
   20243                 currentVolumeUuid = "forward_locked";
   20244             } else {
   20245                 currentAsec = false;
   20246                 currentVolumeUuid = ps.volumeUuid;
   20247 
   20248                 final File probe = new File(pkg.codePath);
   20249                 final File probeOat = new File(probe, "oat");
   20250                 if (!probe.isDirectory() || !probeOat.isDirectory()) {
   20251                     throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
   20252                             "Move only supported for modern cluster style installs");
   20253                 }
   20254             }
   20255 
   20256             if (Objects.equals(currentVolumeUuid, volumeUuid)) {
   20257                 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
   20258                         "Package already moved to " + volumeUuid);
   20259             }
   20260             if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
   20261                 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
   20262                         "Device admin cannot be moved");
   20263             }
   20264 
   20265             if (mFrozenPackages.contains(packageName)) {
   20266                 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
   20267                         "Failed to move already frozen package");
   20268             }
   20269 
   20270             codeFile = new File(pkg.codePath);
   20271             installerPackageName = ps.installerPackageName;
   20272             packageAbiOverride = ps.cpuAbiOverrideString;
   20273             appId = UserHandle.getAppId(pkg.applicationInfo.uid);
   20274             seinfo = pkg.applicationInfo.seinfo;
   20275             label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
   20276             targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
   20277             freezer = freezePackage(packageName, "movePackageInternal");
   20278             installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
   20279         }
   20280 
   20281         final Bundle extras = new Bundle();
   20282         extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
   20283         extras.putString(Intent.EXTRA_TITLE, label);
   20284         mMoveCallbacks.notifyCreated(moveId, extras);
   20285 
   20286         int installFlags;
   20287         final boolean moveCompleteApp;
   20288         final File measurePath;
   20289 
   20290         if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
   20291             installFlags = INSTALL_INTERNAL;
   20292             moveCompleteApp = !currentAsec;
   20293             measurePath = Environment.getDataAppDirectory(volumeUuid);
   20294         } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
   20295             installFlags = INSTALL_EXTERNAL;
   20296             moveCompleteApp = false;
   20297             measurePath = storage.getPrimaryPhysicalVolume().getPath();
   20298         } else {
   20299             final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
   20300             if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
   20301                     || !volume.isMountedWritable()) {
   20302                 freezer.close();
   20303                 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
   20304                         "Move location not mounted private volume");
   20305             }
   20306 
   20307             Preconditions.checkState(!currentAsec);
   20308 
   20309             installFlags = INSTALL_INTERNAL;
   20310             moveCompleteApp = true;
   20311             measurePath = Environment.getDataAppDirectory(volumeUuid);
   20312         }
   20313 
   20314         final PackageStats stats = new PackageStats(null, -1);
   20315         synchronized (mInstaller) {
   20316             for (int userId : installedUserIds) {
   20317                 if (!getPackageSizeInfoLI(packageName, userId, stats)) {
   20318                     freezer.close();
   20319                     throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
   20320                             "Failed to measure package size");
   20321                 }
   20322             }
   20323         }
   20324 
   20325         if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
   20326                 + stats.dataSize);
   20327 
   20328         final long startFreeBytes = measurePath.getFreeSpace();
   20329         final long sizeBytes;
   20330         if (moveCompleteApp) {
   20331             sizeBytes = stats.codeSize + stats.dataSize;
   20332         } else {
   20333             sizeBytes = stats.codeSize;
   20334         }
   20335 
   20336         if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
   20337             freezer.close();
   20338             throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
   20339                     "Not enough free space to move");
   20340         }
   20341 
   20342         mMoveCallbacks.notifyStatusChanged(moveId, 10);
   20343 
   20344         final CountDownLatch installedLatch = new CountDownLatch(1);
   20345         final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
   20346             @Override
   20347             public void onUserActionRequired(Intent intent) throws RemoteException {
   20348                 throw new IllegalStateException();
   20349             }
   20350 
   20351             @Override
   20352             public void onPackageInstalled(String basePackageName, int returnCode, String msg,
   20353                     Bundle extras) throws RemoteException {
   20354                 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
   20355                         + PackageManager.installStatusToString(returnCode, msg));
   20356 
   20357                 installedLatch.countDown();
   20358                 freezer.close();
   20359 
   20360                 final int status = PackageManager.installStatusToPublicStatus(returnCode);
   20361                 switch (status) {
   20362                     case PackageInstaller.STATUS_SUCCESS:
   20363                         mMoveCallbacks.notifyStatusChanged(moveId,
   20364                                 PackageManager.MOVE_SUCCEEDED);
   20365                         break;
   20366                     case PackageInstaller.STATUS_FAILURE_STORAGE:
   20367                         mMoveCallbacks.notifyStatusChanged(moveId,
   20368                                 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
   20369                         break;
   20370                     default:
   20371                         mMoveCallbacks.notifyStatusChanged(moveId,
   20372                                 PackageManager.MOVE_FAILED_INTERNAL_ERROR);
   20373                         break;
   20374                 }
   20375             }
   20376         };
   20377 
   20378         final MoveInfo move;
   20379         if (moveCompleteApp) {
   20380             // Kick off a thread to report progress estimates
   20381             new Thread() {
   20382                 @Override
   20383                 public void run() {
   20384                     while (true) {
   20385                         try {
   20386                             if (installedLatch.await(1, TimeUnit.SECONDS)) {
   20387                                 break;
   20388                             }
   20389                         } catch (InterruptedException ignored) {
   20390                         }
   20391 
   20392                         final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace();
   20393                         final int progress = 10 + (int) MathUtils.constrain(
   20394                                 ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
   20395                         mMoveCallbacks.notifyStatusChanged(moveId, progress);
   20396                     }
   20397                 }
   20398             }.start();
   20399 
   20400             final String dataAppName = codeFile.getName();
   20401             move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
   20402                     dataAppName, appId, seinfo, targetSdkVersion);
   20403         } else {
   20404             move = null;
   20405         }
   20406 
   20407         installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
   20408 
   20409         final Message msg = mHandler.obtainMessage(INIT_COPY);
   20410         final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
   20411         final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
   20412                 installerPackageName, volumeUuid, null /*verificationInfo*/, user,
   20413                 packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/);
   20414         params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
   20415         msg.obj = params;
   20416 
   20417         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
   20418                 System.identityHashCode(msg.obj));
   20419         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
   20420                 System.identityHashCode(msg.obj));
   20421 
   20422         mHandler.sendMessage(msg);
   20423     }
   20424 
   20425     @Override
   20426     public int movePrimaryStorage(String volumeUuid) throws RemoteException {
   20427         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
   20428 
   20429         final int realMoveId = mNextMoveId.getAndIncrement();
   20430         final Bundle extras = new Bundle();
   20431         extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
   20432         mMoveCallbacks.notifyCreated(realMoveId, extras);
   20433 
   20434         final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
   20435             @Override
   20436             public void onCreated(int moveId, Bundle extras) {
   20437                 // Ignored
   20438             }
   20439 
   20440             @Override
   20441             public void onStatusChanged(int moveId, int status, long estMillis) {
   20442                 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
   20443             }
   20444         };
   20445 
   20446         final StorageManager storage = mContext.getSystemService(StorageManager.class);
   20447         storage.setPrimaryStorageUuid(volumeUuid, callback);
   20448         return realMoveId;
   20449     }
   20450 
   20451     @Override
   20452     public int getMoveStatus(int moveId) {
   20453         mContext.enforceCallingOrSelfPermission(
   20454                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
   20455         return mMoveCallbacks.mLastStatus.get(moveId);
   20456     }
   20457 
   20458     @Override
   20459     public void registerMoveCallback(IPackageMoveObserver callback) {
   20460         mContext.enforceCallingOrSelfPermission(
   20461                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
   20462         mMoveCallbacks.register(callback);
   20463     }
   20464 
   20465     @Override
   20466     public void unregisterMoveCallback(IPackageMoveObserver callback) {
   20467         mContext.enforceCallingOrSelfPermission(
   20468                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
   20469         mMoveCallbacks.unregister(callback);
   20470     }
   20471 
   20472     @Override
   20473     public boolean setInstallLocation(int loc) {
   20474         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
   20475                 null);
   20476         if (getInstallLocation() == loc) {
   20477             return true;
   20478         }
   20479         if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
   20480                 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
   20481             android.provider.Settings.Global.putInt(mContext.getContentResolver(),
   20482                     android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
   20483             return true;
   20484         }
   20485         return false;
   20486    }
   20487 
   20488     @Override
   20489     public int getInstallLocation() {
   20490         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
   20491                 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
   20492                 PackageHelper.APP_INSTALL_AUTO);
   20493     }
   20494 
   20495     /** Called by UserManagerService */
   20496     void cleanUpUser(UserManagerService userManager, int userHandle) {
   20497         synchronized (mPackages) {
   20498             mDirtyUsers.remove(userHandle);
   20499             mUserNeedsBadging.delete(userHandle);
   20500             mSettings.removeUserLPw(userHandle);
   20501             mPendingBroadcasts.remove(userHandle);
   20502             mEphemeralApplicationRegistry.onUserRemovedLPw(userHandle);
   20503             removeUnusedPackagesLPw(userManager, userHandle);
   20504         }
   20505     }
   20506 
   20507     /**
   20508      * We're removing userHandle and would like to remove any downloaded packages
   20509      * that are no longer in use by any other user.
   20510      * @param userHandle the user being removed
   20511      */
   20512     private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
   20513         final boolean DEBUG_CLEAN_APKS = false;
   20514         int [] users = userManager.getUserIds();
   20515         Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
   20516         while (psit.hasNext()) {
   20517             PackageSetting ps = psit.next();
   20518             if (ps.pkg == null) {
   20519                 continue;
   20520             }
   20521             final String packageName = ps.pkg.packageName;
   20522             // Skip over if system app
   20523             if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
   20524                 continue;
   20525             }
   20526             if (DEBUG_CLEAN_APKS) {
   20527                 Slog.i(TAG, "Checking package " + packageName);
   20528             }
   20529             boolean keep = shouldKeepUninstalledPackageLPr(packageName);
   20530             if (keep) {
   20531                 if (DEBUG_CLEAN_APKS) {
   20532                     Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
   20533                 }
   20534             } else {
   20535                 for (int i = 0; i < users.length; i++) {
   20536                     if (users[i] != userHandle && ps.getInstalled(users[i])) {
   20537                         keep = true;
   20538                         if (DEBUG_CLEAN_APKS) {
   20539                             Slog.i(TAG, "  Keeping package " + packageName + " for user "
   20540                                     + users[i]);
   20541                         }
   20542                         break;
   20543                     }
   20544                 }
   20545             }
   20546             if (!keep) {
   20547                 if (DEBUG_CLEAN_APKS) {
   20548                     Slog.i(TAG, "  Removing package " + packageName);
   20549                 }
   20550                 mHandler.post(new Runnable() {
   20551                     public void run() {
   20552                         deletePackageX(packageName, userHandle, 0);
   20553                     } //end run
   20554                 });
   20555             }
   20556         }
   20557     }
   20558 
   20559     /** Called by UserManagerService */
   20560     void createNewUser(int userId) {
   20561         synchronized (mInstallLock) {
   20562             mSettings.createNewUserLI(this, mInstaller, userId);
   20563         }
   20564         synchronized (mPackages) {
   20565             scheduleWritePackageRestrictionsLocked(userId);
   20566             scheduleWritePackageListLocked(userId);
   20567             applyFactoryDefaultBrowserLPw(userId);
   20568             primeDomainVerificationsLPw(userId);
   20569         }
   20570     }
   20571 
   20572     void onNewUserCreated(final int userId) {
   20573         mDefaultPermissionPolicy.grantDefaultPermissions(userId);
   20574         // If permission review for legacy apps is required, we represent
   20575         // dagerous permissions for such apps as always granted runtime
   20576         // permissions to keep per user flag state whether review is needed.
   20577         // Hence, if a new user is added we have to propagate dangerous
   20578         // permission grants for these legacy apps.
   20579         if (Build.PERMISSIONS_REVIEW_REQUIRED) {
   20580             updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
   20581                     | UPDATE_PERMISSIONS_REPLACE_ALL);
   20582         }
   20583     }
   20584 
   20585     @Override
   20586     public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
   20587         mContext.enforceCallingOrSelfPermission(
   20588                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
   20589                 "Only package verification agents can read the verifier device identity");
   20590 
   20591         synchronized (mPackages) {
   20592             return mSettings.getVerifierDeviceIdentityLPw();
   20593         }
   20594     }
   20595 
   20596     @Override
   20597     public void setPermissionEnforced(String permission, boolean enforced) {
   20598         // TODO: Now that we no longer change GID for storage, this should to away.
   20599         mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
   20600                 "setPermissionEnforced");
   20601         if (READ_EXTERNAL_STORAGE.equals(permission)) {
   20602             synchronized (mPackages) {
   20603                 if (mSettings.mReadExternalStorageEnforced == null
   20604                         || mSettings.mReadExternalStorageEnforced != enforced) {
   20605                     mSettings.mReadExternalStorageEnforced = enforced;
   20606                     mSettings.writeLPr();
   20607                 }
   20608             }
   20609             // kill any non-foreground processes so we restart them and
   20610             // grant/revoke the GID.
   20611             final IActivityManager am = ActivityManagerNative.getDefault();
   20612             if (am != null) {
   20613                 final long token = Binder.clearCallingIdentity();
   20614                 try {
   20615                     am.killProcessesBelowForeground("setPermissionEnforcement");
   20616                 } catch (RemoteException e) {
   20617                 } finally {
   20618                     Binder.restoreCallingIdentity(token);
   20619                 }
   20620             }
   20621         } else {
   20622             throw new IllegalArgumentException("No selective enforcement for " + permission);
   20623         }
   20624     }
   20625 
   20626     @Override
   20627     @Deprecated
   20628     public boolean isPermissionEnforced(String permission) {
   20629         return true;
   20630     }
   20631 
   20632     @Override
   20633     public boolean isStorageLow() {
   20634         final long token = Binder.clearCallingIdentity();
   20635         try {
   20636             final DeviceStorageMonitorInternal
   20637                     dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
   20638             if (dsm != null) {
   20639                 return dsm.isMemoryLow();
   20640             } else {
   20641                 return false;
   20642             }
   20643         } finally {
   20644             Binder.restoreCallingIdentity(token);
   20645         }
   20646     }
   20647 
   20648     @Override
   20649     public IPackageInstaller getPackageInstaller() {
   20650         return mInstallerService;
   20651     }
   20652 
   20653     private boolean userNeedsBadging(int userId) {
   20654         int index = mUserNeedsBadging.indexOfKey(userId);
   20655         if (index < 0) {
   20656             final UserInfo userInfo;
   20657             final long token = Binder.clearCallingIdentity();
   20658             try {
   20659                 userInfo = sUserManager.getUserInfo(userId);
   20660             } finally {
   20661                 Binder.restoreCallingIdentity(token);
   20662             }
   20663             final boolean b;
   20664             if (userInfo != null && userInfo.isManagedProfile()) {
   20665                 b = true;
   20666             } else {
   20667                 b = false;
   20668             }
   20669             mUserNeedsBadging.put(userId, b);
   20670             return b;
   20671         }
   20672         return mUserNeedsBadging.valueAt(index);
   20673     }
   20674 
   20675     @Override
   20676     public KeySet getKeySetByAlias(String packageName, String alias) {
   20677         if (packageName == null || alias == null) {
   20678             return null;
   20679         }
   20680         synchronized(mPackages) {
   20681             final PackageParser.Package pkg = mPackages.get(packageName);
   20682             if (pkg == null) {
   20683                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
   20684                 throw new IllegalArgumentException("Unknown package: " + packageName);
   20685             }
   20686             KeySetManagerService ksms = mSettings.mKeySetManagerService;
   20687             return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
   20688         }
   20689     }
   20690 
   20691     @Override
   20692     public KeySet getSigningKeySet(String packageName) {
   20693         if (packageName == null) {
   20694             return null;
   20695         }
   20696         synchronized(mPackages) {
   20697             final PackageParser.Package pkg = mPackages.get(packageName);
   20698             if (pkg == null) {
   20699                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
   20700                 throw new IllegalArgumentException("Unknown package: " + packageName);
   20701             }
   20702             if (pkg.applicationInfo.uid != Binder.getCallingUid()
   20703                     && Process.SYSTEM_UID != Binder.getCallingUid()) {
   20704                 throw new SecurityException("May not access signing KeySet of other apps.");
   20705             }
   20706             KeySetManagerService ksms = mSettings.mKeySetManagerService;
   20707             return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
   20708         }
   20709     }
   20710 
   20711     @Override
   20712     public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
   20713         if (packageName == null || ks == null) {
   20714             return false;
   20715         }
   20716         synchronized(mPackages) {
   20717             final PackageParser.Package pkg = mPackages.get(packageName);
   20718             if (pkg == null) {
   20719                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
   20720                 throw new IllegalArgumentException("Unknown package: " + packageName);
   20721             }
   20722             IBinder ksh = ks.getToken();
   20723             if (ksh instanceof KeySetHandle) {
   20724                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
   20725                 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
   20726             }
   20727             return false;
   20728         }
   20729     }
   20730 
   20731     @Override
   20732     public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
   20733         if (packageName == null || ks == null) {
   20734             return false;
   20735         }
   20736         synchronized(mPackages) {
   20737             final PackageParser.Package pkg = mPackages.get(packageName);
   20738             if (pkg == null) {
   20739                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
   20740                 throw new IllegalArgumentException("Unknown package: " + packageName);
   20741             }
   20742             IBinder ksh = ks.getToken();
   20743             if (ksh instanceof KeySetHandle) {
   20744                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
   20745                 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
   20746             }
   20747             return false;
   20748         }
   20749     }
   20750 
   20751     private void deletePackageIfUnusedLPr(final String packageName) {
   20752         PackageSetting ps = mSettings.mPackages.get(packageName);
   20753         if (ps == null) {
   20754             return;
   20755         }
   20756         if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
   20757             // TODO Implement atomic delete if package is unused
   20758             // It is currently possible that the package will be deleted even if it is installed
   20759             // after this method returns.
   20760             mHandler.post(new Runnable() {
   20761                 public void run() {
   20762                     deletePackageX(packageName, 0, PackageManager.DELETE_ALL_USERS);
   20763                 }
   20764             });
   20765         }
   20766     }
   20767 
   20768     /**
   20769      * Check and throw if the given before/after packages would be considered a
   20770      * downgrade.
   20771      */
   20772     private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
   20773             throws PackageManagerException {
   20774         if (after.versionCode < before.mVersionCode) {
   20775             throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
   20776                     "Update version code " + after.versionCode + " is older than current "
   20777                     + before.mVersionCode);
   20778         } else if (after.versionCode == before.mVersionCode) {
   20779             if (after.baseRevisionCode < before.baseRevisionCode) {
   20780                 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
   20781                         "Update base revision code " + after.baseRevisionCode
   20782                         + " is older than current " + before.baseRevisionCode);
   20783             }
   20784 
   20785             if (!ArrayUtils.isEmpty(after.splitNames)) {
   20786                 for (int i = 0; i < after.splitNames.length; i++) {
   20787                     final String splitName = after.splitNames[i];
   20788                     final int j = ArrayUtils.indexOf(before.splitNames, splitName);
   20789                     if (j != -1) {
   20790                         if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
   20791                             throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
   20792                                     "Update split " + splitName + " revision code "
   20793                                     + after.splitRevisionCodes[i] + " is older than current "
   20794                                     + before.splitRevisionCodes[j]);
   20795                         }
   20796                     }
   20797                 }
   20798             }
   20799         }
   20800     }
   20801 
   20802     private static class MoveCallbacks extends Handler {
   20803         private static final int MSG_CREATED = 1;
   20804         private static final int MSG_STATUS_CHANGED = 2;
   20805 
   20806         private final RemoteCallbackList<IPackageMoveObserver>
   20807                 mCallbacks = new RemoteCallbackList<>();
   20808 
   20809         private final SparseIntArray mLastStatus = new SparseIntArray();
   20810 
   20811         public MoveCallbacks(Looper looper) {
   20812             super(looper);
   20813         }
   20814 
   20815         public void register(IPackageMoveObserver callback) {
   20816             mCallbacks.register(callback);
   20817         }
   20818 
   20819         public void unregister(IPackageMoveObserver callback) {
   20820             mCallbacks.unregister(callback);
   20821         }
   20822 
   20823         @Override
   20824         public void handleMessage(Message msg) {
   20825             final SomeArgs args = (SomeArgs) msg.obj;
   20826             final int n = mCallbacks.beginBroadcast();
   20827             for (int i = 0; i < n; i++) {
   20828                 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
   20829                 try {
   20830                     invokeCallback(callback, msg.what, args);
   20831                 } catch (RemoteException ignored) {
   20832                 }
   20833             }
   20834             mCallbacks.finishBroadcast();
   20835             args.recycle();
   20836         }
   20837 
   20838         private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
   20839                 throws RemoteException {
   20840             switch (what) {
   20841                 case MSG_CREATED: {
   20842                     callback.onCreated(args.argi1, (Bundle) args.arg2);
   20843                     break;
   20844                 }
   20845                 case MSG_STATUS_CHANGED: {
   20846                     callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
   20847                     break;
   20848                 }
   20849             }
   20850         }
   20851 
   20852         private void notifyCreated(int moveId, Bundle extras) {
   20853             Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
   20854 
   20855             final SomeArgs args = SomeArgs.obtain();
   20856             args.argi1 = moveId;
   20857             args.arg2 = extras;
   20858             obtainMessage(MSG_CREATED, args).sendToTarget();
   20859         }
   20860 
   20861         private void notifyStatusChanged(int moveId, int status) {
   20862             notifyStatusChanged(moveId, status, -1);
   20863         }
   20864 
   20865         private void notifyStatusChanged(int moveId, int status, long estMillis) {
   20866             Slog.v(TAG, "Move " + moveId + " status " + status);
   20867 
   20868             final SomeArgs args = SomeArgs.obtain();
   20869             args.argi1 = moveId;
   20870             args.argi2 = status;
   20871             args.arg3 = estMillis;
   20872             obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
   20873 
   20874             synchronized (mLastStatus) {
   20875                 mLastStatus.put(moveId, status);
   20876             }
   20877         }
   20878     }
   20879 
   20880     private final static class OnPermissionChangeListeners extends Handler {
   20881         private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
   20882 
   20883         private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
   20884                 new RemoteCallbackList<>();
   20885 
   20886         public OnPermissionChangeListeners(Looper looper) {
   20887             super(looper);
   20888         }
   20889 
   20890         @Override
   20891         public void handleMessage(Message msg) {
   20892             switch (msg.what) {
   20893                 case MSG_ON_PERMISSIONS_CHANGED: {
   20894                     final int uid = msg.arg1;
   20895                     handleOnPermissionsChanged(uid);
   20896                 } break;
   20897             }
   20898         }
   20899 
   20900         public void addListenerLocked(IOnPermissionsChangeListener listener) {
   20901             mPermissionListeners.register(listener);
   20902 
   20903         }
   20904 
   20905         public void removeListenerLocked(IOnPermissionsChangeListener listener) {
   20906             mPermissionListeners.unregister(listener);
   20907         }
   20908 
   20909         public void onPermissionsChanged(int uid) {
   20910             if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
   20911                 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
   20912             }
   20913         }
   20914 
   20915         private void handleOnPermissionsChanged(int uid) {
   20916             final int count = mPermissionListeners.beginBroadcast();
   20917             try {
   20918                 for (int i = 0; i < count; i++) {
   20919                     IOnPermissionsChangeListener callback = mPermissionListeners
   20920                             .getBroadcastItem(i);
   20921                     try {
   20922                         callback.onPermissionsChanged(uid);
   20923                     } catch (RemoteException e) {
   20924                         Log.e(TAG, "Permission listener is dead", e);
   20925                     }
   20926                 }
   20927             } finally {
   20928                 mPermissionListeners.finishBroadcast();
   20929             }
   20930         }
   20931     }
   20932 
   20933     private class PackageManagerInternalImpl extends PackageManagerInternal {
   20934         @Override
   20935         public void setLocationPackagesProvider(PackagesProvider provider) {
   20936             synchronized (mPackages) {
   20937                 mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
   20938             }
   20939         }
   20940 
   20941         @Override
   20942         public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
   20943             synchronized (mPackages) {
   20944                 mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
   20945             }
   20946         }
   20947 
   20948         @Override
   20949         public void setSmsAppPackagesProvider(PackagesProvider provider) {
   20950             synchronized (mPackages) {
   20951                 mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
   20952             }
   20953         }
   20954 
   20955         @Override
   20956         public void setDialerAppPackagesProvider(PackagesProvider provider) {
   20957             synchronized (mPackages) {
   20958                 mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
   20959             }
   20960         }
   20961 
   20962         @Override
   20963         public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
   20964             synchronized (mPackages) {
   20965                 mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider);
   20966             }
   20967         }
   20968 
   20969         @Override
   20970         public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
   20971             synchronized (mPackages) {
   20972                 mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider);
   20973             }
   20974         }
   20975 
   20976         @Override
   20977         public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
   20978             synchronized (mPackages) {
   20979                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
   20980                         packageName, userId);
   20981             }
   20982         }
   20983 
   20984         @Override
   20985         public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
   20986             synchronized (mPackages) {
   20987                 mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
   20988                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
   20989                         packageName, userId);
   20990             }
   20991         }
   20992 
   20993         @Override
   20994         public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
   20995             synchronized (mPackages) {
   20996                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr(
   20997                         packageName, userId);
   20998             }
   20999         }
   21000 
   21001         @Override
   21002         public void setKeepUninstalledPackages(final List<String> packageList) {
   21003             Preconditions.checkNotNull(packageList);
   21004             List<String> removedFromList = null;
   21005             synchronized (mPackages) {
   21006                 if (mKeepUninstalledPackages != null) {
   21007                     final int packagesCount = mKeepUninstalledPackages.size();
   21008                     for (int i = 0; i < packagesCount; i++) {
   21009                         String oldPackage = mKeepUninstalledPackages.get(i);
   21010                         if (packageList != null && packageList.contains(oldPackage)) {
   21011                             continue;
   21012                         }
   21013                         if (removedFromList == null) {
   21014                             removedFromList = new ArrayList<>();
   21015                         }
   21016                         removedFromList.add(oldPackage);
   21017                     }
   21018                 }
   21019                 mKeepUninstalledPackages = new ArrayList<>(packageList);
   21020                 if (removedFromList != null) {
   21021                     final int removedCount = removedFromList.size();
   21022                     for (int i = 0; i < removedCount; i++) {
   21023                         deletePackageIfUnusedLPr(removedFromList.get(i));
   21024                     }
   21025                 }
   21026             }
   21027         }
   21028 
   21029         @Override
   21030         public boolean isPermissionsReviewRequired(String packageName, int userId) {
   21031             synchronized (mPackages) {
   21032                 // If we do not support permission review, done.
   21033                 if (!Build.PERMISSIONS_REVIEW_REQUIRED) {
   21034                     return false;
   21035                 }
   21036 
   21037                 PackageSetting packageSetting = mSettings.mPackages.get(packageName);
   21038                 if (packageSetting == null) {
   21039                     return false;
   21040                 }
   21041 
   21042                 // Permission review applies only to apps not supporting the new permission model.
   21043                 if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
   21044                     return false;
   21045                 }
   21046 
   21047                 // Legacy apps have the permission and get user consent on launch.
   21048                 PermissionsState permissionsState = packageSetting.getPermissionsState();
   21049                 return permissionsState.isPermissionReviewRequired(userId);
   21050             }
   21051         }
   21052 
   21053         @Override
   21054         public ApplicationInfo getApplicationInfo(String packageName, int userId) {
   21055             return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId);
   21056         }
   21057 
   21058         @Override
   21059         public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
   21060                 int userId) {
   21061             return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
   21062         }
   21063 
   21064         @Override
   21065         public void setDeviceAndProfileOwnerPackages(
   21066                 int deviceOwnerUserId, String deviceOwnerPackage,
   21067                 SparseArray<String> profileOwnerPackages) {
   21068             mProtectedPackages.setDeviceAndProfileOwnerPackages(
   21069                     deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
   21070         }
   21071 
   21072         @Override
   21073         public boolean isPackageDataProtected(int userId, String packageName) {
   21074             return mProtectedPackages.isPackageDataProtected(userId, packageName);
   21075         }
   21076 
   21077         @Override
   21078         public boolean wasPackageEverLaunched(String packageName, int userId) {
   21079             synchronized (mPackages) {
   21080                 return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
   21081             }
   21082         }
   21083     }
   21084 
   21085     @Override
   21086     public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
   21087         enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
   21088         synchronized (mPackages) {
   21089             final long identity = Binder.clearCallingIdentity();
   21090             try {
   21091                 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
   21092                         packageNames, userId);
   21093             } finally {
   21094                 Binder.restoreCallingIdentity(identity);
   21095             }
   21096         }
   21097     }
   21098 
   21099     private static void enforceSystemOrPhoneCaller(String tag) {
   21100         int callingUid = Binder.getCallingUid();
   21101         if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
   21102             throw new SecurityException(
   21103                     "Cannot call " + tag + " from UID " + callingUid);
   21104         }
   21105     }
   21106 
   21107     boolean isHistoricalPackageUsageAvailable() {
   21108         return mPackageUsage.isHistoricalPackageUsageAvailable();
   21109     }
   21110 
   21111     /**
   21112      * Return a <b>copy</b> of the collection of packages known to the package manager.
   21113      * @return A copy of the values of mPackages.
   21114      */
   21115     Collection<PackageParser.Package> getPackages() {
   21116         synchronized (mPackages) {
   21117             return new ArrayList<>(mPackages.values());
   21118         }
   21119     }
   21120 
   21121     /**
   21122      * Logs process start information (including base APK hash) to the security log.
   21123      * @hide
   21124      */
   21125     public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
   21126             String apkFile, int pid) {
   21127         if (!SecurityLog.isLoggingEnabled()) {
   21128             return;
   21129         }
   21130         Bundle data = new Bundle();
   21131         data.putLong("startTimestamp", System.currentTimeMillis());
   21132         data.putString("processName", processName);
   21133         data.putInt("uid", uid);
   21134         data.putString("seinfo", seinfo);
   21135         data.putString("apkFile", apkFile);
   21136         data.putInt("pid", pid);
   21137         Message msg = mProcessLoggingHandler.obtainMessage(
   21138                 ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
   21139         msg.setData(data);
   21140         mProcessLoggingHandler.sendMessage(msg);
   21141     }
   21142 
   21143     public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
   21144         return mCompilerStats.getPackageStats(pkgName);
   21145     }
   21146 
   21147     public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
   21148         return getOrCreateCompilerPackageStats(pkg.packageName);
   21149     }
   21150 
   21151     public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
   21152         return mCompilerStats.getOrCreatePackageStats(pkgName);
   21153     }
   21154 
   21155     public void deleteCompilerPackageStats(String pkgName) {
   21156         mCompilerStats.deletePackageStats(pkgName);
   21157     }
   21158 }
   21159