• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
28 import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
29 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
30 import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
31 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
32 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
33 import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
34 import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
35 import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
36 import static android.content.pm.PackageManager.INSTALL_FAILED_DEXOPT;
37 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
38 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
39 import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
40 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
41 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
42 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
43 import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
44 import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
45 import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
46 import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
47 import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
48 import static android.content.pm.PackageManager.INSTALL_FAILED_UID_CHANGED;
49 import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
50 import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
51 import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
52 import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK;
53 import static android.content.pm.PackageManager.INSTALL_INTERNAL;
54 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
55 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
56 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
57 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
58 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
59 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
60 import static android.content.pm.PackageManager.MATCH_ALL;
61 import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
62 import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
63 import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
64 import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
65 import static android.content.pm.PackageManager.PERMISSION_DENIED;
66 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
67 import static android.content.pm.PackageParser.isApkFile;
68 import static android.os.Process.PACKAGE_INFO_GID;
69 import static android.os.Process.SYSTEM_UID;
70 import static android.system.OsConstants.O_CREAT;
71 import static android.system.OsConstants.O_RDWR;
72 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
73 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_USER_OWNER;
74 import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
75 import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
76 import static com.android.internal.util.ArrayUtils.appendInt;
77 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
78 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
79 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
80 import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
81 import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
82 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
83 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
84 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
85 
86 import android.Manifest;
87 import android.app.ActivityManager;
88 import android.app.ActivityManagerNative;
89 import android.app.AppGlobals;
90 import android.app.IActivityManager;
91 import android.app.admin.IDevicePolicyManager;
92 import android.app.backup.IBackupManager;
93 import android.app.usage.UsageStats;
94 import android.app.usage.UsageStatsManager;
95 import android.content.BroadcastReceiver;
96 import android.content.ComponentName;
97 import android.content.Context;
98 import android.content.IIntentReceiver;
99 import android.content.Intent;
100 import android.content.IntentFilter;
101 import android.content.IntentSender;
102 import android.content.IntentSender.SendIntentException;
103 import android.content.ServiceConnection;
104 import android.content.pm.ActivityInfo;
105 import android.content.pm.ApplicationInfo;
106 import android.content.pm.FeatureInfo;
107 import android.content.pm.IOnPermissionsChangeListener;
108 import android.content.pm.IPackageDataObserver;
109 import android.content.pm.IPackageDeleteObserver;
110 import android.content.pm.IPackageDeleteObserver2;
111 import android.content.pm.IPackageInstallObserver2;
112 import android.content.pm.IPackageInstaller;
113 import android.content.pm.IPackageManager;
114 import android.content.pm.IPackageMoveObserver;
115 import android.content.pm.IPackageStatsObserver;
116 import android.content.pm.InstrumentationInfo;
117 import android.content.pm.IntentFilterVerificationInfo;
118 import android.content.pm.KeySet;
119 import android.content.pm.ManifestDigest;
120 import android.content.pm.PackageCleanItem;
121 import android.content.pm.PackageInfo;
122 import android.content.pm.PackageInfoLite;
123 import android.content.pm.PackageInstaller;
124 import android.content.pm.PackageManager;
125 import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
126 import android.content.pm.PackageManagerInternal;
127 import android.content.pm.PackageParser;
128 import android.content.pm.PackageParser.ActivityIntentInfo;
129 import android.content.pm.PackageParser.PackageLite;
130 import android.content.pm.PackageParser.PackageParserException;
131 import android.content.pm.PackageStats;
132 import android.content.pm.PackageUserState;
133 import android.content.pm.ParceledListSlice;
134 import android.content.pm.PermissionGroupInfo;
135 import android.content.pm.PermissionInfo;
136 import android.content.pm.ProviderInfo;
137 import android.content.pm.ResolveInfo;
138 import android.content.pm.ServiceInfo;
139 import android.content.pm.Signature;
140 import android.content.pm.UserInfo;
141 import android.content.pm.VerificationParams;
142 import android.content.pm.VerifierDeviceIdentity;
143 import android.content.pm.VerifierInfo;
144 import android.content.res.Resources;
145 import android.hardware.display.DisplayManager;
146 import android.net.Uri;
147 import android.os.Debug;
148 import android.os.Binder;
149 import android.os.Build;
150 import android.os.Bundle;
151 import android.os.Environment;
152 import android.os.Environment.UserEnvironment;
153 import android.os.FileUtils;
154 import android.os.Handler;
155 import android.os.IBinder;
156 import android.os.Looper;
157 import android.os.Message;
158 import android.os.Parcel;
159 import android.os.ParcelFileDescriptor;
160 import android.os.Process;
161 import android.os.RemoteCallbackList;
162 import android.os.RemoteException;
163 import android.os.SELinux;
164 import android.os.ServiceManager;
165 import android.os.SystemClock;
166 import android.os.SystemProperties;
167 import android.os.UserHandle;
168 import android.os.UserManager;
169 import android.os.storage.IMountService;
170 import android.os.storage.MountServiceInternal;
171 import android.os.storage.StorageEventListener;
172 import android.os.storage.StorageManager;
173 import android.os.storage.VolumeInfo;
174 import android.os.storage.VolumeRecord;
175 import android.security.KeyStore;
176 import android.security.SystemKeyStore;
177 import android.system.ErrnoException;
178 import android.system.Os;
179 import android.system.StructStat;
180 import android.text.TextUtils;
181 import android.text.format.DateUtils;
182 import android.util.ArrayMap;
183 import android.util.ArraySet;
184 import android.util.AtomicFile;
185 import android.util.DisplayMetrics;
186 import android.util.EventLog;
187 import android.util.ExceptionUtils;
188 import android.util.Log;
189 import android.util.LogPrinter;
190 import android.util.MathUtils;
191 import android.util.PrintStreamPrinter;
192 import android.util.Slog;
193 import android.util.SparseArray;
194 import android.util.SparseBooleanArray;
195 import android.util.SparseIntArray;
196 import android.util.Xml;
197 import android.view.Display;
198 
199 import dalvik.system.DexFile;
200 import dalvik.system.VMRuntime;
201 
202 import libcore.io.IoUtils;
203 import libcore.util.EmptyArray;
204 
205 import com.android.internal.R;
206 import com.android.internal.annotations.GuardedBy;
207 import com.android.internal.app.IMediaContainerService;
208 import com.android.internal.app.ResolverActivity;
209 import com.android.internal.content.NativeLibraryHelper;
210 import com.android.internal.content.PackageHelper;
211 import com.android.internal.os.IParcelFileDescriptorFactory;
212 import com.android.internal.os.SomeArgs;
213 import com.android.internal.os.Zygote;
214 import com.android.internal.util.ArrayUtils;
215 import com.android.internal.util.FastPrintWriter;
216 import com.android.internal.util.FastXmlSerializer;
217 import com.android.internal.util.IndentingPrintWriter;
218 import com.android.internal.util.Preconditions;
219 import com.android.server.EventLogTags;
220 import com.android.server.FgThread;
221 import com.android.server.IntentResolver;
222 import com.android.server.LocalServices;
223 import com.android.server.ServiceThread;
224 import com.android.server.SystemConfig;
225 import com.android.server.Watchdog;
226 import com.android.server.pm.PermissionsState.PermissionState;
227 import com.android.server.pm.Settings.DatabaseVersion;
228 import com.android.server.pm.Settings.VersionInfo;
229 import com.android.server.storage.DeviceStorageMonitorInternal;
230 
231 import org.xmlpull.v1.XmlPullParser;
232 import org.xmlpull.v1.XmlPullParserException;
233 import org.xmlpull.v1.XmlSerializer;
234 
235 import java.io.BufferedInputStream;
236 import java.io.BufferedOutputStream;
237 import java.io.BufferedReader;
238 import java.io.ByteArrayInputStream;
239 import java.io.ByteArrayOutputStream;
240 import java.io.File;
241 import java.io.FileDescriptor;
242 import java.io.FileNotFoundException;
243 import java.io.FileOutputStream;
244 import java.io.FileReader;
245 import java.io.FilenameFilter;
246 import java.io.IOException;
247 import java.io.InputStream;
248 import java.io.PrintWriter;
249 import java.nio.charset.StandardCharsets;
250 import java.security.NoSuchAlgorithmException;
251 import java.security.PublicKey;
252 import java.security.cert.CertificateEncodingException;
253 import java.security.cert.CertificateException;
254 import java.text.SimpleDateFormat;
255 import java.util.ArrayList;
256 import java.util.Arrays;
257 import java.util.Collection;
258 import java.util.Collections;
259 import java.util.Comparator;
260 import java.util.Date;
261 import java.util.Iterator;
262 import java.util.List;
263 import java.util.Map;
264 import java.util.Objects;
265 import java.util.Set;
266 import java.util.concurrent.CountDownLatch;
267 import java.util.concurrent.TimeUnit;
268 import java.util.concurrent.atomic.AtomicBoolean;
269 import java.util.concurrent.atomic.AtomicInteger;
270 import java.util.concurrent.atomic.AtomicLong;
271 
272 /**
273  * Keep track of all those .apks everywhere.
274  *
275  * This is very central to the platform's security; please run the unit
276  * tests whenever making modifications here:
277  *
278 mmm frameworks/base/tests/AndroidTests
279 adb install -r -f out/target/product/passion/data/app/AndroidTests.apk
280 adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner
281  *
282  * {@hide}
283  */
284 public class PackageManagerService extends IPackageManager.Stub {
285     static final String TAG = "PackageManager";
286     static final boolean DEBUG_SETTINGS = false;
287     static final boolean DEBUG_PREFERRED = false;
288     static final boolean DEBUG_UPGRADE = false;
289     static final boolean DEBUG_DOMAIN_VERIFICATION = false;
290     private static final boolean DEBUG_BACKUP = false;
291     private static final boolean DEBUG_INSTALL = false;
292     private static final boolean DEBUG_REMOVE = false;
293     private static final boolean DEBUG_BROADCASTS = false;
294     private static final boolean DEBUG_SHOW_INFO = false;
295     private static final boolean DEBUG_PACKAGE_INFO = false;
296     private static final boolean DEBUG_INTENT_MATCHING = false;
297     private static final boolean DEBUG_PACKAGE_SCANNING = false;
298     private static final boolean DEBUG_VERIFY = false;
299     private static final boolean DEBUG_DEXOPT = false;
300     private static final boolean DEBUG_FILTERS = false;
301     private static final boolean DEBUG_ABI_SELECTION = false;
302 
303     static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
304 
305     private static final int RADIO_UID = Process.PHONE_UID;
306     private static final int LOG_UID = Process.LOG_UID;
307     private static final int NFC_UID = Process.NFC_UID;
308     private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
309     private static final int SHELL_UID = Process.SHELL_UID;
310 
311     // Cap the size of permission trees that 3rd party apps can define
312     private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
313 
314     // Suffix used during package installation when copying/moving
315     // package apks to install directory.
316     private static final String INSTALL_PACKAGE_SUFFIX = "-";
317 
318     static final int SCAN_NO_DEX = 1<<1;
319     static final int SCAN_FORCE_DEX = 1<<2;
320     static final int SCAN_UPDATE_SIGNATURE = 1<<3;
321     static final int SCAN_NEW_INSTALL = 1<<4;
322     static final int SCAN_NO_PATHS = 1<<5;
323     static final int SCAN_UPDATE_TIME = 1<<6;
324     static final int SCAN_DEFER_DEX = 1<<7;
325     static final int SCAN_BOOTING = 1<<8;
326     static final int SCAN_TRUSTED_OVERLAY = 1<<9;
327     static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10;
328     static final int SCAN_REPLACING = 1<<11;
329     static final int SCAN_REQUIRE_KNOWN = 1<<12;
330     static final int SCAN_MOVE = 1<<13;
331     static final int SCAN_INITIAL = 1<<14;
332 
333     static final int REMOVE_CHATTY = 1<<16;
334 
335     private static final int[] EMPTY_INT_ARRAY = new int[0];
336 
337     /**
338      * Timeout (in milliseconds) after which the watchdog should declare that
339      * our handler thread is wedged.  The usual default for such things is one
340      * minute but we sometimes do very lengthy I/O operations on this thread,
341      * such as installing multi-gigabyte applications, so ours needs to be longer.
342      */
343     private static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
344 
345     /**
346      * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
347      * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
348      * settings entry if available, otherwise we use the hardcoded default.  If it's been
349      * more than this long since the last fstrim, we force one during the boot sequence.
350      *
351      * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
352      * one gets run at the next available charging+idle time.  This final mandatory
353      * no-fstrim check kicks in only of the other scheduling criteria is never met.
354      */
355     private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
356 
357     /**
358      * Whether verification is enabled by default.
359      */
360     private static final boolean DEFAULT_VERIFY_ENABLE = true;
361 
362     /**
363      * The default maximum time to wait for the verification agent to return in
364      * milliseconds.
365      */
366     private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
367 
368     /**
369      * The default response for package verification timeout.
370      *
371      * This can be either PackageManager.VERIFICATION_ALLOW or
372      * PackageManager.VERIFICATION_REJECT.
373      */
374     private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
375 
376     static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
377 
378     static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
379             DEFAULT_CONTAINER_PACKAGE,
380             "com.android.defcontainer.DefaultContainerService");
381 
382     private static final String KILL_APP_REASON_GIDS_CHANGED =
383             "permission grant or revoke changed gids";
384 
385     private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
386             "permissions revoked";
387 
388     private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
389 
390     private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
391 
392     /** Permission grant: not grant the permission. */
393     private static final int GRANT_DENIED = 1;
394 
395     /** Permission grant: grant the permission as an install permission. */
396     private static final int GRANT_INSTALL = 2;
397 
398     /** Permission grant: grant the permission as an install permission for a legacy app. */
399     private static final int GRANT_INSTALL_LEGACY = 3;
400 
401     /** Permission grant: grant the permission as a runtime one. */
402     private static final int GRANT_RUNTIME = 4;
403 
404     /** Permission grant: grant as runtime a permission that was granted as an install time one. */
405     private static final int GRANT_UPGRADE = 5;
406 
407     /** Canonical intent used to identify what counts as a "web browser" app */
408     private static final Intent sBrowserIntent;
409     static {
410         sBrowserIntent = new Intent();
411         sBrowserIntent.setAction(Intent.ACTION_VIEW);
412         sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
413         sBrowserIntent.setData(Uri.parse("http:"));
414     }
415 
416     final ServiceThread mHandlerThread;
417 
418     final PackageHandler mHandler;
419 
420     /**
421      * Messages for {@link #mHandler} that need to wait for system ready before
422      * being dispatched.
423      */
424     private ArrayList<Message> mPostSystemReadyMessages;
425 
426     final int mSdkVersion = Build.VERSION.SDK_INT;
427 
428     final Context mContext;
429     final boolean mFactoryTest;
430     final boolean mOnlyCore;
431     final boolean mLazyDexOpt;
432     final long mDexOptLRUThresholdInMills;
433     final DisplayMetrics mMetrics;
434     final int mDefParseFlags;
435     final String[] mSeparateProcesses;
436     final boolean mIsUpgrade;
437 
438     // This is where all application persistent data goes.
439     final File mAppDataDir;
440 
441     // This is where all application persistent data goes for secondary users.
442     final File mUserAppDataDir;
443 
444     /** The location for ASEC container files on internal storage. */
445     final String mAsecInternalPath;
446 
447     // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
448     // LOCK HELD.  Can be called with mInstallLock held.
449     @GuardedBy("mInstallLock")
450     final Installer mInstaller;
451 
452     /** Directory where installed third-party apps stored */
453     final File mAppInstallDir;
454 
455     /**
456      * Directory to which applications installed internally have their
457      * 32 bit native libraries copied.
458      */
459     private File mAppLib32InstallDir;
460 
461     // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
462     // apps.
463     final File mDrmAppPrivateInstallDir;
464 
465     // ----------------------------------------------------------------
466 
467     // Lock for state used when installing and doing other long running
468     // operations.  Methods that must be called with this lock held have
469     // the suffix "LI".
470     final Object mInstallLock = new Object();
471 
472     // ----------------------------------------------------------------
473 
474     // Keys are String (package name), values are Package.  This also serves
475     // as the lock for the global state.  Methods that must be called with
476     // this lock held have the prefix "LP".
477     @GuardedBy("mPackages")
478     final ArrayMap<String, PackageParser.Package> mPackages =
479             new ArrayMap<String, PackageParser.Package>();
480 
481     // Tracks available target package names -> overlay package paths.
482     final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays =
483         new ArrayMap<String, ArrayMap<String, PackageParser.Package>>();
484 
485     /**
486      * Tracks new system packages [received in an OTA] that we expect to
487      * find updated user-installed versions. Keys are package name, values
488      * are package location.
489      */
490     final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
491 
492     /**
493      * Tracks existing system packages prior to receiving an OTA. Keys are package name.
494      */
495     final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
496     /**
497      * Whether or not system app permissions should be promoted from install to runtime.
498      */
499     boolean mPromoteSystemApps;
500 
501     final Settings mSettings;
502     boolean mRestoredSettings;
503 
504     // System configuration read by SystemConfig.
505     final int[] mGlobalGids;
506     final SparseArray<ArraySet<String>> mSystemPermissions;
507     final ArrayMap<String, FeatureInfo> mAvailableFeatures;
508 
509     // If mac_permissions.xml was found for seinfo labeling.
510     boolean mFoundPolicyFile;
511 
512     // If a recursive restorecon of /data/data/<pkg> is needed.
513     private boolean mShouldRestoreconData = SELinuxMMAC.shouldRestorecon();
514 
515     public static final class SharedLibraryEntry {
516         public final String path;
517         public final String apk;
518 
SharedLibraryEntry(String _path, String _apk)519         SharedLibraryEntry(String _path, String _apk) {
520             path = _path;
521             apk = _apk;
522         }
523     }
524 
525     // Currently known shared libraries.
526     final ArrayMap<String, SharedLibraryEntry> mSharedLibraries =
527             new ArrayMap<String, SharedLibraryEntry>();
528 
529     // All available activities, for your resolving pleasure.
530     final ActivityIntentResolver mActivities =
531             new ActivityIntentResolver();
532 
533     // All available receivers, for your resolving pleasure.
534     final ActivityIntentResolver mReceivers =
535             new ActivityIntentResolver();
536 
537     // All available services, for your resolving pleasure.
538     final ServiceIntentResolver mServices = new ServiceIntentResolver();
539 
540     // All available providers, for your resolving pleasure.
541     final ProviderIntentResolver mProviders = new ProviderIntentResolver();
542 
543     // Mapping from provider base names (first directory in content URI codePath)
544     // to the provider information.
545     final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
546             new ArrayMap<String, PackageParser.Provider>();
547 
548     // Mapping from instrumentation class names to info about them.
549     final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
550             new ArrayMap<ComponentName, PackageParser.Instrumentation>();
551 
552     // Mapping from permission names to info about them.
553     final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
554             new ArrayMap<String, PackageParser.PermissionGroup>();
555 
556     // Packages whose data we have transfered into another package, thus
557     // should no longer exist.
558     final ArraySet<String> mTransferedPackages = new ArraySet<String>();
559 
560     // Broadcast actions that are only available to the system.
561     final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>();
562 
563     /** List of packages waiting for verification. */
564     final SparseArray<PackageVerificationState> mPendingVerification
565             = new SparseArray<PackageVerificationState>();
566 
567     /** Set of packages associated with each app op permission. */
568     final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
569 
570     final PackageInstallerService mInstallerService;
571 
572     private final PackageDexOptimizer mPackageDexOptimizer;
573 
574     private AtomicInteger mNextMoveId = new AtomicInteger();
575     private final MoveCallbacks mMoveCallbacks;
576 
577     private final OnPermissionChangeListeners mOnPermissionChangeListeners;
578 
579     // Cache of users who need badging.
580     SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
581 
582     /** Token for keys in mPendingVerification. */
583     private int mPendingVerificationToken = 0;
584 
585     volatile boolean mSystemReady;
586     volatile boolean mSafeMode;
587     volatile boolean mHasSystemUidErrors;
588 
589     ApplicationInfo mAndroidApplication;
590     final ActivityInfo mResolveActivity = new ActivityInfo();
591     final ResolveInfo mResolveInfo = new ResolveInfo();
592     ComponentName mResolveComponentName;
593     PackageParser.Package mPlatformPackage;
594     ComponentName mCustomResolverComponentName;
595 
596     boolean mResolverReplaced = false;
597 
598     private final ComponentName mIntentFilterVerifierComponent;
599     private int mIntentFilterVerificationToken = 0;
600 
601     final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
602             = new SparseArray<IntentFilterVerificationState>();
603 
604     final DefaultPermissionGrantPolicy mDefaultPermissionPolicy =
605             new DefaultPermissionGrantPolicy(this);
606 
607     private static class IFVerificationParams {
608         PackageParser.Package pkg;
609         boolean replacing;
610         int userId;
611         int verifierUid;
612 
IFVerificationParams(PackageParser.Package _pkg, boolean _replacing, int _userId, int _verifierUid)613         public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
614                 int _userId, int _verifierUid) {
615             pkg = _pkg;
616             replacing = _replacing;
617             userId = _userId;
618             replacing = _replacing;
619             verifierUid = _verifierUid;
620         }
621     }
622 
623     private interface IntentFilterVerifier<T extends IntentFilter> {
addOneIntentFilterVerification(int verifierId, int userId, int verificationId, T filter, String packageName)624         boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
625                                                T filter, String packageName);
startVerifications(int userId)626         void startVerifications(int userId);
receiveVerificationResponse(int verificationId)627         void receiveVerificationResponse(int verificationId);
628     }
629 
630     private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
631         private Context mContext;
632         private ComponentName mIntentFilterVerifierComponent;
633         private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
634 
IntentVerifierProxy(Context context, ComponentName verifierComponent)635         public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
636             mContext = context;
637             mIntentFilterVerifierComponent = verifierComponent;
638         }
639 
getDefaultScheme()640         private String getDefaultScheme() {
641             return IntentFilter.SCHEME_HTTPS;
642         }
643 
644         @Override
startVerifications(int userId)645         public void startVerifications(int userId) {
646             // Launch verifications requests
647             int count = mCurrentIntentFilterVerifications.size();
648             for (int n=0; n<count; n++) {
649                 int verificationId = mCurrentIntentFilterVerifications.get(n);
650                 final IntentFilterVerificationState ivs =
651                         mIntentFilterVerificationStates.get(verificationId);
652 
653                 String packageName = ivs.getPackageName();
654 
655                 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
656                 final int filterCount = filters.size();
657                 ArraySet<String> domainsSet = new ArraySet<>();
658                 for (int m=0; m<filterCount; m++) {
659                     PackageParser.ActivityIntentInfo filter = filters.get(m);
660                     domainsSet.addAll(filter.getHostsList());
661                 }
662                 ArrayList<String> domainsList = new ArrayList<>(domainsSet);
663                 synchronized (mPackages) {
664                     if (mSettings.createIntentFilterVerificationIfNeededLPw(
665                             packageName, domainsList) != null) {
666                         scheduleWriteSettingsLocked();
667                     }
668                 }
669                 sendVerificationRequest(userId, verificationId, ivs);
670             }
671             mCurrentIntentFilterVerifications.clear();
672         }
673 
sendVerificationRequest(int userId, int verificationId, IntentFilterVerificationState ivs)674         private void sendVerificationRequest(int userId, int verificationId,
675                 IntentFilterVerificationState ivs) {
676 
677             Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
678             verificationIntent.putExtra(
679                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
680                     verificationId);
681             verificationIntent.putExtra(
682                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
683                     getDefaultScheme());
684             verificationIntent.putExtra(
685                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
686                     ivs.getHostsString());
687             verificationIntent.putExtra(
688                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
689                     ivs.getPackageName());
690             verificationIntent.setComponent(mIntentFilterVerifierComponent);
691             verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
692 
693             UserHandle user = new UserHandle(userId);
694             mContext.sendBroadcastAsUser(verificationIntent, user);
695             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
696                     "Sending IntentFilter verification broadcast");
697         }
698 
receiveVerificationResponse(int verificationId)699         public void receiveVerificationResponse(int verificationId) {
700             IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
701 
702             final boolean verified = ivs.isVerified();
703 
704             ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
705             final int count = filters.size();
706             if (DEBUG_DOMAIN_VERIFICATION) {
707                 Slog.i(TAG, "Received verification response " + verificationId
708                         + " for " + count + " filters, verified=" + verified);
709             }
710             for (int n=0; n<count; n++) {
711                 PackageParser.ActivityIntentInfo filter = filters.get(n);
712                 filter.setVerified(verified);
713 
714                 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
715                         + " verified with result:" + verified + " and hosts:"
716                         + ivs.getHostsString());
717             }
718 
719             mIntentFilterVerificationStates.remove(verificationId);
720 
721             final String packageName = ivs.getPackageName();
722             IntentFilterVerificationInfo ivi = null;
723 
724             synchronized (mPackages) {
725                 ivi = mSettings.getIntentFilterVerificationLPr(packageName);
726             }
727             if (ivi == null) {
728                 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
729                         + verificationId + " packageName:" + packageName);
730                 return;
731             }
732             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
733                     "Updating IntentFilterVerificationInfo for package " + packageName
734                             +" verificationId:" + verificationId);
735 
736             synchronized (mPackages) {
737                 if (verified) {
738                     ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
739                 } else {
740                     ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
741                 }
742                 scheduleWriteSettingsLocked();
743 
744                 final int userId = ivs.getUserId();
745                 if (userId != UserHandle.USER_ALL) {
746                     final int userStatus =
747                             mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
748 
749                     int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
750                     boolean needUpdate = false;
751 
752                     // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
753                     // already been set by the User thru the Disambiguation dialog
754                     switch (userStatus) {
755                         case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
756                             if (verified) {
757                                 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
758                             } else {
759                                 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
760                             }
761                             needUpdate = true;
762                             break;
763 
764                         case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
765                             if (verified) {
766                                 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
767                                 needUpdate = true;
768                             }
769                             break;
770 
771                         default:
772                             // Nothing to do
773                     }
774 
775                     if (needUpdate) {
776                         mSettings.updateIntentFilterVerificationStatusLPw(
777                                 packageName, updatedStatus, userId);
778                         scheduleWritePackageRestrictionsLocked(userId);
779                     }
780                 }
781             }
782         }
783 
784         @Override
addOneIntentFilterVerification(int verifierUid, int userId, int verificationId, ActivityIntentInfo filter, String packageName)785         public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
786                     ActivityIntentInfo filter, String packageName) {
787             if (!hasValidDomains(filter)) {
788                 return false;
789             }
790             IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
791             if (ivs == null) {
792                 ivs = createDomainVerificationState(verifierUid, userId, verificationId,
793                         packageName);
794             }
795             if (DEBUG_DOMAIN_VERIFICATION) {
796                 Slog.d(TAG, "Adding verification filter for " + packageName + " : " + filter);
797             }
798             ivs.addFilter(filter);
799             return true;
800         }
801 
createDomainVerificationState(int verifierUid, int userId, int verificationId, String packageName)802         private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
803                 int userId, int verificationId, String packageName) {
804             IntentFilterVerificationState ivs = new IntentFilterVerificationState(
805                     verifierUid, userId, packageName);
806             ivs.setPendingState();
807             synchronized (mPackages) {
808                 mIntentFilterVerificationStates.append(verificationId, ivs);
809                 mCurrentIntentFilterVerifications.add(verificationId);
810             }
811             return ivs;
812         }
813     }
814 
hasValidDomains(ActivityIntentInfo filter)815     private static boolean hasValidDomains(ActivityIntentInfo filter) {
816         return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
817                 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
818                         filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
819     }
820 
821     private IntentFilterVerifier mIntentFilterVerifier;
822 
823     // Set of pending broadcasts for aggregating enable/disable of components.
824     static class PendingPackageBroadcasts {
825         // for each user id, a map of <package name -> components within that package>
826         final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
827 
PendingPackageBroadcasts()828         public PendingPackageBroadcasts() {
829             mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
830         }
831 
get(int userId, String packageName)832         public ArrayList<String> get(int userId, String packageName) {
833             ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
834             return packages.get(packageName);
835         }
836 
put(int userId, String packageName, ArrayList<String> components)837         public void put(int userId, String packageName, ArrayList<String> components) {
838             ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
839             packages.put(packageName, components);
840         }
841 
remove(int userId, String packageName)842         public void remove(int userId, String packageName) {
843             ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
844             if (packages != null) {
845                 packages.remove(packageName);
846             }
847         }
848 
remove(int userId)849         public void remove(int userId) {
850             mUidMap.remove(userId);
851         }
852 
userIdCount()853         public int userIdCount() {
854             return mUidMap.size();
855         }
856 
userIdAt(int n)857         public int userIdAt(int n) {
858             return mUidMap.keyAt(n);
859         }
860 
packagesForUserId(int userId)861         public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
862             return mUidMap.get(userId);
863         }
864 
size()865         public int size() {
866             // total number of pending broadcast entries across all userIds
867             int num = 0;
868             for (int i = 0; i< mUidMap.size(); i++) {
869                 num += mUidMap.valueAt(i).size();
870             }
871             return num;
872         }
873 
clear()874         public void clear() {
875             mUidMap.clear();
876         }
877 
getOrAllocate(int userId)878         private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
879             ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
880             if (map == null) {
881                 map = new ArrayMap<String, ArrayList<String>>();
882                 mUidMap.put(userId, map);
883             }
884             return map;
885         }
886     }
887     final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
888 
889     // Service Connection to remote media container service to copy
890     // package uri's from external media onto secure containers
891     // or internal storage.
892     private IMediaContainerService mContainerService = null;
893 
894     static final int SEND_PENDING_BROADCAST = 1;
895     static final int MCS_BOUND = 3;
896     static final int END_COPY = 4;
897     static final int INIT_COPY = 5;
898     static final int MCS_UNBIND = 6;
899     static final int START_CLEANING_PACKAGE = 7;
900     static final int FIND_INSTALL_LOC = 8;
901     static final int POST_INSTALL = 9;
902     static final int MCS_RECONNECT = 10;
903     static final int MCS_GIVE_UP = 11;
904     static final int UPDATED_MEDIA_STATUS = 12;
905     static final int WRITE_SETTINGS = 13;
906     static final int WRITE_PACKAGE_RESTRICTIONS = 14;
907     static final int PACKAGE_VERIFIED = 15;
908     static final int CHECK_PENDING_VERIFICATION = 16;
909     static final int START_INTENT_FILTER_VERIFICATIONS = 17;
910     static final int INTENT_FILTER_VERIFIED = 18;
911 
912     static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
913 
914     // Delay time in millisecs
915     static final int BROADCAST_DELAY = 10 * 1000;
916 
917     static UserManagerService sUserManager;
918 
919     // Stores a list of users whose package restrictions file needs to be updated
920     private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
921 
922     final private DefaultContainerConnection mDefContainerConn =
923             new DefaultContainerConnection();
924     class DefaultContainerConnection implements ServiceConnection {
onServiceConnected(ComponentName name, IBinder service)925         public void onServiceConnected(ComponentName name, IBinder service) {
926             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
927             IMediaContainerService imcs =
928                 IMediaContainerService.Stub.asInterface(service);
929             mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
930         }
931 
onServiceDisconnected(ComponentName name)932         public void onServiceDisconnected(ComponentName name) {
933             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
934         }
935     }
936 
937     // Recordkeeping of restore-after-install operations that are currently in flight
938     // between the Package Manager and the Backup Manager
939     class PostInstallData {
940         public InstallArgs args;
941         public PackageInstalledInfo res;
942 
PostInstallData(InstallArgs _a, PackageInstalledInfo _r)943         PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
944             args = _a;
945             res = _r;
946         }
947     }
948 
949     final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
950     int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
951 
952     // XML tags for backup/restore of various bits of state
953     private static final String TAG_PREFERRED_BACKUP = "pa";
954     private static final String TAG_DEFAULT_APPS = "da";
955     private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
956 
957     final String mRequiredVerifierPackage;
958     final String mRequiredInstallerPackage;
959 
960     private final PackageUsage mPackageUsage = new PackageUsage();
961 
962     private class PackageUsage {
963         private static final int WRITE_INTERVAL
964             = (DEBUG_DEXOPT) ? 0 : 30*60*1000; // 30m in ms
965 
966         private final Object mFileLock = new Object();
967         private final AtomicLong mLastWritten = new AtomicLong(0);
968         private final AtomicBoolean mBackgroundWriteRunning = new AtomicBoolean(false);
969 
970         private boolean mIsHistoricalPackageUsageAvailable = true;
971 
isHistoricalPackageUsageAvailable()972         boolean isHistoricalPackageUsageAvailable() {
973             return mIsHistoricalPackageUsageAvailable;
974         }
975 
write(boolean force)976         void write(boolean force) {
977             if (force) {
978                 writeInternal();
979                 return;
980             }
981             if (SystemClock.elapsedRealtime() - mLastWritten.get() < WRITE_INTERVAL
982                 && !DEBUG_DEXOPT) {
983                 return;
984             }
985             if (mBackgroundWriteRunning.compareAndSet(false, true)) {
986                 new Thread("PackageUsage_DiskWriter") {
987                     @Override
988                     public void run() {
989                         try {
990                             writeInternal();
991                         } finally {
992                             mBackgroundWriteRunning.set(false);
993                         }
994                     }
995                 }.start();
996             }
997         }
998 
writeInternal()999         private void writeInternal() {
1000             synchronized (mPackages) {
1001                 synchronized (mFileLock) {
1002                     AtomicFile file = getFile();
1003                     FileOutputStream f = null;
1004                     try {
1005                         f = file.startWrite();
1006                         BufferedOutputStream out = new BufferedOutputStream(f);
1007                         FileUtils.setPermissions(file.getBaseFile().getPath(), 0640, SYSTEM_UID, PACKAGE_INFO_GID);
1008                         StringBuilder sb = new StringBuilder();
1009                         for (PackageParser.Package pkg : mPackages.values()) {
1010                             if (pkg.mLastPackageUsageTimeInMills == 0) {
1011                                 continue;
1012                             }
1013                             sb.setLength(0);
1014                             sb.append(pkg.packageName);
1015                             sb.append(' ');
1016                             sb.append((long)pkg.mLastPackageUsageTimeInMills);
1017                             sb.append('\n');
1018                             out.write(sb.toString().getBytes(StandardCharsets.US_ASCII));
1019                         }
1020                         out.flush();
1021                         file.finishWrite(f);
1022                     } catch (IOException e) {
1023                         if (f != null) {
1024                             file.failWrite(f);
1025                         }
1026                         Log.e(TAG, "Failed to write package usage times", e);
1027                     }
1028                 }
1029             }
1030             mLastWritten.set(SystemClock.elapsedRealtime());
1031         }
1032 
readLP()1033         void readLP() {
1034             synchronized (mFileLock) {
1035                 AtomicFile file = getFile();
1036                 BufferedInputStream in = null;
1037                 try {
1038                     in = new BufferedInputStream(file.openRead());
1039                     StringBuffer sb = new StringBuffer();
1040                     while (true) {
1041                         String packageName = readToken(in, sb, ' ');
1042                         if (packageName == null) {
1043                             break;
1044                         }
1045                         String timeInMillisString = readToken(in, sb, '\n');
1046                         if (timeInMillisString == null) {
1047                             throw new IOException("Failed to find last usage time for package "
1048                                                   + packageName);
1049                         }
1050                         PackageParser.Package pkg = mPackages.get(packageName);
1051                         if (pkg == null) {
1052                             continue;
1053                         }
1054                         long timeInMillis;
1055                         try {
1056                             timeInMillis = Long.parseLong(timeInMillisString.toString());
1057                         } catch (NumberFormatException e) {
1058                             throw new IOException("Failed to parse " + timeInMillisString
1059                                                   + " as a long.", e);
1060                         }
1061                         pkg.mLastPackageUsageTimeInMills = timeInMillis;
1062                     }
1063                 } catch (FileNotFoundException expected) {
1064                     mIsHistoricalPackageUsageAvailable = false;
1065                 } catch (IOException e) {
1066                     Log.w(TAG, "Failed to read package usage times", e);
1067                 } finally {
1068                     IoUtils.closeQuietly(in);
1069                 }
1070             }
1071             mLastWritten.set(SystemClock.elapsedRealtime());
1072         }
1073 
readToken(InputStream in, StringBuffer sb, char endOfToken)1074         private String readToken(InputStream in, StringBuffer sb, char endOfToken)
1075                 throws IOException {
1076             sb.setLength(0);
1077             while (true) {
1078                 int ch = in.read();
1079                 if (ch == -1) {
1080                     if (sb.length() == 0) {
1081                         return null;
1082                     }
1083                     throw new IOException("Unexpected EOF");
1084                 }
1085                 if (ch == endOfToken) {
1086                     return sb.toString();
1087                 }
1088                 sb.append((char)ch);
1089             }
1090         }
1091 
getFile()1092         private AtomicFile getFile() {
1093             File dataDir = Environment.getDataDirectory();
1094             File systemDir = new File(dataDir, "system");
1095             File fname = new File(systemDir, "package-usage.list");
1096             return new AtomicFile(fname);
1097         }
1098     }
1099 
1100     class PackageHandler extends Handler {
1101         private boolean mBound = false;
1102         final ArrayList<HandlerParams> mPendingInstalls =
1103             new ArrayList<HandlerParams>();
1104 
connectToService()1105         private boolean connectToService() {
1106             if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1107                     " DefaultContainerService");
1108             Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1109             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1110             if (mContext.bindServiceAsUser(service, mDefContainerConn,
1111                     Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
1112                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1113                 mBound = true;
1114                 return true;
1115             }
1116             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1117             return false;
1118         }
1119 
disconnectService()1120         private void disconnectService() {
1121             mContainerService = null;
1122             mBound = false;
1123             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1124             mContext.unbindService(mDefContainerConn);
1125             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1126         }
1127 
PackageHandler(Looper looper)1128         PackageHandler(Looper looper) {
1129             super(looper);
1130         }
1131 
handleMessage(Message msg)1132         public void handleMessage(Message msg) {
1133             try {
1134                 doHandleMessage(msg);
1135             } finally {
1136                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1137             }
1138         }
1139 
doHandleMessage(Message msg)1140         void doHandleMessage(Message msg) {
1141             switch (msg.what) {
1142                 case INIT_COPY: {
1143                     HandlerParams params = (HandlerParams) msg.obj;
1144                     int idx = mPendingInstalls.size();
1145                     if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1146                     // If a bind was already initiated we dont really
1147                     // need to do anything. The pending install
1148                     // will be processed later on.
1149                     if (!mBound) {
1150                         // If this is the only one pending we might
1151                         // have to bind to the service again.
1152                         if (!connectToService()) {
1153                             Slog.e(TAG, "Failed to bind to media container service");
1154                             params.serviceError();
1155                             return;
1156                         } else {
1157                             // Once we bind to the service, the first
1158                             // pending request will be processed.
1159                             mPendingInstalls.add(idx, params);
1160                         }
1161                     } else {
1162                         mPendingInstalls.add(idx, params);
1163                         // Already bound to the service. Just make
1164                         // sure we trigger off processing the first request.
1165                         if (idx == 0) {
1166                             mHandler.sendEmptyMessage(MCS_BOUND);
1167                         }
1168                     }
1169                     break;
1170                 }
1171                 case MCS_BOUND: {
1172                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1173                     if (msg.obj != null) {
1174                         mContainerService = (IMediaContainerService) msg.obj;
1175                     }
1176                     if (mContainerService == null) {
1177                         if (!mBound) {
1178                             // Something seriously wrong since we are not bound and we are not
1179                             // waiting for connection. Bail out.
1180                             Slog.e(TAG, "Cannot bind to media container service");
1181                             for (HandlerParams params : mPendingInstalls) {
1182                                 // Indicate service bind error
1183                                 params.serviceError();
1184                             }
1185                             mPendingInstalls.clear();
1186                         } else {
1187                             Slog.w(TAG, "Waiting to connect to media container service");
1188                         }
1189                     } else if (mPendingInstalls.size() > 0) {
1190                         HandlerParams params = mPendingInstalls.get(0);
1191                         if (params != null) {
1192                             if (params.startCopy()) {
1193                                 // We are done...  look for more work or to
1194                                 // go idle.
1195                                 if (DEBUG_SD_INSTALL) Log.i(TAG,
1196                                         "Checking for more work or unbind...");
1197                                 // Delete pending install
1198                                 if (mPendingInstalls.size() > 0) {
1199                                     mPendingInstalls.remove(0);
1200                                 }
1201                                 if (mPendingInstalls.size() == 0) {
1202                                     if (mBound) {
1203                                         if (DEBUG_SD_INSTALL) Log.i(TAG,
1204                                                 "Posting delayed MCS_UNBIND");
1205                                         removeMessages(MCS_UNBIND);
1206                                         Message ubmsg = obtainMessage(MCS_UNBIND);
1207                                         // Unbind after a little delay, to avoid
1208                                         // continual thrashing.
1209                                         sendMessageDelayed(ubmsg, 10000);
1210                                     }
1211                                 } else {
1212                                     // There are more pending requests in queue.
1213                                     // Just post MCS_BOUND message to trigger processing
1214                                     // of next pending install.
1215                                     if (DEBUG_SD_INSTALL) Log.i(TAG,
1216                                             "Posting MCS_BOUND for next work");
1217                                     mHandler.sendEmptyMessage(MCS_BOUND);
1218                                 }
1219                             }
1220                         }
1221                     } else {
1222                         // Should never happen ideally.
1223                         Slog.w(TAG, "Empty queue");
1224                     }
1225                     break;
1226                 }
1227                 case MCS_RECONNECT: {
1228                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1229                     if (mPendingInstalls.size() > 0) {
1230                         if (mBound) {
1231                             disconnectService();
1232                         }
1233                         if (!connectToService()) {
1234                             Slog.e(TAG, "Failed to bind to media container service");
1235                             for (HandlerParams params : mPendingInstalls) {
1236                                 // Indicate service bind error
1237                                 params.serviceError();
1238                             }
1239                             mPendingInstalls.clear();
1240                         }
1241                     }
1242                     break;
1243                 }
1244                 case MCS_UNBIND: {
1245                     // If there is no actual work left, then time to unbind.
1246                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1247 
1248                     if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1249                         if (mBound) {
1250                             if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1251 
1252                             disconnectService();
1253                         }
1254                     } else if (mPendingInstalls.size() > 0) {
1255                         // There are more pending requests in queue.
1256                         // Just post MCS_BOUND message to trigger processing
1257                         // of next pending install.
1258                         mHandler.sendEmptyMessage(MCS_BOUND);
1259                     }
1260 
1261                     break;
1262                 }
1263                 case MCS_GIVE_UP: {
1264                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1265                     mPendingInstalls.remove(0);
1266                     break;
1267                 }
1268                 case SEND_PENDING_BROADCAST: {
1269                     String packages[];
1270                     ArrayList<String> components[];
1271                     int size = 0;
1272                     int uids[];
1273                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1274                     synchronized (mPackages) {
1275                         if (mPendingBroadcasts == null) {
1276                             return;
1277                         }
1278                         size = mPendingBroadcasts.size();
1279                         if (size <= 0) {
1280                             // Nothing to be done. Just return
1281                             return;
1282                         }
1283                         packages = new String[size];
1284                         components = new ArrayList[size];
1285                         uids = new int[size];
1286                         int i = 0;  // filling out the above arrays
1287 
1288                         for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1289                             int packageUserId = mPendingBroadcasts.userIdAt(n);
1290                             Iterator<Map.Entry<String, ArrayList<String>>> it
1291                                     = mPendingBroadcasts.packagesForUserId(packageUserId)
1292                                             .entrySet().iterator();
1293                             while (it.hasNext() && i < size) {
1294                                 Map.Entry<String, ArrayList<String>> ent = it.next();
1295                                 packages[i] = ent.getKey();
1296                                 components[i] = ent.getValue();
1297                                 PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1298                                 uids[i] = (ps != null)
1299                                         ? UserHandle.getUid(packageUserId, ps.appId)
1300                                         : -1;
1301                                 i++;
1302                             }
1303                         }
1304                         size = i;
1305                         mPendingBroadcasts.clear();
1306                     }
1307                     // Send broadcasts
1308                     for (int i = 0; i < size; i++) {
1309                         sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1310                     }
1311                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1312                     break;
1313                 }
1314                 case START_CLEANING_PACKAGE: {
1315                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1316                     final String packageName = (String)msg.obj;
1317                     final int userId = msg.arg1;
1318                     final boolean andCode = msg.arg2 != 0;
1319                     synchronized (mPackages) {
1320                         if (userId == UserHandle.USER_ALL) {
1321                             int[] users = sUserManager.getUserIds();
1322                             for (int user : users) {
1323                                 mSettings.addPackageToCleanLPw(
1324                                         new PackageCleanItem(user, packageName, andCode));
1325                             }
1326                         } else {
1327                             mSettings.addPackageToCleanLPw(
1328                                     new PackageCleanItem(userId, packageName, andCode));
1329                         }
1330                     }
1331                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1332                     startCleaningPackages();
1333                 } break;
1334                 case POST_INSTALL: {
1335                     if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1336                     PostInstallData data = mRunningInstalls.get(msg.arg1);
1337                     mRunningInstalls.delete(msg.arg1);
1338                     boolean deleteOld = false;
1339 
1340                     if (data != null) {
1341                         InstallArgs args = data.args;
1342                         PackageInstalledInfo res = data.res;
1343 
1344                         if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1345                             final String packageName = res.pkg.applicationInfo.packageName;
1346                             res.removedInfo.sendBroadcast(false, true, false);
1347                             Bundle extras = new Bundle(1);
1348                             extras.putInt(Intent.EXTRA_UID, res.uid);
1349 
1350                             // Now that we successfully installed the package, grant runtime
1351                             // permissions if requested before broadcasting the install.
1352                             if ((args.installFlags
1353                                     & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0) {
1354                                 grantRequestedRuntimePermissions(res.pkg, args.user.getIdentifier(),
1355                                         args.installGrantPermissions);
1356                             }
1357 
1358                             // Determine the set of users who are adding this
1359                             // package for the first time vs. those who are seeing
1360                             // an update.
1361                             int[] firstUsers;
1362                             int[] updateUsers = new int[0];
1363                             if (res.origUsers == null || res.origUsers.length == 0) {
1364                                 firstUsers = res.newUsers;
1365                             } else {
1366                                 firstUsers = new int[0];
1367                                 for (int i=0; i<res.newUsers.length; i++) {
1368                                     int user = res.newUsers[i];
1369                                     boolean isNew = true;
1370                                     for (int j=0; j<res.origUsers.length; j++) {
1371                                         if (res.origUsers[j] == user) {
1372                                             isNew = false;
1373                                             break;
1374                                         }
1375                                     }
1376                                     if (isNew) {
1377                                         int[] newFirst = new int[firstUsers.length+1];
1378                                         System.arraycopy(firstUsers, 0, newFirst, 0,
1379                                                 firstUsers.length);
1380                                         newFirst[firstUsers.length] = user;
1381                                         firstUsers = newFirst;
1382                                     } else {
1383                                         int[] newUpdate = new int[updateUsers.length+1];
1384                                         System.arraycopy(updateUsers, 0, newUpdate, 0,
1385                                                 updateUsers.length);
1386                                         newUpdate[updateUsers.length] = user;
1387                                         updateUsers = newUpdate;
1388                                     }
1389                                 }
1390                             }
1391                             sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
1392                                     packageName, extras, null, null, firstUsers);
1393                             final boolean update = res.removedInfo.removedPackage != null;
1394                             if (update) {
1395                                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
1396                             }
1397                             sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
1398                                     packageName, extras, null, null, updateUsers);
1399                             if (update) {
1400                                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
1401                                         packageName, extras, null, null, updateUsers);
1402                                 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
1403                                         null, null, packageName, null, updateUsers);
1404 
1405                                 // treat asec-hosted packages like removable media on upgrade
1406                                 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
1407                                     if (DEBUG_INSTALL) {
1408                                         Slog.i(TAG, "upgrading pkg " + res.pkg
1409                                                 + " is ASEC-hosted -> AVAILABLE");
1410                                     }
1411                                     int[] uidArray = new int[] { res.pkg.applicationInfo.uid };
1412                                     ArrayList<String> pkgList = new ArrayList<String>(1);
1413                                     pkgList.add(packageName);
1414                                     sendResourcesChangedBroadcast(true, true,
1415                                             pkgList,uidArray, null);
1416                                 }
1417                             }
1418                             if (res.removedInfo.args != null) {
1419                                 // Remove the replaced package's older resources safely now
1420                                 deleteOld = true;
1421                             }
1422 
1423                             // If this app is a browser and it's newly-installed for some
1424                             // users, clear any default-browser state in those users
1425                             if (firstUsers.length > 0) {
1426                                 // the app's nature doesn't depend on the user, so we can just
1427                                 // check its browser nature in any user and generalize.
1428                                 if (packageIsBrowser(packageName, firstUsers[0])) {
1429                                     synchronized (mPackages) {
1430                                         for (int userId : firstUsers) {
1431                                             mSettings.setDefaultBrowserPackageNameLPw(null, userId);
1432                                         }
1433                                     }
1434                                 }
1435                             }
1436                             // Log current value of "unknown sources" setting
1437                             EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
1438                                 getUnknownSourcesSettings());
1439                         }
1440                         // Force a gc to clear up things
1441                         Runtime.getRuntime().gc();
1442                         // We delete after a gc for applications  on sdcard.
1443                         if (deleteOld) {
1444                             synchronized (mInstallLock) {
1445                                 res.removedInfo.args.doPostDeleteLI(true);
1446                             }
1447                         }
1448                         if (args.observer != null) {
1449                             try {
1450                                 Bundle extras = extrasForInstallResult(res);
1451                                 args.observer.onPackageInstalled(res.name, res.returnCode,
1452                                         res.returnMsg, extras);
1453                             } catch (RemoteException e) {
1454                                 Slog.i(TAG, "Observer no longer exists.");
1455                             }
1456                         }
1457                     } else {
1458                         Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1459                     }
1460                 } break;
1461                 case UPDATED_MEDIA_STATUS: {
1462                     if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1463                     boolean reportStatus = msg.arg1 == 1;
1464                     boolean doGc = msg.arg2 == 1;
1465                     if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1466                     if (doGc) {
1467                         // Force a gc to clear up stale containers.
1468                         Runtime.getRuntime().gc();
1469                     }
1470                     if (msg.obj != null) {
1471                         @SuppressWarnings("unchecked")
1472                         Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1473                         if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1474                         // Unload containers
1475                         unloadAllContainers(args);
1476                     }
1477                     if (reportStatus) {
1478                         try {
1479                             if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back");
1480                             PackageHelper.getMountService().finishMediaUpdate();
1481                         } catch (RemoteException e) {
1482                             Log.e(TAG, "MountService not running?");
1483                         }
1484                     }
1485                 } break;
1486                 case WRITE_SETTINGS: {
1487                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1488                     synchronized (mPackages) {
1489                         removeMessages(WRITE_SETTINGS);
1490                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1491                         mSettings.writeLPr();
1492                         mDirtyUsers.clear();
1493                     }
1494                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1495                 } break;
1496                 case WRITE_PACKAGE_RESTRICTIONS: {
1497                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1498                     synchronized (mPackages) {
1499                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1500                         for (int userId : mDirtyUsers) {
1501                             mSettings.writePackageRestrictionsLPr(userId);
1502                         }
1503                         mDirtyUsers.clear();
1504                     }
1505                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1506                 } break;
1507                 case CHECK_PENDING_VERIFICATION: {
1508                     final int verificationId = msg.arg1;
1509                     final PackageVerificationState state = mPendingVerification.get(verificationId);
1510 
1511                     if ((state != null) && !state.timeoutExtended()) {
1512                         final InstallArgs args = state.getInstallArgs();
1513                         final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1514 
1515                         Slog.i(TAG, "Verification timed out for " + originUri);
1516                         mPendingVerification.remove(verificationId);
1517 
1518                         int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1519 
1520                         if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
1521                             Slog.i(TAG, "Continuing with installation of " + originUri);
1522                             state.setVerifierResponse(Binder.getCallingUid(),
1523                                     PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1524                             broadcastPackageVerified(verificationId, originUri,
1525                                     PackageManager.VERIFICATION_ALLOW,
1526                                     state.getInstallArgs().getUser());
1527                             try {
1528                                 ret = args.copyApk(mContainerService, true);
1529                             } catch (RemoteException e) {
1530                                 Slog.e(TAG, "Could not contact the ContainerService");
1531                             }
1532                         } else {
1533                             broadcastPackageVerified(verificationId, originUri,
1534                                     PackageManager.VERIFICATION_REJECT,
1535                                     state.getInstallArgs().getUser());
1536                         }
1537 
1538                         processPendingInstall(args, ret);
1539                         mHandler.sendEmptyMessage(MCS_UNBIND);
1540                     }
1541                     break;
1542                 }
1543                 case PACKAGE_VERIFIED: {
1544                     final int verificationId = msg.arg1;
1545 
1546                     final PackageVerificationState state = mPendingVerification.get(verificationId);
1547                     if (state == null) {
1548                         Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1549                         break;
1550                     }
1551 
1552                     final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1553 
1554                     state.setVerifierResponse(response.callerUid, response.code);
1555 
1556                     if (state.isVerificationComplete()) {
1557                         mPendingVerification.remove(verificationId);
1558 
1559                         final InstallArgs args = state.getInstallArgs();
1560                         final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1561 
1562                         int ret;
1563                         if (state.isInstallAllowed()) {
1564                             ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1565                             broadcastPackageVerified(verificationId, originUri,
1566                                     response.code, state.getInstallArgs().getUser());
1567                             try {
1568                                 ret = args.copyApk(mContainerService, true);
1569                             } catch (RemoteException e) {
1570                                 Slog.e(TAG, "Could not contact the ContainerService");
1571                             }
1572                         } else {
1573                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1574                         }
1575 
1576                         processPendingInstall(args, ret);
1577 
1578                         mHandler.sendEmptyMessage(MCS_UNBIND);
1579                     }
1580 
1581                     break;
1582                 }
1583                 case START_INTENT_FILTER_VERIFICATIONS: {
1584                     IFVerificationParams params = (IFVerificationParams) msg.obj;
1585                     verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1586                             params.replacing, params.pkg);
1587                     break;
1588                 }
1589                 case INTENT_FILTER_VERIFIED: {
1590                     final int verificationId = msg.arg1;
1591 
1592                     final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1593                             verificationId);
1594                     if (state == null) {
1595                         Slog.w(TAG, "Invalid IntentFilter verification token "
1596                                 + verificationId + " received");
1597                         break;
1598                     }
1599 
1600                     final int userId = state.getUserId();
1601 
1602                     if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1603                             "Processing IntentFilter verification with token:"
1604                             + verificationId + " and userId:" + userId);
1605 
1606                     final IntentFilterVerificationResponse response =
1607                             (IntentFilterVerificationResponse) msg.obj;
1608 
1609                     state.setVerifierResponse(response.callerUid, response.code);
1610 
1611                     if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1612                             "IntentFilter verification with token:" + verificationId
1613                             + " and userId:" + userId
1614                             + " is settings verifier response with response code:"
1615                             + response.code);
1616 
1617                     if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1618                         if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1619                                 + response.getFailedDomainsString());
1620                     }
1621 
1622                     if (state.isVerificationComplete()) {
1623                         mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1624                     } else {
1625                         if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1626                                 "IntentFilter verification with token:" + verificationId
1627                                 + " was not said to be complete");
1628                     }
1629 
1630                     break;
1631                 }
1632             }
1633         }
1634     }
1635 
1636     private StorageEventListener mStorageListener = new StorageEventListener() {
1637         @Override
1638         public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
1639             if (vol.type == VolumeInfo.TYPE_PRIVATE) {
1640                 if (vol.state == VolumeInfo.STATE_MOUNTED) {
1641                     final String volumeUuid = vol.getFsUuid();
1642 
1643                     // Clean up any users or apps that were removed or recreated
1644                     // while this volume was missing
1645                     reconcileUsers(volumeUuid);
1646                     reconcileApps(volumeUuid);
1647 
1648                     // Clean up any install sessions that expired or were
1649                     // cancelled while this volume was missing
1650                     mInstallerService.onPrivateVolumeMounted(volumeUuid);
1651 
1652                     loadPrivatePackages(vol);
1653 
1654                 } else if (vol.state == VolumeInfo.STATE_EJECTING) {
1655                     unloadPrivatePackages(vol);
1656                 }
1657             }
1658 
1659             if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) {
1660                 if (vol.state == VolumeInfo.STATE_MOUNTED) {
1661                     updateExternalMediaStatus(true, false);
1662                 } else if (vol.state == VolumeInfo.STATE_EJECTING) {
1663                     updateExternalMediaStatus(false, false);
1664                 }
1665             }
1666         }
1667 
1668         @Override
1669         public void onVolumeForgotten(String fsUuid) {
1670             if (TextUtils.isEmpty(fsUuid)) {
1671                 Slog.w(TAG, "Forgetting internal storage is probably a mistake; ignoring");
1672                 return;
1673             }
1674 
1675             // Remove any apps installed on the forgotten volume
1676             synchronized (mPackages) {
1677                 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
1678                 for (PackageSetting ps : packages) {
1679                     Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
1680                     deletePackage(ps.name, new LegacyPackageDeleteObserver(null).getBinder(),
1681                             UserHandle.USER_OWNER, PackageManager.DELETE_ALL_USERS);
1682                 }
1683 
1684                 mSettings.onVolumeForgotten(fsUuid);
1685                 mSettings.writeLPr();
1686             }
1687         }
1688     };
1689 
grantRequestedRuntimePermissions(PackageParser.Package pkg, int userId, String[] grantedPermissions)1690     private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int userId,
1691             String[] grantedPermissions) {
1692         if (userId >= UserHandle.USER_OWNER) {
1693             grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions);
1694         } else if (userId == UserHandle.USER_ALL) {
1695             final int[] userIds;
1696             synchronized (mPackages) {
1697                 userIds = UserManagerService.getInstance().getUserIds();
1698             }
1699             for (int someUserId : userIds) {
1700                 grantRequestedRuntimePermissionsForUser(pkg, someUserId, grantedPermissions);
1701             }
1702         }
1703 
1704         // We could have touched GID membership, so flush out packages.list
1705         synchronized (mPackages) {
1706             mSettings.writePackageListLPr();
1707         }
1708     }
1709 
grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId, String[] grantedPermissions)1710     private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
1711             String[] grantedPermissions) {
1712         SettingBase sb = (SettingBase) pkg.mExtras;
1713         if (sb == null) {
1714             return;
1715         }
1716 
1717         synchronized (mPackages) {
1718             for (String permission : pkg.requestedPermissions) {
1719                 BasePermission bp = mSettings.mPermissions.get(permission);
1720                 if (bp != null && (bp.isRuntime() || bp.isDevelopment())
1721                         && (grantedPermissions == null
1722                                || ArrayUtils.contains(grantedPermissions, permission))
1723                         && (getPermissionFlags(permission, pkg.packageName, userId)
1724                                 & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) == 0) {
1725                     grantRuntimePermission(pkg.packageName, permission, userId);
1726                 }
1727             }
1728         }
1729     }
1730 
extrasForInstallResult(PackageInstalledInfo res)1731     Bundle extrasForInstallResult(PackageInstalledInfo res) {
1732         Bundle extras = null;
1733         switch (res.returnCode) {
1734             case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
1735                 extras = new Bundle();
1736                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
1737                         res.origPermission);
1738                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
1739                         res.origPackage);
1740                 break;
1741             }
1742             case PackageManager.INSTALL_SUCCEEDED: {
1743                 extras = new Bundle();
1744                 extras.putBoolean(Intent.EXTRA_REPLACING,
1745                         res.removedInfo != null && res.removedInfo.removedPackage != null);
1746                 break;
1747             }
1748         }
1749         return extras;
1750     }
1751 
scheduleWriteSettingsLocked()1752     void scheduleWriteSettingsLocked() {
1753         if (!mHandler.hasMessages(WRITE_SETTINGS)) {
1754             mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
1755         }
1756     }
1757 
scheduleWritePackageRestrictionsLocked(int userId)1758     void scheduleWritePackageRestrictionsLocked(int userId) {
1759         if (!sUserManager.exists(userId)) return;
1760         mDirtyUsers.add(userId);
1761         if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
1762             mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
1763         }
1764     }
1765 
main(Context context, Installer installer, boolean factoryTest, boolean onlyCore)1766     public static PackageManagerService main(Context context, Installer installer,
1767             boolean factoryTest, boolean onlyCore) {
1768         PackageManagerService m = new PackageManagerService(context, installer,
1769                 factoryTest, onlyCore);
1770         ServiceManager.addService("package", m);
1771         return m;
1772     }
1773 
splitString(String str, char sep)1774     static String[] splitString(String str, char sep) {
1775         int count = 1;
1776         int i = 0;
1777         while ((i=str.indexOf(sep, i)) >= 0) {
1778             count++;
1779             i++;
1780         }
1781 
1782         String[] res = new String[count];
1783         i=0;
1784         count = 0;
1785         int lastI=0;
1786         while ((i=str.indexOf(sep, i)) >= 0) {
1787             res[count] = str.substring(lastI, i);
1788             count++;
1789             i++;
1790             lastI = i;
1791         }
1792         res[count] = str.substring(lastI, str.length());
1793         return res;
1794     }
1795 
getDefaultDisplayMetrics(Context context, DisplayMetrics metrics)1796     private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
1797         DisplayManager displayManager = (DisplayManager) context.getSystemService(
1798                 Context.DISPLAY_SERVICE);
1799         displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
1800     }
1801 
PackageManagerService(Context context, Installer installer, boolean factoryTest, boolean onlyCore)1802     public PackageManagerService(Context context, Installer installer,
1803             boolean factoryTest, boolean onlyCore) {
1804         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
1805                 SystemClock.uptimeMillis());
1806 
1807         if (mSdkVersion <= 0) {
1808             Slog.w(TAG, "**** ro.build.version.sdk not set!");
1809         }
1810 
1811         mContext = context;
1812         mFactoryTest = factoryTest;
1813         mOnlyCore = onlyCore;
1814         mLazyDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));
1815         mMetrics = new DisplayMetrics();
1816         mSettings = new Settings(mPackages);
1817         mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
1818                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1819         mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
1820                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1821         mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
1822                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1823         mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
1824                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1825         mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
1826                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1827         mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
1828                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1829 
1830         // TODO: add a property to control this?
1831         long dexOptLRUThresholdInMinutes;
1832         if (mLazyDexOpt) {
1833             dexOptLRUThresholdInMinutes = 30; // only last 30 minutes of apps for eng builds.
1834         } else {
1835             dexOptLRUThresholdInMinutes = 7 * 24 * 60; // apps used in the 7 days for users.
1836         }
1837         mDexOptLRUThresholdInMills = dexOptLRUThresholdInMinutes * 60 * 1000;
1838 
1839         String separateProcesses = SystemProperties.get("debug.separate_processes");
1840         if (separateProcesses != null && separateProcesses.length() > 0) {
1841             if ("*".equals(separateProcesses)) {
1842                 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
1843                 mSeparateProcesses = null;
1844                 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
1845             } else {
1846                 mDefParseFlags = 0;
1847                 mSeparateProcesses = separateProcesses.split(",");
1848                 Slog.w(TAG, "Running with debug.separate_processes: "
1849                         + separateProcesses);
1850             }
1851         } else {
1852             mDefParseFlags = 0;
1853             mSeparateProcesses = null;
1854         }
1855 
1856         mInstaller = installer;
1857         mPackageDexOptimizer = new PackageDexOptimizer(this);
1858         mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
1859 
1860         mOnPermissionChangeListeners = new OnPermissionChangeListeners(
1861                 FgThread.get().getLooper());
1862 
1863         getDefaultDisplayMetrics(context, mMetrics);
1864 
1865         SystemConfig systemConfig = SystemConfig.getInstance();
1866         mGlobalGids = systemConfig.getGlobalGids();
1867         mSystemPermissions = systemConfig.getSystemPermissions();
1868         mAvailableFeatures = systemConfig.getAvailableFeatures();
1869 
1870         synchronized (mInstallLock) {
1871         // writer
1872         synchronized (mPackages) {
1873             mHandlerThread = new ServiceThread(TAG,
1874                     Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
1875             mHandlerThread.start();
1876             mHandler = new PackageHandler(mHandlerThread.getLooper());
1877             Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
1878 
1879             File dataDir = Environment.getDataDirectory();
1880             mAppDataDir = new File(dataDir, "data");
1881             mAppInstallDir = new File(dataDir, "app");
1882             mAppLib32InstallDir = new File(dataDir, "app-lib");
1883             mAsecInternalPath = new File(dataDir, "app-asec").getPath();
1884             mUserAppDataDir = new File(dataDir, "user");
1885             mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
1886 
1887             sUserManager = new UserManagerService(context, this,
1888                     mInstallLock, mPackages);
1889 
1890             // Propagate permission configuration in to package manager.
1891             ArrayMap<String, SystemConfig.PermissionEntry> permConfig
1892                     = systemConfig.getPermissions();
1893             for (int i=0; i<permConfig.size(); i++) {
1894                 SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
1895                 BasePermission bp = mSettings.mPermissions.get(perm.name);
1896                 if (bp == null) {
1897                     bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
1898                     mSettings.mPermissions.put(perm.name, bp);
1899                 }
1900                 if (perm.gids != null) {
1901                     bp.setGids(perm.gids, perm.perUser);
1902                 }
1903             }
1904 
1905             ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
1906             for (int i=0; i<libConfig.size(); i++) {
1907                 mSharedLibraries.put(libConfig.keyAt(i),
1908                         new SharedLibraryEntry(libConfig.valueAt(i), null));
1909             }
1910 
1911             mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
1912 
1913             mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false),
1914                     mSdkVersion, mOnlyCore);
1915 
1916             String customResolverActivity = Resources.getSystem().getString(
1917                     R.string.config_customResolverActivity);
1918             if (TextUtils.isEmpty(customResolverActivity)) {
1919                 customResolverActivity = null;
1920             } else {
1921                 mCustomResolverComponentName = ComponentName.unflattenFromString(
1922                         customResolverActivity);
1923             }
1924 
1925             long startTime = SystemClock.uptimeMillis();
1926 
1927             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
1928                     startTime);
1929 
1930             // Set flag to monitor and not change apk file paths when
1931             // scanning install directories.
1932             final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING | SCAN_INITIAL;
1933 
1934             final ArraySet<String> alreadyDexOpted = new ArraySet<String>();
1935 
1936             /**
1937              * Add everything in the in the boot class path to the
1938              * list of process files because dexopt will have been run
1939              * if necessary during zygote startup.
1940              */
1941             final String bootClassPath = System.getenv("BOOTCLASSPATH");
1942             final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
1943 
1944             if (bootClassPath != null) {
1945                 String[] bootClassPathElements = splitString(bootClassPath, ':');
1946                 for (String element : bootClassPathElements) {
1947                     alreadyDexOpted.add(element);
1948                 }
1949             } else {
1950                 Slog.w(TAG, "No BOOTCLASSPATH found!");
1951             }
1952 
1953             if (systemServerClassPath != null) {
1954                 String[] systemServerClassPathElements = splitString(systemServerClassPath, ':');
1955                 for (String element : systemServerClassPathElements) {
1956                     alreadyDexOpted.add(element);
1957                 }
1958             } else {
1959                 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
1960             }
1961 
1962             final List<String> allInstructionSets = InstructionSets.getAllInstructionSets();
1963             final String[] dexCodeInstructionSets =
1964                     getDexCodeInstructionSets(
1965                             allInstructionSets.toArray(new String[allInstructionSets.size()]));
1966 
1967             /**
1968              * Ensure all external libraries have had dexopt run on them.
1969              */
1970             if (mSharedLibraries.size() > 0) {
1971                 // NOTE: For now, we're compiling these system "shared libraries"
1972                 // (and framework jars) into all available architectures. It's possible
1973                 // to compile them only when we come across an app that uses them (there's
1974                 // already logic for that in scanPackageLI) but that adds some complexity.
1975                 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
1976                     for (SharedLibraryEntry libEntry : mSharedLibraries.values()) {
1977                         final String lib = libEntry.path;
1978                         if (lib == null) {
1979                             continue;
1980                         }
1981 
1982                         try {
1983                             int dexoptNeeded = DexFile.getDexOptNeeded(lib, null, dexCodeInstructionSet, false);
1984                             if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
1985                                 alreadyDexOpted.add(lib);
1986                                 mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded, false);
1987                             }
1988                         } catch (FileNotFoundException e) {
1989                             Slog.w(TAG, "Library not found: " + lib);
1990                         } catch (IOException e) {
1991                             Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
1992                                     + e.getMessage());
1993                         }
1994                     }
1995                 }
1996             }
1997 
1998             File frameworkDir = new File(Environment.getRootDirectory(), "framework");
1999 
2000             // Gross hack for now: we know this file doesn't contain any
2001             // code, so don't dexopt it to avoid the resulting log spew.
2002             alreadyDexOpted.add(frameworkDir.getPath() + "/framework-res.apk");
2003 
2004             // Gross hack for now: we know this file is only part of
2005             // the boot class path for art, so don't dexopt it to
2006             // avoid the resulting log spew.
2007             alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar");
2008 
2009             /**
2010              * There are a number of commands implemented in Java, which
2011              * we currently need to do the dexopt on so that they can be
2012              * run from a non-root shell.
2013              */
2014             String[] frameworkFiles = frameworkDir.list();
2015             if (frameworkFiles != null) {
2016                 // TODO: We could compile these only for the most preferred ABI. We should
2017                 // first double check that the dex files for these commands are not referenced
2018                 // by other system apps.
2019                 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
2020                     for (int i=0; i<frameworkFiles.length; i++) {
2021                         File libPath = new File(frameworkDir, frameworkFiles[i]);
2022                         String path = libPath.getPath();
2023                         // Skip the file if we already did it.
2024                         if (alreadyDexOpted.contains(path)) {
2025                             continue;
2026                         }
2027                         // Skip the file if it is not a type we want to dexopt.
2028                         if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
2029                             continue;
2030                         }
2031                         try {
2032                             int dexoptNeeded = DexFile.getDexOptNeeded(path, null, dexCodeInstructionSet, false);
2033                             if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
2034                                 mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded, false);
2035                             }
2036                         } catch (FileNotFoundException e) {
2037                             Slog.w(TAG, "Jar not found: " + path);
2038                         } catch (IOException e) {
2039                             Slog.w(TAG, "Exception reading jar: " + path, e);
2040                         }
2041                     }
2042                 }
2043             }
2044 
2045             final VersionInfo ver = mSettings.getInternalVersion();
2046             mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2047             // when upgrading from pre-M, promote system app permissions from install to runtime
2048             mPromoteSystemApps =
2049                     mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2050 
2051             // save off the names of pre-existing system packages prior to scanning; we don't
2052             // want to automatically grant runtime permissions for new system apps
2053             if (mPromoteSystemApps) {
2054                 Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2055                 while (pkgSettingIter.hasNext()) {
2056                     PackageSetting ps = pkgSettingIter.next();
2057                     if (isSystemApp(ps)) {
2058                         mExistingSystemPackages.add(ps.name);
2059                     }
2060                 }
2061             }
2062 
2063             // Collect vendor overlay packages.
2064             // (Do this before scanning any apps.)
2065             // For security and version matching reason, only consider
2066             // overlay packages if they reside in VENDOR_OVERLAY_DIR.
2067             File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR);
2068             scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM
2069                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2070 
2071             // Find base frameworks (resource packages without code).
2072             scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM
2073                     | PackageParser.PARSE_IS_SYSTEM_DIR
2074                     | PackageParser.PARSE_IS_PRIVILEGED,
2075                     scanFlags | SCAN_NO_DEX, 0);
2076 
2077             // Collected privileged system packages.
2078             final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2079             scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM
2080                     | PackageParser.PARSE_IS_SYSTEM_DIR
2081                     | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
2082 
2083             // Collect ordinary system packages.
2084             final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2085             scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM
2086                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2087 
2088             // Collect all vendor packages.
2089             File vendorAppDir = new File("/vendor/app");
2090             try {
2091                 vendorAppDir = vendorAppDir.getCanonicalFile();
2092             } catch (IOException e) {
2093                 // failed to look up canonical path, continue with original one
2094             }
2095             scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM
2096                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2097 
2098             // Collect all OEM packages.
2099             final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2100             scanDirLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM
2101                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2102 
2103             if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");
2104             mInstaller.moveFiles();
2105 
2106             // Prune any system packages that no longer exist.
2107             final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
2108             if (!mOnlyCore) {
2109                 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2110                 while (psit.hasNext()) {
2111                     PackageSetting ps = psit.next();
2112 
2113                     /*
2114                      * If this is not a system app, it can't be a
2115                      * disable system app.
2116                      */
2117                     if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2118                         continue;
2119                     }
2120 
2121                     /*
2122                      * If the package is scanned, it's not erased.
2123                      */
2124                     final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2125                     if (scannedPkg != null) {
2126                         /*
2127                          * If the system app is both scanned and in the
2128                          * disabled packages list, then it must have been
2129                          * added via OTA. Remove it from the currently
2130                          * scanned package so the previously user-installed
2131                          * application can be scanned.
2132                          */
2133                         if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2134                             logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2135                                     + ps.name + "; removing system app.  Last known codePath="
2136                                     + ps.codePathString + ", installStatus=" + ps.installStatus
2137                                     + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2138                                     + scannedPkg.mVersionCode);
2139                             removePackageLI(ps, true);
2140                             mExpectingBetter.put(ps.name, ps.codePath);
2141                         }
2142 
2143                         continue;
2144                     }
2145 
2146                     if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2147                         psit.remove();
2148                         logCriticalInfo(Log.WARN, "System package " + ps.name
2149                                 + " no longer exists; wiping its data");
2150                         removeDataDirsLI(null, ps.name);
2151                     } else {
2152                         final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
2153                         if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
2154                             possiblyDeletedUpdatedSystemApps.add(ps.name);
2155                         }
2156                     }
2157                 }
2158             }
2159 
2160             //look for any incomplete package installations
2161             ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2162             //clean up list
2163             for(int i = 0; i < deletePkgsList.size(); i++) {
2164                 //clean up here
2165                 cleanupInstallFailedPackage(deletePkgsList.get(i));
2166             }
2167             //delete tmp files
2168             deleteTempPackageFiles();
2169 
2170             // Remove any shared userIDs that have no associated packages
2171             mSettings.pruneSharedUsersLPw();
2172 
2173             if (!mOnlyCore) {
2174                 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2175                         SystemClock.uptimeMillis());
2176                 scanDirLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2177 
2178                 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
2179                         scanFlags | SCAN_REQUIRE_KNOWN, 0);
2180 
2181                 /**
2182                  * Remove disable package settings for any updated system
2183                  * apps that were removed via an OTA. If they're not a
2184                  * previously-updated app, remove them completely.
2185                  * Otherwise, just revoke their system-level permissions.
2186                  */
2187                 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2188                     PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2189                     mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2190 
2191                     String msg;
2192                     if (deletedPkg == null) {
2193                         msg = "Updated system package " + deletedAppName
2194                                 + " no longer exists; wiping its data";
2195                         removeDataDirsLI(null, deletedAppName);
2196                     } else {
2197                         msg = "Updated system app + " + deletedAppName
2198                                 + " no longer present; removing system privileges for "
2199                                 + deletedAppName;
2200 
2201                         deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2202 
2203                         PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2204                         deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2205                     }
2206                     logCriticalInfo(Log.WARN, msg);
2207                 }
2208 
2209                 /**
2210                  * Make sure all system apps that we expected to appear on
2211                  * the userdata partition actually showed up. If they never
2212                  * appeared, crawl back and revive the system version.
2213                  */
2214                 for (int i = 0; i < mExpectingBetter.size(); i++) {
2215                     final String packageName = mExpectingBetter.keyAt(i);
2216                     if (!mPackages.containsKey(packageName)) {
2217                         final File scanFile = mExpectingBetter.valueAt(i);
2218 
2219                         logCriticalInfo(Log.WARN, "Expected better " + packageName
2220                                 + " but never showed up; reverting to system");
2221 
2222                         final int reparseFlags;
2223                         if (FileUtils.contains(privilegedAppDir, scanFile)) {
2224                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
2225                                     | PackageParser.PARSE_IS_SYSTEM_DIR
2226                                     | PackageParser.PARSE_IS_PRIVILEGED;
2227                         } else if (FileUtils.contains(systemAppDir, scanFile)) {
2228                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
2229                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
2230                         } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2231                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
2232                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
2233                         } else if (FileUtils.contains(oemAppDir, scanFile)) {
2234                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
2235                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
2236                         } else {
2237                             Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2238                             continue;
2239                         }
2240 
2241                         mSettings.enableSystemPackageLPw(packageName);
2242 
2243                         try {
2244                             scanPackageLI(scanFile, reparseFlags, scanFlags, 0, null);
2245                         } catch (PackageManagerException e) {
2246                             Slog.e(TAG, "Failed to parse original system package: "
2247                                     + e.getMessage());
2248                         }
2249                     }
2250                 }
2251             }
2252             mExpectingBetter.clear();
2253 
2254             // Now that we know all of the shared libraries, update all clients to have
2255             // the correct library paths.
2256             updateAllSharedLibrariesLPw();
2257 
2258             for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2259                 // NOTE: We ignore potential failures here during a system scan (like
2260                 // the rest of the commands above) because there's precious little we
2261                 // can do about it. A settings error is reported, though.
2262                 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */,
2263                         false /* force dexopt */, false /* defer dexopt */,
2264                         false /* boot complete */);
2265             }
2266 
2267             // Now that we know all the packages we are keeping,
2268             // read and update their last usage times.
2269             mPackageUsage.readLP();
2270 
2271             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2272                     SystemClock.uptimeMillis());
2273             Slog.i(TAG, "Time to scan packages: "
2274                     + ((SystemClock.uptimeMillis()-startTime)/1000f)
2275                     + " seconds");
2276 
2277             // If the platform SDK has changed since the last time we booted,
2278             // we need to re-grant app permission to catch any new ones that
2279             // appear.  This is really a hack, and means that apps can in some
2280             // cases get permissions that the user didn't initially explicitly
2281             // allow...  it would be nice to have some better way to handle
2282             // this situation.
2283             int updateFlags = UPDATE_PERMISSIONS_ALL;
2284             if (ver.sdkVersion != mSdkVersion) {
2285                 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2286                         + mSdkVersion + "; regranting permissions for internal storage");
2287                 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
2288             }
2289             updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
2290             ver.sdkVersion = mSdkVersion;
2291 
2292             // If this is the first boot or an update from pre-M, and it is a normal
2293             // boot, then we need to initialize the default preferred apps across
2294             // all defined users.
2295             if (!onlyCore && (mPromoteSystemApps || !mRestoredSettings)) {
2296                 for (UserInfo user : sUserManager.getUsers(true)) {
2297                     mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2298                     applyFactoryDefaultBrowserLPw(user.id);
2299                     primeDomainVerificationsLPw(user.id);
2300                 }
2301             }
2302 
2303             // If this is first boot after an OTA, and a normal boot, then
2304             // we need to clear code cache directories.
2305             if (mIsUpgrade && !onlyCore) {
2306                 Slog.i(TAG, "Build fingerprint changed; clearing code caches");
2307                 for (int i = 0; i < mSettings.mPackages.size(); i++) {
2308                     final PackageSetting ps = mSettings.mPackages.valueAt(i);
2309                     if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
2310                         deleteCodeCacheDirsLI(ps.volumeUuid, ps.name);
2311                     }
2312                 }
2313                 ver.fingerprint = Build.FINGERPRINT;
2314             }
2315 
2316             checkDefaultBrowser();
2317 
2318             // clear only after permissions and other defaults have been updated
2319             mExistingSystemPackages.clear();
2320             mPromoteSystemApps = false;
2321 
2322             // All the changes are done during package scanning.
2323             ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
2324 
2325             // can downgrade to reader
2326             mSettings.writeLPr();
2327 
2328             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
2329                     SystemClock.uptimeMillis());
2330 
2331             mRequiredVerifierPackage = getRequiredVerifierLPr();
2332             mRequiredInstallerPackage = getRequiredInstallerLPr();
2333 
2334             mInstallerService = new PackageInstallerService(context, this);
2335 
2336             mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
2337             mIntentFilterVerifier = new IntentVerifierProxy(mContext,
2338                     mIntentFilterVerifierComponent);
2339 
2340         } // synchronized (mPackages)
2341         } // synchronized (mInstallLock)
2342 
2343         // Now after opening every single application zip, make sure they
2344         // are all flushed.  Not really needed, but keeps things nice and
2345         // tidy.
2346         Runtime.getRuntime().gc();
2347 
2348         // Expose private service for system components to use.
2349         LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
2350     }
2351 
2352     @Override
isFirstBoot()2353     public boolean isFirstBoot() {
2354         return !mRestoredSettings;
2355     }
2356 
2357     @Override
isOnlyCoreApps()2358     public boolean isOnlyCoreApps() {
2359         return mOnlyCore;
2360     }
2361 
2362     @Override
isUpgrade()2363     public boolean isUpgrade() {
2364         return mIsUpgrade;
2365     }
2366 
getRequiredVerifierLPr()2367     private String getRequiredVerifierLPr() {
2368         final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
2369         final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE,
2370                 PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */);
2371 
2372         String requiredVerifier = null;
2373 
2374         final int N = receivers.size();
2375         for (int i = 0; i < N; i++) {
2376             final ResolveInfo info = receivers.get(i);
2377 
2378             if (info.activityInfo == null) {
2379                 continue;
2380             }
2381 
2382             final String packageName = info.activityInfo.packageName;
2383 
2384             if (checkPermission(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
2385                     packageName, UserHandle.USER_OWNER) != PackageManager.PERMISSION_GRANTED) {
2386                 continue;
2387             }
2388 
2389             if (requiredVerifier != null) {
2390                 throw new RuntimeException("There can be only one required verifier");
2391             }
2392 
2393             requiredVerifier = packageName;
2394         }
2395 
2396         return requiredVerifier;
2397     }
2398 
getRequiredInstallerLPr()2399     private String getRequiredInstallerLPr() {
2400         Intent installerIntent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
2401         installerIntent.addCategory(Intent.CATEGORY_DEFAULT);
2402         installerIntent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
2403 
2404         final List<ResolveInfo> installers = queryIntentActivities(installerIntent,
2405                 PACKAGE_MIME_TYPE, 0, 0);
2406 
2407         String requiredInstaller = null;
2408 
2409         final int N = installers.size();
2410         for (int i = 0; i < N; i++) {
2411             final ResolveInfo info = installers.get(i);
2412             final String packageName = info.activityInfo.packageName;
2413 
2414             if (!info.activityInfo.applicationInfo.isSystemApp()) {
2415                 continue;
2416             }
2417 
2418             if (requiredInstaller != null) {
2419                 throw new RuntimeException("There must be one required installer");
2420             }
2421 
2422             requiredInstaller = packageName;
2423         }
2424 
2425         if (requiredInstaller == null) {
2426             throw new RuntimeException("There must be one required installer");
2427         }
2428 
2429         return requiredInstaller;
2430     }
2431 
getIntentFilterVerifierComponentNameLPr()2432     private ComponentName getIntentFilterVerifierComponentNameLPr() {
2433         final Intent verification = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
2434         final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE,
2435                 PackageManager.GET_DISABLED_COMPONENTS, 0 /* userId */);
2436 
2437         ComponentName verifierComponentName = null;
2438 
2439         int priority = -1000;
2440         final int N = receivers.size();
2441         for (int i = 0; i < N; i++) {
2442             final ResolveInfo info = receivers.get(i);
2443 
2444             if (info.activityInfo == null) {
2445                 continue;
2446             }
2447 
2448             final String packageName = info.activityInfo.packageName;
2449 
2450             final PackageSetting ps = mSettings.mPackages.get(packageName);
2451             if (ps == null) {
2452                 continue;
2453             }
2454 
2455             if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
2456                     packageName, UserHandle.USER_OWNER) != PackageManager.PERMISSION_GRANTED) {
2457                 continue;
2458             }
2459 
2460             // Select the IntentFilterVerifier with the highest priority
2461             if (priority < info.priority) {
2462                 priority = info.priority;
2463                 verifierComponentName = new ComponentName(packageName, info.activityInfo.name);
2464                 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Selecting IntentFilterVerifier: "
2465                         + verifierComponentName + " with priority: " + info.priority);
2466             }
2467         }
2468 
2469         return verifierComponentName;
2470     }
2471 
primeDomainVerificationsLPw(int userId)2472     private void primeDomainVerificationsLPw(int userId) {
2473         if (DEBUG_DOMAIN_VERIFICATION) {
2474             Slog.d(TAG, "Priming domain verifications in user " + userId);
2475         }
2476 
2477         SystemConfig systemConfig = SystemConfig.getInstance();
2478         ArraySet<String> packages = systemConfig.getLinkedApps();
2479         ArraySet<String> domains = new ArraySet<String>();
2480 
2481         for (String packageName : packages) {
2482             PackageParser.Package pkg = mPackages.get(packageName);
2483             if (pkg != null) {
2484                 if (!pkg.isSystemApp()) {
2485                     Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
2486                     continue;
2487                 }
2488 
2489                 domains.clear();
2490                 for (PackageParser.Activity a : pkg.activities) {
2491                     for (ActivityIntentInfo filter : a.intents) {
2492                         if (hasValidDomains(filter)) {
2493                             domains.addAll(filter.getHostsList());
2494                         }
2495                     }
2496                 }
2497 
2498                 if (domains.size() > 0) {
2499                     if (DEBUG_DOMAIN_VERIFICATION) {
2500                         Slog.v(TAG, "      + " + packageName);
2501                     }
2502                     // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
2503                     // state w.r.t. the formal app-linkage "no verification attempted" state;
2504                     // and then 'always' in the per-user state actually used for intent resolution.
2505                     final IntentFilterVerificationInfo ivi;
2506                     ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName,
2507                             new ArrayList<String>(domains));
2508                     ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
2509                     mSettings.updateIntentFilterVerificationStatusLPw(packageName,
2510                             INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
2511                 } else {
2512                     Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
2513                             + "' does not handle web links");
2514                 }
2515             } else {
2516                 Slog.w(TAG, "Unknown package '" + packageName + "' in sysconfig <app-link>");
2517             }
2518         }
2519 
2520         scheduleWritePackageRestrictionsLocked(userId);
2521         scheduleWriteSettingsLocked();
2522     }
2523 
applyFactoryDefaultBrowserLPw(int userId)2524     private void applyFactoryDefaultBrowserLPw(int userId) {
2525         // The default browser app's package name is stored in a string resource,
2526         // with a product-specific overlay used for vendor customization.
2527         String browserPkg = mContext.getResources().getString(
2528                 com.android.internal.R.string.default_browser);
2529         if (!TextUtils.isEmpty(browserPkg)) {
2530             // non-empty string => required to be a known package
2531             PackageSetting ps = mSettings.mPackages.get(browserPkg);
2532             if (ps == null) {
2533                 Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
2534                 browserPkg = null;
2535             } else {
2536                 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
2537             }
2538         }
2539 
2540         // Nothing valid explicitly set? Make the factory-installed browser the explicit
2541         // default.  If there's more than one, just leave everything alone.
2542         if (browserPkg == null) {
2543             calculateDefaultBrowserLPw(userId);
2544         }
2545     }
2546 
calculateDefaultBrowserLPw(int userId)2547     private void calculateDefaultBrowserLPw(int userId) {
2548         List<String> allBrowsers = resolveAllBrowserApps(userId);
2549         final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
2550         mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
2551     }
2552 
resolveAllBrowserApps(int userId)2553     private List<String> resolveAllBrowserApps(int userId) {
2554         // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
2555         List<ResolveInfo> list = queryIntentActivities(sBrowserIntent, null,
2556                 PackageManager.MATCH_ALL, userId);
2557 
2558         final int count = list.size();
2559         List<String> result = new ArrayList<String>(count);
2560         for (int i=0; i<count; i++) {
2561             ResolveInfo info = list.get(i);
2562             if (info.activityInfo == null
2563                     || !info.handleAllWebDataURI
2564                     || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
2565                     || result.contains(info.activityInfo.packageName)) {
2566                 continue;
2567             }
2568             result.add(info.activityInfo.packageName);
2569         }
2570 
2571         return result;
2572     }
2573 
packageIsBrowser(String packageName, int userId)2574     private boolean packageIsBrowser(String packageName, int userId) {
2575         List<ResolveInfo> list = queryIntentActivities(sBrowserIntent, null,
2576                 PackageManager.MATCH_ALL, userId);
2577         final int N = list.size();
2578         for (int i = 0; i < N; i++) {
2579             ResolveInfo info = list.get(i);
2580             if (packageName.equals(info.activityInfo.packageName)) {
2581                 return true;
2582             }
2583         }
2584         return false;
2585     }
2586 
checkDefaultBrowser()2587     private void checkDefaultBrowser() {
2588         final int myUserId = UserHandle.myUserId();
2589         final String packageName = getDefaultBrowserPackageName(myUserId);
2590         if (packageName != null) {
2591             PackageInfo info = getPackageInfo(packageName, 0, myUserId);
2592             if (info == null) {
2593                 Slog.w(TAG, "Default browser no longer installed: " + packageName);
2594                 synchronized (mPackages) {
2595                     applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
2596                 }
2597             }
2598         }
2599     }
2600 
2601     @Override
onTransact(int code, Parcel data, Parcel reply, int flags)2602     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2603             throws RemoteException {
2604         try {
2605             return super.onTransact(code, data, reply, flags);
2606         } catch (RuntimeException e) {
2607             if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
2608                 Slog.wtf(TAG, "Package Manager Crash", e);
2609             }
2610             throw e;
2611         }
2612     }
2613 
cleanupInstallFailedPackage(PackageSetting ps)2614     void cleanupInstallFailedPackage(PackageSetting ps) {
2615         logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name);
2616 
2617         removeDataDirsLI(ps.volumeUuid, ps.name);
2618         if (ps.codePath != null) {
2619             if (ps.codePath.isDirectory()) {
2620                 mInstaller.rmPackageDir(ps.codePath.getAbsolutePath());
2621             } else {
2622                 ps.codePath.delete();
2623             }
2624         }
2625         if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) {
2626             if (ps.resourcePath.isDirectory()) {
2627                 FileUtils.deleteContents(ps.resourcePath);
2628             }
2629             ps.resourcePath.delete();
2630         }
2631         mSettings.removePackageLPw(ps.name);
2632     }
2633 
appendInts(int[] cur, int[] add)2634     static int[] appendInts(int[] cur, int[] add) {
2635         if (add == null) return cur;
2636         if (cur == null) return add;
2637         final int N = add.length;
2638         for (int i=0; i<N; i++) {
2639             cur = appendInt(cur, add[i]);
2640         }
2641         return cur;
2642     }
2643 
generatePackageInfo(PackageParser.Package p, int flags, int userId)2644     PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) {
2645         if (!sUserManager.exists(userId)) return null;
2646         final PackageSetting ps = (PackageSetting) p.mExtras;
2647         if (ps == null) {
2648             return null;
2649         }
2650 
2651         final PermissionsState permissionsState = ps.getPermissionsState();
2652 
2653         final int[] gids = permissionsState.computeGids(userId);
2654         final Set<String> permissions = permissionsState.getPermissions(userId);
2655         final PackageUserState state = ps.readUserState(userId);
2656 
2657         return PackageParser.generatePackageInfo(p, gids, flags,
2658                 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
2659     }
2660 
2661     @Override
isPackageFrozen(String packageName)2662     public boolean isPackageFrozen(String packageName) {
2663         synchronized (mPackages) {
2664             final PackageSetting ps = mSettings.mPackages.get(packageName);
2665             if (ps != null) {
2666                 return ps.frozen;
2667             }
2668         }
2669         Slog.w(TAG, "Package " + packageName + " is missing; assuming frozen");
2670         return true;
2671     }
2672 
2673     @Override
isPackageAvailable(String packageName, int userId)2674     public boolean isPackageAvailable(String packageName, int userId) {
2675         if (!sUserManager.exists(userId)) return false;
2676         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "is package available");
2677         synchronized (mPackages) {
2678             PackageParser.Package p = mPackages.get(packageName);
2679             if (p != null) {
2680                 final PackageSetting ps = (PackageSetting) p.mExtras;
2681                 if (ps != null) {
2682                     final PackageUserState state = ps.readUserState(userId);
2683                     if (state != null) {
2684                         return PackageParser.isAvailable(state);
2685                     }
2686                 }
2687             }
2688         }
2689         return false;
2690     }
2691 
2692     @Override
getPackageInfo(String packageName, int flags, int userId)2693     public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
2694         if (!sUserManager.exists(userId)) return null;
2695         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package info");
2696         // reader
2697         synchronized (mPackages) {
2698             PackageParser.Package p = mPackages.get(packageName);
2699             if (DEBUG_PACKAGE_INFO)
2700                 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
2701             if (p != null) {
2702                 return generatePackageInfo(p, flags, userId);
2703             }
2704             if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
2705                 return generatePackageInfoFromSettingsLPw(packageName, flags, userId);
2706             }
2707         }
2708         return null;
2709     }
2710 
2711     @Override
currentToCanonicalPackageNames(String[] names)2712     public String[] currentToCanonicalPackageNames(String[] names) {
2713         String[] out = new String[names.length];
2714         // reader
2715         synchronized (mPackages) {
2716             for (int i=names.length-1; i>=0; i--) {
2717                 PackageSetting ps = mSettings.mPackages.get(names[i]);
2718                 out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
2719             }
2720         }
2721         return out;
2722     }
2723 
2724     @Override
canonicalToCurrentPackageNames(String[] names)2725     public String[] canonicalToCurrentPackageNames(String[] names) {
2726         String[] out = new String[names.length];
2727         // reader
2728         synchronized (mPackages) {
2729             for (int i=names.length-1; i>=0; i--) {
2730                 String cur = mSettings.mRenamedPackages.get(names[i]);
2731                 out[i] = cur != null ? cur : names[i];
2732             }
2733         }
2734         return out;
2735     }
2736 
2737     @Override
getPackageUid(String packageName, int userId)2738     public int getPackageUid(String packageName, int userId) {
2739         return getPackageUidEtc(packageName, 0, userId);
2740     }
2741 
2742     @Override
getPackageUidEtc(String packageName, int flags, int userId)2743     public int getPackageUidEtc(String packageName, int flags, int userId) {
2744         if (!sUserManager.exists(userId)) return -1;
2745         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid");
2746 
2747         // reader
2748         synchronized (mPackages) {
2749             final PackageParser.Package p = mPackages.get(packageName);
2750             if (p != null) {
2751                 return UserHandle.getUid(userId, p.applicationInfo.uid);
2752             }
2753             if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
2754                 final PackageSetting ps = mSettings.mPackages.get(packageName);
2755                 if (ps != null) {
2756                     return UserHandle.getUid(userId, ps.appId);
2757                 }
2758             }
2759         }
2760 
2761         return -1;
2762     }
2763 
2764     @Override
getPackageGids(String packageName, int userId)2765     public int[] getPackageGids(String packageName, int userId) {
2766         return getPackageGidsEtc(packageName, 0, userId);
2767     }
2768 
2769     @Override
getPackageGidsEtc(String packageName, int flags, int userId)2770     public int[] getPackageGidsEtc(String packageName, int flags, int userId) {
2771         if (!sUserManager.exists(userId)) {
2772             return null;
2773         }
2774 
2775         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
2776                 "getPackageGids");
2777 
2778         // reader
2779         synchronized (mPackages) {
2780             final PackageParser.Package p = mPackages.get(packageName);
2781             if (p != null) {
2782                 PackageSetting ps = (PackageSetting) p.mExtras;
2783                 return ps.getPermissionsState().computeGids(userId);
2784             }
2785             if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
2786                 final PackageSetting ps = mSettings.mPackages.get(packageName);
2787                 if (ps != null) {
2788                     return ps.getPermissionsState().computeGids(userId);
2789                 }
2790             }
2791         }
2792 
2793         return null;
2794     }
2795 
generatePermissionInfo( BasePermission bp, int flags)2796     static PermissionInfo generatePermissionInfo(
2797             BasePermission bp, int flags) {
2798         if (bp.perm != null) {
2799             return PackageParser.generatePermissionInfo(bp.perm, flags);
2800         }
2801         PermissionInfo pi = new PermissionInfo();
2802         pi.name = bp.name;
2803         pi.packageName = bp.sourcePackage;
2804         pi.nonLocalizedLabel = bp.name;
2805         pi.protectionLevel = bp.protectionLevel;
2806         return pi;
2807     }
2808 
2809     @Override
getPermissionInfo(String name, int flags)2810     public PermissionInfo getPermissionInfo(String name, int flags) {
2811         // reader
2812         synchronized (mPackages) {
2813             final BasePermission p = mSettings.mPermissions.get(name);
2814             if (p != null) {
2815                 return generatePermissionInfo(p, flags);
2816             }
2817             return null;
2818         }
2819     }
2820 
2821     @Override
queryPermissionsByGroup(String group, int flags)2822     public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) {
2823         // reader
2824         synchronized (mPackages) {
2825             ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
2826             for (BasePermission p : mSettings.mPermissions.values()) {
2827                 if (group == null) {
2828                     if (p.perm == null || p.perm.info.group == null) {
2829                         out.add(generatePermissionInfo(p, flags));
2830                     }
2831                 } else {
2832                     if (p.perm != null && group.equals(p.perm.info.group)) {
2833                         out.add(PackageParser.generatePermissionInfo(p.perm, flags));
2834                     }
2835                 }
2836             }
2837 
2838             if (out.size() > 0) {
2839                 return out;
2840             }
2841             return mPermissionGroups.containsKey(group) ? out : null;
2842         }
2843     }
2844 
2845     @Override
getPermissionGroupInfo(String name, int flags)2846     public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
2847         // reader
2848         synchronized (mPackages) {
2849             return PackageParser.generatePermissionGroupInfo(
2850                     mPermissionGroups.get(name), flags);
2851         }
2852     }
2853 
2854     @Override
getAllPermissionGroups(int flags)2855     public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
2856         // reader
2857         synchronized (mPackages) {
2858             final int N = mPermissionGroups.size();
2859             ArrayList<PermissionGroupInfo> out
2860                     = new ArrayList<PermissionGroupInfo>(N);
2861             for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
2862                 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
2863             }
2864             return out;
2865         }
2866     }
2867 
generateApplicationInfoFromSettingsLPw(String packageName, int flags, int userId)2868     private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
2869             int userId) {
2870         if (!sUserManager.exists(userId)) return null;
2871         PackageSetting ps = mSettings.mPackages.get(packageName);
2872         if (ps != null) {
2873             if (ps.pkg == null) {
2874                 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName,
2875                         flags, userId);
2876                 if (pInfo != null) {
2877                     return pInfo.applicationInfo;
2878                 }
2879                 return null;
2880             }
2881             return PackageParser.generateApplicationInfo(ps.pkg, flags,
2882                     ps.readUserState(userId), userId);
2883         }
2884         return null;
2885     }
2886 
generatePackageInfoFromSettingsLPw(String packageName, int flags, int userId)2887     private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags,
2888             int userId) {
2889         if (!sUserManager.exists(userId)) return null;
2890         PackageSetting ps = mSettings.mPackages.get(packageName);
2891         if (ps != null) {
2892             PackageParser.Package pkg = ps.pkg;
2893             if (pkg == null) {
2894                 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) == 0) {
2895                     return null;
2896                 }
2897                 // Only data remains, so we aren't worried about code paths
2898                 pkg = new PackageParser.Package(packageName);
2899                 pkg.applicationInfo.packageName = packageName;
2900                 pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY;
2901                 pkg.applicationInfo.privateFlags = ps.pkgPrivateFlags;
2902                 pkg.applicationInfo.dataDir = Environment
2903                         .getDataUserPackageDirectory(ps.volumeUuid, userId, packageName)
2904                         .getAbsolutePath();
2905                 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
2906                 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
2907             }
2908             return generatePackageInfo(pkg, flags, userId);
2909         }
2910         return null;
2911     }
2912 
2913     @Override
getApplicationInfo(String packageName, int flags, int userId)2914     public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
2915         if (!sUserManager.exists(userId)) return null;
2916         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get application info");
2917         // writer
2918         synchronized (mPackages) {
2919             PackageParser.Package p = mPackages.get(packageName);
2920             if (DEBUG_PACKAGE_INFO) Log.v(
2921                     TAG, "getApplicationInfo " + packageName
2922                     + ": " + p);
2923             if (p != null) {
2924                 PackageSetting ps = mSettings.mPackages.get(packageName);
2925                 if (ps == null) return null;
2926                 // Note: isEnabledLP() does not apply here - always return info
2927                 return PackageParser.generateApplicationInfo(
2928                         p, flags, ps.readUserState(userId), userId);
2929             }
2930             if ("android".equals(packageName)||"system".equals(packageName)) {
2931                 return mAndroidApplication;
2932             }
2933             if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
2934                 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId);
2935             }
2936         }
2937         return null;
2938     }
2939 
2940     @Override
freeStorageAndNotify(final String volumeUuid, final long freeStorageSize, final IPackageDataObserver observer)2941     public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
2942             final IPackageDataObserver observer) {
2943         mContext.enforceCallingOrSelfPermission(
2944                 android.Manifest.permission.CLEAR_APP_CACHE, null);
2945         // Queue up an async operation since clearing cache may take a little while.
2946         mHandler.post(new Runnable() {
2947             public void run() {
2948                 mHandler.removeCallbacks(this);
2949                 int retCode = -1;
2950                 synchronized (mInstallLock) {
2951                     retCode = mInstaller.freeCache(volumeUuid, freeStorageSize);
2952                     if (retCode < 0) {
2953                         Slog.w(TAG, "Couldn't clear application caches");
2954                     }
2955                 }
2956                 if (observer != null) {
2957                     try {
2958                         observer.onRemoveCompleted(null, (retCode >= 0));
2959                     } catch (RemoteException e) {
2960                         Slog.w(TAG, "RemoveException when invoking call back");
2961                     }
2962                 }
2963             }
2964         });
2965     }
2966 
2967     @Override
freeStorage(final String volumeUuid, final long freeStorageSize, final IntentSender pi)2968     public void freeStorage(final String volumeUuid, final long freeStorageSize,
2969             final IntentSender pi) {
2970         mContext.enforceCallingOrSelfPermission(
2971                 android.Manifest.permission.CLEAR_APP_CACHE, null);
2972         // Queue up an async operation since clearing cache may take a little while.
2973         mHandler.post(new Runnable() {
2974             public void run() {
2975                 mHandler.removeCallbacks(this);
2976                 int retCode = -1;
2977                 synchronized (mInstallLock) {
2978                     retCode = mInstaller.freeCache(volumeUuid, freeStorageSize);
2979                     if (retCode < 0) {
2980                         Slog.w(TAG, "Couldn't clear application caches");
2981                     }
2982                 }
2983                 if(pi != null) {
2984                     try {
2985                         // Callback via pending intent
2986                         int code = (retCode >= 0) ? 1 : 0;
2987                         pi.sendIntent(null, code, null,
2988                                 null, null);
2989                     } catch (SendIntentException e1) {
2990                         Slog.i(TAG, "Failed to send pending intent");
2991                     }
2992                 }
2993             }
2994         });
2995     }
2996 
freeStorage(String volumeUuid, long freeStorageSize)2997     void freeStorage(String volumeUuid, long freeStorageSize) throws IOException {
2998         synchronized (mInstallLock) {
2999             if (mInstaller.freeCache(volumeUuid, freeStorageSize) < 0) {
3000                 throw new IOException("Failed to free enough space");
3001             }
3002         }
3003     }
3004 
3005     @Override
getActivityInfo(ComponentName component, int flags, int userId)3006     public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
3007         if (!sUserManager.exists(userId)) return null;
3008         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info");
3009         synchronized (mPackages) {
3010             PackageParser.Activity a = mActivities.mActivities.get(component);
3011 
3012             if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
3013             if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
3014                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3015                 if (ps == null) return null;
3016                 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
3017                         userId);
3018             }
3019             if (mResolveComponentName.equals(component)) {
3020                 return PackageParser.generateActivityInfo(mResolveActivity, flags,
3021                         new PackageUserState(), userId);
3022             }
3023         }
3024         return null;
3025     }
3026 
3027     @Override
activitySupportsIntent(ComponentName component, Intent intent, String resolvedType)3028     public boolean activitySupportsIntent(ComponentName component, Intent intent,
3029             String resolvedType) {
3030         synchronized (mPackages) {
3031             if (component.equals(mResolveComponentName)) {
3032                 // The resolver supports EVERYTHING!
3033                 return true;
3034             }
3035             PackageParser.Activity a = mActivities.mActivities.get(component);
3036             if (a == null) {
3037                 return false;
3038             }
3039             for (int i=0; i<a.intents.size(); i++) {
3040                 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
3041                         intent.getData(), intent.getCategories(), TAG) >= 0) {
3042                     return true;
3043                 }
3044             }
3045             return false;
3046         }
3047     }
3048 
3049     @Override
getReceiverInfo(ComponentName component, int flags, int userId)3050     public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
3051         if (!sUserManager.exists(userId)) return null;
3052         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info");
3053         synchronized (mPackages) {
3054             PackageParser.Activity a = mReceivers.mActivities.get(component);
3055             if (DEBUG_PACKAGE_INFO) Log.v(
3056                 TAG, "getReceiverInfo " + component + ": " + a);
3057             if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
3058                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3059                 if (ps == null) return null;
3060                 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
3061                         userId);
3062             }
3063         }
3064         return null;
3065     }
3066 
3067     @Override
getServiceInfo(ComponentName component, int flags, int userId)3068     public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
3069         if (!sUserManager.exists(userId)) return null;
3070         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info");
3071         synchronized (mPackages) {
3072             PackageParser.Service s = mServices.mServices.get(component);
3073             if (DEBUG_PACKAGE_INFO) Log.v(
3074                 TAG, "getServiceInfo " + component + ": " + s);
3075             if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) {
3076                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3077                 if (ps == null) return null;
3078                 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
3079                         userId);
3080             }
3081         }
3082         return null;
3083     }
3084 
3085     @Override
getProviderInfo(ComponentName component, int flags, int userId)3086     public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
3087         if (!sUserManager.exists(userId)) return null;
3088         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info");
3089         synchronized (mPackages) {
3090             PackageParser.Provider p = mProviders.mProviders.get(component);
3091             if (DEBUG_PACKAGE_INFO) Log.v(
3092                 TAG, "getProviderInfo " + component + ": " + p);
3093             if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) {
3094                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3095                 if (ps == null) return null;
3096                 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
3097                         userId);
3098             }
3099         }
3100         return null;
3101     }
3102 
3103     @Override
getSystemSharedLibraryNames()3104     public String[] getSystemSharedLibraryNames() {
3105         Set<String> libSet;
3106         synchronized (mPackages) {
3107             libSet = mSharedLibraries.keySet();
3108             int size = libSet.size();
3109             if (size > 0) {
3110                 String[] libs = new String[size];
3111                 libSet.toArray(libs);
3112                 return libs;
3113             }
3114         }
3115         return null;
3116     }
3117 
3118     /**
3119      * @hide
3120      */
findSharedNonSystemLibrary(String libName)3121     PackageParser.Package findSharedNonSystemLibrary(String libName) {
3122         synchronized (mPackages) {
3123             PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName);
3124             if (lib != null && lib.apk != null) {
3125                 return mPackages.get(lib.apk);
3126             }
3127         }
3128         return null;
3129     }
3130 
3131     @Override
getSystemAvailableFeatures()3132     public FeatureInfo[] getSystemAvailableFeatures() {
3133         Collection<FeatureInfo> featSet;
3134         synchronized (mPackages) {
3135             featSet = mAvailableFeatures.values();
3136             int size = featSet.size();
3137             if (size > 0) {
3138                 FeatureInfo[] features = new FeatureInfo[size+1];
3139                 featSet.toArray(features);
3140                 FeatureInfo fi = new FeatureInfo();
3141                 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
3142                         FeatureInfo.GL_ES_VERSION_UNDEFINED);
3143                 features[size] = fi;
3144                 return features;
3145             }
3146         }
3147         return null;
3148     }
3149 
3150     @Override
hasSystemFeature(String name)3151     public boolean hasSystemFeature(String name) {
3152         synchronized (mPackages) {
3153             return mAvailableFeatures.containsKey(name);
3154         }
3155     }
3156 
checkValidCaller(int uid, int userId)3157     private void checkValidCaller(int uid, int userId) {
3158         if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0)
3159             return;
3160 
3161         throw new SecurityException("Caller uid=" + uid
3162                 + " is not privileged to communicate with user=" + userId);
3163     }
3164 
3165     @Override
checkPermission(String permName, String pkgName, int userId)3166     public int checkPermission(String permName, String pkgName, int userId) {
3167         if (!sUserManager.exists(userId)) {
3168             return PackageManager.PERMISSION_DENIED;
3169         }
3170 
3171         synchronized (mPackages) {
3172             final PackageParser.Package p = mPackages.get(pkgName);
3173             if (p != null && p.mExtras != null) {
3174                 final PackageSetting ps = (PackageSetting) p.mExtras;
3175                 final PermissionsState permissionsState = ps.getPermissionsState();
3176                 if (permissionsState.hasPermission(permName, userId)) {
3177                     return PackageManager.PERMISSION_GRANTED;
3178                 }
3179                 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
3180                 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
3181                         .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
3182                     return PackageManager.PERMISSION_GRANTED;
3183                 }
3184             }
3185         }
3186 
3187         return PackageManager.PERMISSION_DENIED;
3188     }
3189 
3190     @Override
checkUidPermission(String permName, int uid)3191     public int checkUidPermission(String permName, int uid) {
3192         final int userId = UserHandle.getUserId(uid);
3193 
3194         if (!sUserManager.exists(userId)) {
3195             return PackageManager.PERMISSION_DENIED;
3196         }
3197 
3198         synchronized (mPackages) {
3199             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
3200             if (obj != null) {
3201                 final SettingBase ps = (SettingBase) obj;
3202                 final PermissionsState permissionsState = ps.getPermissionsState();
3203                 if (permissionsState.hasPermission(permName, userId)) {
3204                     return PackageManager.PERMISSION_GRANTED;
3205                 }
3206                 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
3207                 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
3208                         .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
3209                     return PackageManager.PERMISSION_GRANTED;
3210                 }
3211             } else {
3212                 ArraySet<String> perms = mSystemPermissions.get(uid);
3213                 if (perms != null) {
3214                     if (perms.contains(permName)) {
3215                         return PackageManager.PERMISSION_GRANTED;
3216                     }
3217                     if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
3218                             .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
3219                         return PackageManager.PERMISSION_GRANTED;
3220                     }
3221                 }
3222             }
3223         }
3224 
3225         return PackageManager.PERMISSION_DENIED;
3226     }
3227 
3228     @Override
isPermissionRevokedByPolicy(String permission, String packageName, int userId)3229     public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
3230         if (UserHandle.getCallingUserId() != userId) {
3231             mContext.enforceCallingPermission(
3232                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
3233                     "isPermissionRevokedByPolicy for user " + userId);
3234         }
3235 
3236         if (checkPermission(permission, packageName, userId)
3237                 == PackageManager.PERMISSION_GRANTED) {
3238             return false;
3239         }
3240 
3241         final long identity = Binder.clearCallingIdentity();
3242         try {
3243             final int flags = getPermissionFlags(permission, packageName, userId);
3244             return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
3245         } finally {
3246             Binder.restoreCallingIdentity(identity);
3247         }
3248     }
3249 
3250     @Override
getPermissionControllerPackageName()3251     public String getPermissionControllerPackageName() {
3252         synchronized (mPackages) {
3253             return mRequiredInstallerPackage;
3254         }
3255     }
3256 
3257     /**
3258      * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
3259      * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
3260      * @param checkShell TODO(yamasani):
3261      * @param message the message to log on security exception
3262      */
enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, boolean checkShell, String message)3263     void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
3264             boolean checkShell, String message) {
3265         if (userId < 0) {
3266             throw new IllegalArgumentException("Invalid userId " + userId);
3267         }
3268         if (checkShell) {
3269             enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
3270         }
3271         if (userId == UserHandle.getUserId(callingUid)) return;
3272         if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
3273             if (requireFullPermission) {
3274                 mContext.enforceCallingOrSelfPermission(
3275                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
3276             } else {
3277                 try {
3278                     mContext.enforceCallingOrSelfPermission(
3279                             android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
3280                 } catch (SecurityException se) {
3281                     mContext.enforceCallingOrSelfPermission(
3282                             android.Manifest.permission.INTERACT_ACROSS_USERS, message);
3283                 }
3284             }
3285         }
3286     }
3287 
enforceShellRestriction(String restriction, int callingUid, int userHandle)3288     void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
3289         if (callingUid == Process.SHELL_UID) {
3290             if (userHandle >= 0
3291                     && sUserManager.hasUserRestriction(restriction, userHandle)) {
3292                 throw new SecurityException("Shell does not have permission to access user "
3293                         + userHandle);
3294             } else if (userHandle < 0) {
3295                 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
3296                         + Debug.getCallers(3));
3297             }
3298         }
3299     }
3300 
findPermissionTreeLP(String permName)3301     private BasePermission findPermissionTreeLP(String permName) {
3302         for(BasePermission bp : mSettings.mPermissionTrees.values()) {
3303             if (permName.startsWith(bp.name) &&
3304                     permName.length() > bp.name.length() &&
3305                     permName.charAt(bp.name.length()) == '.') {
3306                 return bp;
3307             }
3308         }
3309         return null;
3310     }
3311 
checkPermissionTreeLP(String permName)3312     private BasePermission checkPermissionTreeLP(String permName) {
3313         if (permName != null) {
3314             BasePermission bp = findPermissionTreeLP(permName);
3315             if (bp != null) {
3316                 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
3317                     return bp;
3318                 }
3319                 throw new SecurityException("Calling uid "
3320                         + Binder.getCallingUid()
3321                         + " is not allowed to add to permission tree "
3322                         + bp.name + " owned by uid " + bp.uid);
3323             }
3324         }
3325         throw new SecurityException("No permission tree found for " + permName);
3326     }
3327 
compareStrings(CharSequence s1, CharSequence s2)3328     static boolean compareStrings(CharSequence s1, CharSequence s2) {
3329         if (s1 == null) {
3330             return s2 == null;
3331         }
3332         if (s2 == null) {
3333             return false;
3334         }
3335         if (s1.getClass() != s2.getClass()) {
3336             return false;
3337         }
3338         return s1.equals(s2);
3339     }
3340 
comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2)3341     static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
3342         if (pi1.icon != pi2.icon) return false;
3343         if (pi1.logo != pi2.logo) return false;
3344         if (pi1.protectionLevel != pi2.protectionLevel) return false;
3345         if (!compareStrings(pi1.name, pi2.name)) return false;
3346         if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
3347         // We'll take care of setting this one.
3348         if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
3349         // These are not currently stored in settings.
3350         //if (!compareStrings(pi1.group, pi2.group)) return false;
3351         //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
3352         //if (pi1.labelRes != pi2.labelRes) return false;
3353         //if (pi1.descriptionRes != pi2.descriptionRes) return false;
3354         return true;
3355     }
3356 
permissionInfoFootprint(PermissionInfo info)3357     int permissionInfoFootprint(PermissionInfo info) {
3358         int size = info.name.length();
3359         if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
3360         if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
3361         return size;
3362     }
3363 
calculateCurrentPermissionFootprintLocked(BasePermission tree)3364     int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
3365         int size = 0;
3366         for (BasePermission perm : mSettings.mPermissions.values()) {
3367             if (perm.uid == tree.uid) {
3368                 size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
3369             }
3370         }
3371         return size;
3372     }
3373 
enforcePermissionCapLocked(PermissionInfo info, BasePermission tree)3374     void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
3375         // We calculate the max size of permissions defined by this uid and throw
3376         // if that plus the size of 'info' would exceed our stated maximum.
3377         if (tree.uid != Process.SYSTEM_UID) {
3378             final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
3379             if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
3380                 throw new SecurityException("Permission tree size cap exceeded");
3381             }
3382         }
3383     }
3384 
addPermissionLocked(PermissionInfo info, boolean async)3385     boolean addPermissionLocked(PermissionInfo info, boolean async) {
3386         if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
3387             throw new SecurityException("Label must be specified in permission");
3388         }
3389         BasePermission tree = checkPermissionTreeLP(info.name);
3390         BasePermission bp = mSettings.mPermissions.get(info.name);
3391         boolean added = bp == null;
3392         boolean changed = true;
3393         int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
3394         if (added) {
3395             enforcePermissionCapLocked(info, tree);
3396             bp = new BasePermission(info.name, tree.sourcePackage,
3397                     BasePermission.TYPE_DYNAMIC);
3398         } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
3399             throw new SecurityException(
3400                     "Not allowed to modify non-dynamic permission "
3401                     + info.name);
3402         } else {
3403             if (bp.protectionLevel == fixedLevel
3404                     && bp.perm.owner.equals(tree.perm.owner)
3405                     && bp.uid == tree.uid
3406                     && comparePermissionInfos(bp.perm.info, info)) {
3407                 changed = false;
3408             }
3409         }
3410         bp.protectionLevel = fixedLevel;
3411         info = new PermissionInfo(info);
3412         info.protectionLevel = fixedLevel;
3413         bp.perm = new PackageParser.Permission(tree.perm.owner, info);
3414         bp.perm.info.packageName = tree.perm.info.packageName;
3415         bp.uid = tree.uid;
3416         if (added) {
3417             mSettings.mPermissions.put(info.name, bp);
3418         }
3419         if (changed) {
3420             if (!async) {
3421                 mSettings.writeLPr();
3422             } else {
3423                 scheduleWriteSettingsLocked();
3424             }
3425         }
3426         return added;
3427     }
3428 
3429     @Override
addPermission(PermissionInfo info)3430     public boolean addPermission(PermissionInfo info) {
3431         synchronized (mPackages) {
3432             return addPermissionLocked(info, false);
3433         }
3434     }
3435 
3436     @Override
addPermissionAsync(PermissionInfo info)3437     public boolean addPermissionAsync(PermissionInfo info) {
3438         synchronized (mPackages) {
3439             return addPermissionLocked(info, true);
3440         }
3441     }
3442 
3443     @Override
removePermission(String name)3444     public void removePermission(String name) {
3445         synchronized (mPackages) {
3446             checkPermissionTreeLP(name);
3447             BasePermission bp = mSettings.mPermissions.get(name);
3448             if (bp != null) {
3449                 if (bp.type != BasePermission.TYPE_DYNAMIC) {
3450                     throw new SecurityException(
3451                             "Not allowed to modify non-dynamic permission "
3452                             + name);
3453                 }
3454                 mSettings.mPermissions.remove(name);
3455                 mSettings.writeLPr();
3456             }
3457         }
3458     }
3459 
enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg, BasePermission bp)3460     private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg,
3461             BasePermission bp) {
3462         int index = pkg.requestedPermissions.indexOf(bp.name);
3463         if (index == -1) {
3464             throw new SecurityException("Package " + pkg.packageName
3465                     + " has not requested permission " + bp.name);
3466         }
3467         if (!bp.isRuntime() && !bp.isDevelopment()) {
3468             throw new SecurityException("Permission " + bp.name
3469                     + " is not a changeable permission type");
3470         }
3471     }
3472 
3473     @Override
grantRuntimePermission(String packageName, String name, final int userId)3474     public void grantRuntimePermission(String packageName, String name, final int userId) {
3475         if (!sUserManager.exists(userId)) {
3476             Log.e(TAG, "No such user:" + userId);
3477             return;
3478         }
3479 
3480         mContext.enforceCallingOrSelfPermission(
3481                 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
3482                 "grantRuntimePermission");
3483 
3484         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3485                 "grantRuntimePermission");
3486 
3487         final int uid;
3488         final SettingBase sb;
3489 
3490         synchronized (mPackages) {
3491             final PackageParser.Package pkg = mPackages.get(packageName);
3492             if (pkg == null) {
3493                 throw new IllegalArgumentException("Unknown package: " + packageName);
3494             }
3495 
3496             final BasePermission bp = mSettings.mPermissions.get(name);
3497             if (bp == null) {
3498                 throw new IllegalArgumentException("Unknown permission: " + name);
3499             }
3500 
3501             enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
3502 
3503             uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
3504             sb = (SettingBase) pkg.mExtras;
3505             if (sb == null) {
3506                 throw new IllegalArgumentException("Unknown package: " + packageName);
3507             }
3508 
3509             final PermissionsState permissionsState = sb.getPermissionsState();
3510 
3511             final int flags = permissionsState.getPermissionFlags(name, userId);
3512             if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
3513                 throw new SecurityException("Cannot grant system fixed permission: "
3514                         + name + " for package: " + packageName);
3515             }
3516 
3517             if (bp.isDevelopment()) {
3518                 // Development permissions must be handled specially, since they are not
3519                 // normal runtime permissions.  For now they apply to all users.
3520                 if (permissionsState.grantInstallPermission(bp) !=
3521                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
3522                     scheduleWriteSettingsLocked();
3523                 }
3524                 return;
3525             }
3526 
3527             final int result = permissionsState.grantRuntimePermission(bp, userId);
3528             switch (result) {
3529                 case PermissionsState.PERMISSION_OPERATION_FAILURE: {
3530                     return;
3531                 }
3532 
3533                 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
3534                     final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
3535                     mHandler.post(new Runnable() {
3536                         @Override
3537                         public void run() {
3538                             killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
3539                         }
3540                     });
3541                 }
3542                 break;
3543             }
3544 
3545             mOnPermissionChangeListeners.onPermissionsChanged(uid);
3546 
3547             // Not critical if that is lost - app has to request again.
3548             mSettings.writeRuntimePermissionsForUserLPr(userId, false);
3549         }
3550 
3551         // Only need to do this if user is initialized. Otherwise it's a new user
3552         // and there are no processes running as the user yet and there's no need
3553         // to make an expensive call to remount processes for the changed permissions.
3554         if (READ_EXTERNAL_STORAGE.equals(name)
3555                 || WRITE_EXTERNAL_STORAGE.equals(name)) {
3556             final long token = Binder.clearCallingIdentity();
3557             try {
3558                 if (sUserManager.isInitialized(userId)) {
3559                     MountServiceInternal mountServiceInternal = LocalServices.getService(
3560                             MountServiceInternal.class);
3561                     mountServiceInternal.onExternalStoragePolicyChanged(uid, packageName);
3562                 }
3563             } finally {
3564                 Binder.restoreCallingIdentity(token);
3565             }
3566         }
3567     }
3568 
3569     @Override
revokeRuntimePermission(String packageName, String name, int userId)3570     public void revokeRuntimePermission(String packageName, String name, int userId) {
3571         if (!sUserManager.exists(userId)) {
3572             Log.e(TAG, "No such user:" + userId);
3573             return;
3574         }
3575 
3576         mContext.enforceCallingOrSelfPermission(
3577                 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
3578                 "revokeRuntimePermission");
3579 
3580         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3581                 "revokeRuntimePermission");
3582 
3583         final int appId;
3584 
3585         synchronized (mPackages) {
3586             final PackageParser.Package pkg = mPackages.get(packageName);
3587             if (pkg == null) {
3588                 throw new IllegalArgumentException("Unknown package: " + packageName);
3589             }
3590 
3591             final BasePermission bp = mSettings.mPermissions.get(name);
3592             if (bp == null) {
3593                 throw new IllegalArgumentException("Unknown permission: " + name);
3594             }
3595 
3596             enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
3597 
3598             SettingBase sb = (SettingBase) pkg.mExtras;
3599             if (sb == null) {
3600                 throw new IllegalArgumentException("Unknown package: " + packageName);
3601             }
3602 
3603             final PermissionsState permissionsState = sb.getPermissionsState();
3604 
3605             final int flags = permissionsState.getPermissionFlags(name, userId);
3606             if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
3607                 throw new SecurityException("Cannot revoke system fixed permission: "
3608                         + name + " for package: " + packageName);
3609             }
3610 
3611             if (bp.isDevelopment()) {
3612                 // Development permissions must be handled specially, since they are not
3613                 // normal runtime permissions.  For now they apply to all users.
3614                 if (permissionsState.revokeInstallPermission(bp) !=
3615                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
3616                     scheduleWriteSettingsLocked();
3617                 }
3618                 return;
3619             }
3620 
3621             if (permissionsState.revokeRuntimePermission(bp, userId) ==
3622                     PermissionsState.PERMISSION_OPERATION_FAILURE) {
3623                 return;
3624             }
3625 
3626             mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
3627 
3628             // Critical, after this call app should never have the permission.
3629             mSettings.writeRuntimePermissionsForUserLPr(userId, true);
3630 
3631             appId = UserHandle.getAppId(pkg.applicationInfo.uid);
3632         }
3633 
3634         killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
3635     }
3636 
3637     @Override
resetRuntimePermissions()3638     public void resetRuntimePermissions() {
3639         mContext.enforceCallingOrSelfPermission(
3640                 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
3641                 "revokeRuntimePermission");
3642 
3643         int callingUid = Binder.getCallingUid();
3644         if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
3645             mContext.enforceCallingOrSelfPermission(
3646                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
3647                     "resetRuntimePermissions");
3648         }
3649 
3650         synchronized (mPackages) {
3651             updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
3652             for (int userId : UserManagerService.getInstance().getUserIds()) {
3653                 final int packageCount = mPackages.size();
3654                 for (int i = 0; i < packageCount; i++) {
3655                     PackageParser.Package pkg = mPackages.valueAt(i);
3656                     if (!(pkg.mExtras instanceof PackageSetting)) {
3657                         continue;
3658                     }
3659                     PackageSetting ps = (PackageSetting) pkg.mExtras;
3660                     resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
3661                 }
3662             }
3663         }
3664     }
3665 
3666     @Override
getPermissionFlags(String name, String packageName, int userId)3667     public int getPermissionFlags(String name, String packageName, int userId) {
3668         if (!sUserManager.exists(userId)) {
3669             return 0;
3670         }
3671 
3672         enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
3673 
3674         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3675                 "getPermissionFlags");
3676 
3677         synchronized (mPackages) {
3678             final PackageParser.Package pkg = mPackages.get(packageName);
3679             if (pkg == null) {
3680                 throw new IllegalArgumentException("Unknown package: " + packageName);
3681             }
3682 
3683             final BasePermission bp = mSettings.mPermissions.get(name);
3684             if (bp == null) {
3685                 throw new IllegalArgumentException("Unknown permission: " + name);
3686             }
3687 
3688             SettingBase sb = (SettingBase) pkg.mExtras;
3689             if (sb == null) {
3690                 throw new IllegalArgumentException("Unknown package: " + packageName);
3691             }
3692 
3693             PermissionsState permissionsState = sb.getPermissionsState();
3694             return permissionsState.getPermissionFlags(name, userId);
3695         }
3696     }
3697 
3698     @Override
updatePermissionFlags(String name, String packageName, int flagMask, int flagValues, int userId)3699     public void updatePermissionFlags(String name, String packageName, int flagMask,
3700             int flagValues, int userId) {
3701         if (!sUserManager.exists(userId)) {
3702             return;
3703         }
3704 
3705         enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
3706 
3707         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3708                 "updatePermissionFlags");
3709 
3710         // Only the system can change these flags and nothing else.
3711         if (getCallingUid() != Process.SYSTEM_UID) {
3712             flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
3713             flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
3714             flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
3715             flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
3716         }
3717 
3718         synchronized (mPackages) {
3719             final PackageParser.Package pkg = mPackages.get(packageName);
3720             if (pkg == null) {
3721                 throw new IllegalArgumentException("Unknown package: " + packageName);
3722             }
3723 
3724             final BasePermission bp = mSettings.mPermissions.get(name);
3725             if (bp == null) {
3726                 throw new IllegalArgumentException("Unknown permission: " + name);
3727             }
3728 
3729             SettingBase sb = (SettingBase) pkg.mExtras;
3730             if (sb == null) {
3731                 throw new IllegalArgumentException("Unknown package: " + packageName);
3732             }
3733 
3734             PermissionsState permissionsState = sb.getPermissionsState();
3735 
3736             // Only the package manager can change flags for system component permissions.
3737             final int flags = permissionsState.getPermissionFlags(bp.name, userId);
3738             if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
3739                 return;
3740             }
3741 
3742             boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
3743 
3744             if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
3745                 // Install and runtime permissions are stored in different places,
3746                 // so figure out what permission changed and persist the change.
3747                 if (permissionsState.getInstallPermissionState(name) != null) {
3748                     scheduleWriteSettingsLocked();
3749                 } else if (permissionsState.getRuntimePermissionState(name, userId) != null
3750                         || hadState) {
3751                     mSettings.writeRuntimePermissionsForUserLPr(userId, false);
3752                 }
3753             }
3754         }
3755     }
3756 
3757     /**
3758      * Update the permission flags for all packages and runtime permissions of a user in order
3759      * to allow device or profile owner to remove POLICY_FIXED.
3760      */
3761     @Override
updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId)3762     public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
3763         if (!sUserManager.exists(userId)) {
3764             return;
3765         }
3766 
3767         enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps");
3768 
3769         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3770                 "updatePermissionFlagsForAllApps");
3771 
3772         // Only the system can change system fixed flags.
3773         if (getCallingUid() != Process.SYSTEM_UID) {
3774             flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
3775             flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
3776         }
3777 
3778         synchronized (mPackages) {
3779             boolean changed = false;
3780             final int packageCount = mPackages.size();
3781             for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
3782                 final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
3783                 SettingBase sb = (SettingBase) pkg.mExtras;
3784                 if (sb == null) {
3785                     continue;
3786                 }
3787                 PermissionsState permissionsState = sb.getPermissionsState();
3788                 changed |= permissionsState.updatePermissionFlagsForAllPermissions(
3789                         userId, flagMask, flagValues);
3790             }
3791             if (changed) {
3792                 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
3793             }
3794         }
3795     }
3796 
enforceGrantRevokeRuntimePermissionPermissions(String message)3797     private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
3798         if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
3799                 != PackageManager.PERMISSION_GRANTED
3800             && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
3801                 != PackageManager.PERMISSION_GRANTED) {
3802             throw new SecurityException(message + " requires "
3803                     + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
3804                     + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
3805         }
3806     }
3807 
3808     @Override
shouldShowRequestPermissionRationale(String permissionName, String packageName, int userId)3809     public boolean shouldShowRequestPermissionRationale(String permissionName,
3810             String packageName, int userId) {
3811         if (UserHandle.getCallingUserId() != userId) {
3812             mContext.enforceCallingPermission(
3813                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
3814                     "canShowRequestPermissionRationale for user " + userId);
3815         }
3816 
3817         final int uid = getPackageUid(packageName, userId);
3818         if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
3819             return false;
3820         }
3821 
3822         if (checkPermission(permissionName, packageName, userId)
3823                 == PackageManager.PERMISSION_GRANTED) {
3824             return false;
3825         }
3826 
3827         final int flags;
3828 
3829         final long identity = Binder.clearCallingIdentity();
3830         try {
3831             flags = getPermissionFlags(permissionName,
3832                     packageName, userId);
3833         } finally {
3834             Binder.restoreCallingIdentity(identity);
3835         }
3836 
3837         final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
3838                 | PackageManager.FLAG_PERMISSION_POLICY_FIXED
3839                 | PackageManager.FLAG_PERMISSION_USER_FIXED;
3840 
3841         if ((flags & fixedFlags) != 0) {
3842             return false;
3843         }
3844 
3845         return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
3846     }
3847 
3848     @Override
addOnPermissionsChangeListener(IOnPermissionsChangeListener listener)3849     public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
3850         mContext.enforceCallingOrSelfPermission(
3851                 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
3852                 "addOnPermissionsChangeListener");
3853 
3854         synchronized (mPackages) {
3855             mOnPermissionChangeListeners.addListenerLocked(listener);
3856         }
3857     }
3858 
3859     @Override
removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener)3860     public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
3861         synchronized (mPackages) {
3862             mOnPermissionChangeListeners.removeListenerLocked(listener);
3863         }
3864     }
3865 
3866     @Override
isProtectedBroadcast(String actionName)3867     public boolean isProtectedBroadcast(String actionName) {
3868         synchronized (mPackages) {
3869             return mProtectedBroadcasts.contains(actionName);
3870         }
3871     }
3872 
3873     @Override
checkSignatures(String pkg1, String pkg2)3874     public int checkSignatures(String pkg1, String pkg2) {
3875         synchronized (mPackages) {
3876             final PackageParser.Package p1 = mPackages.get(pkg1);
3877             final PackageParser.Package p2 = mPackages.get(pkg2);
3878             if (p1 == null || p1.mExtras == null
3879                     || p2 == null || p2.mExtras == null) {
3880                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
3881             }
3882             return compareSignatures(p1.mSignatures, p2.mSignatures);
3883         }
3884     }
3885 
3886     @Override
checkUidSignatures(int uid1, int uid2)3887     public int checkUidSignatures(int uid1, int uid2) {
3888         // Map to base uids.
3889         uid1 = UserHandle.getAppId(uid1);
3890         uid2 = UserHandle.getAppId(uid2);
3891         // reader
3892         synchronized (mPackages) {
3893             Signature[] s1;
3894             Signature[] s2;
3895             Object obj = mSettings.getUserIdLPr(uid1);
3896             if (obj != null) {
3897                 if (obj instanceof SharedUserSetting) {
3898                     s1 = ((SharedUserSetting)obj).signatures.mSignatures;
3899                 } else if (obj instanceof PackageSetting) {
3900                     s1 = ((PackageSetting)obj).signatures.mSignatures;
3901                 } else {
3902                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
3903                 }
3904             } else {
3905                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
3906             }
3907             obj = mSettings.getUserIdLPr(uid2);
3908             if (obj != null) {
3909                 if (obj instanceof SharedUserSetting) {
3910                     s2 = ((SharedUserSetting)obj).signatures.mSignatures;
3911                 } else if (obj instanceof PackageSetting) {
3912                     s2 = ((PackageSetting)obj).signatures.mSignatures;
3913                 } else {
3914                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
3915                 }
3916             } else {
3917                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
3918             }
3919             return compareSignatures(s1, s2);
3920         }
3921     }
3922 
killUid(int appId, int userId, String reason)3923     private void killUid(int appId, int userId, String reason) {
3924         final long identity = Binder.clearCallingIdentity();
3925         try {
3926             IActivityManager am = ActivityManagerNative.getDefault();
3927             if (am != null) {
3928                 try {
3929                     am.killUid(appId, userId, reason);
3930                 } catch (RemoteException e) {
3931                     /* ignore - same process */
3932                 }
3933             }
3934         } finally {
3935             Binder.restoreCallingIdentity(identity);
3936         }
3937     }
3938 
3939     /**
3940      * Compares two sets of signatures. Returns:
3941      * <br />
3942      * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
3943      * <br />
3944      * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
3945      * <br />
3946      * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
3947      * <br />
3948      * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
3949      * <br />
3950      * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
3951      */
compareSignatures(Signature[] s1, Signature[] s2)3952     static int compareSignatures(Signature[] s1, Signature[] s2) {
3953         if (s1 == null) {
3954             return s2 == null
3955                     ? PackageManager.SIGNATURE_NEITHER_SIGNED
3956                     : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
3957         }
3958 
3959         if (s2 == null) {
3960             return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
3961         }
3962 
3963         if (s1.length != s2.length) {
3964             return PackageManager.SIGNATURE_NO_MATCH;
3965         }
3966 
3967         // Since both signature sets are of size 1, we can compare without HashSets.
3968         if (s1.length == 1) {
3969             return s1[0].equals(s2[0]) ?
3970                     PackageManager.SIGNATURE_MATCH :
3971                     PackageManager.SIGNATURE_NO_MATCH;
3972         }
3973 
3974         ArraySet<Signature> set1 = new ArraySet<Signature>();
3975         for (Signature sig : s1) {
3976             set1.add(sig);
3977         }
3978         ArraySet<Signature> set2 = new ArraySet<Signature>();
3979         for (Signature sig : s2) {
3980             set2.add(sig);
3981         }
3982         // Make sure s2 contains all signatures in s1.
3983         if (set1.equals(set2)) {
3984             return PackageManager.SIGNATURE_MATCH;
3985         }
3986         return PackageManager.SIGNATURE_NO_MATCH;
3987     }
3988 
3989     /**
3990      * If the database version for this type of package (internal storage or
3991      * external storage) is less than the version where package signatures
3992      * were updated, return true.
3993      */
isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg)3994     private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
3995         final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
3996         return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
3997     }
3998 
3999     /**
4000      * Used for backward compatibility to make sure any packages with
4001      * certificate chains get upgraded to the new style. {@code existingSigs}
4002      * will be in the old format (since they were stored on disk from before the
4003      * system upgrade) and {@code scannedSigs} will be in the newer format.
4004      */
compareSignaturesCompat(PackageSignatures existingSigs, PackageParser.Package scannedPkg)4005     private int compareSignaturesCompat(PackageSignatures existingSigs,
4006             PackageParser.Package scannedPkg) {
4007         if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
4008             return PackageManager.SIGNATURE_NO_MATCH;
4009         }
4010 
4011         ArraySet<Signature> existingSet = new ArraySet<Signature>();
4012         for (Signature sig : existingSigs.mSignatures) {
4013             existingSet.add(sig);
4014         }
4015         ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
4016         for (Signature sig : scannedPkg.mSignatures) {
4017             try {
4018                 Signature[] chainSignatures = sig.getChainSignatures();
4019                 for (Signature chainSig : chainSignatures) {
4020                     scannedCompatSet.add(chainSig);
4021                 }
4022             } catch (CertificateEncodingException e) {
4023                 scannedCompatSet.add(sig);
4024             }
4025         }
4026         /*
4027          * Make sure the expanded scanned set contains all signatures in the
4028          * existing one.
4029          */
4030         if (scannedCompatSet.equals(existingSet)) {
4031             // Migrate the old signatures to the new scheme.
4032             existingSigs.assignSignatures(scannedPkg.mSignatures);
4033             // The new KeySets will be re-added later in the scanning process.
4034             synchronized (mPackages) {
4035                 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
4036             }
4037             return PackageManager.SIGNATURE_MATCH;
4038         }
4039         return PackageManager.SIGNATURE_NO_MATCH;
4040     }
4041 
isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg)4042     private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
4043         final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
4044         return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
4045     }
4046 
compareSignaturesRecover(PackageSignatures existingSigs, PackageParser.Package scannedPkg)4047     private int compareSignaturesRecover(PackageSignatures existingSigs,
4048             PackageParser.Package scannedPkg) {
4049         if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
4050             return PackageManager.SIGNATURE_NO_MATCH;
4051         }
4052 
4053         String msg = null;
4054         try {
4055             if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
4056                 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
4057                         + scannedPkg.packageName);
4058                 return PackageManager.SIGNATURE_MATCH;
4059             }
4060         } catch (CertificateException e) {
4061             msg = e.getMessage();
4062         }
4063 
4064         logCriticalInfo(Log.INFO,
4065                 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
4066         return PackageManager.SIGNATURE_NO_MATCH;
4067     }
4068 
4069     @Override
getPackagesForUid(int uid)4070     public String[] getPackagesForUid(int uid) {
4071         uid = UserHandle.getAppId(uid);
4072         // reader
4073         synchronized (mPackages) {
4074             Object obj = mSettings.getUserIdLPr(uid);
4075             if (obj instanceof SharedUserSetting) {
4076                 final SharedUserSetting sus = (SharedUserSetting) obj;
4077                 final int N = sus.packages.size();
4078                 final String[] res = new String[N];
4079                 final Iterator<PackageSetting> it = sus.packages.iterator();
4080                 int i = 0;
4081                 while (it.hasNext()) {
4082                     res[i++] = it.next().name;
4083                 }
4084                 return res;
4085             } else if (obj instanceof PackageSetting) {
4086                 final PackageSetting ps = (PackageSetting) obj;
4087                 return new String[] { ps.name };
4088             }
4089         }
4090         return null;
4091     }
4092 
4093     @Override
getNameForUid(int uid)4094     public String getNameForUid(int uid) {
4095         // reader
4096         synchronized (mPackages) {
4097             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4098             if (obj instanceof SharedUserSetting) {
4099                 final SharedUserSetting sus = (SharedUserSetting) obj;
4100                 return sus.name + ":" + sus.userId;
4101             } else if (obj instanceof PackageSetting) {
4102                 final PackageSetting ps = (PackageSetting) obj;
4103                 return ps.name;
4104             }
4105         }
4106         return null;
4107     }
4108 
4109     @Override
getUidForSharedUser(String sharedUserName)4110     public int getUidForSharedUser(String sharedUserName) {
4111         if(sharedUserName == null) {
4112             return -1;
4113         }
4114         // reader
4115         synchronized (mPackages) {
4116             final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
4117             if (suid == null) {
4118                 return -1;
4119             }
4120             return suid.userId;
4121         }
4122     }
4123 
4124     @Override
getFlagsForUid(int uid)4125     public int getFlagsForUid(int uid) {
4126         synchronized (mPackages) {
4127             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4128             if (obj instanceof SharedUserSetting) {
4129                 final SharedUserSetting sus = (SharedUserSetting) obj;
4130                 return sus.pkgFlags;
4131             } else if (obj instanceof PackageSetting) {
4132                 final PackageSetting ps = (PackageSetting) obj;
4133                 return ps.pkgFlags;
4134             }
4135         }
4136         return 0;
4137     }
4138 
4139     @Override
getPrivateFlagsForUid(int uid)4140     public int getPrivateFlagsForUid(int uid) {
4141         synchronized (mPackages) {
4142             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4143             if (obj instanceof SharedUserSetting) {
4144                 final SharedUserSetting sus = (SharedUserSetting) obj;
4145                 return sus.pkgPrivateFlags;
4146             } else if (obj instanceof PackageSetting) {
4147                 final PackageSetting ps = (PackageSetting) obj;
4148                 return ps.pkgPrivateFlags;
4149             }
4150         }
4151         return 0;
4152     }
4153 
4154     @Override
isUidPrivileged(int uid)4155     public boolean isUidPrivileged(int uid) {
4156         uid = UserHandle.getAppId(uid);
4157         // reader
4158         synchronized (mPackages) {
4159             Object obj = mSettings.getUserIdLPr(uid);
4160             if (obj instanceof SharedUserSetting) {
4161                 final SharedUserSetting sus = (SharedUserSetting) obj;
4162                 final Iterator<PackageSetting> it = sus.packages.iterator();
4163                 while (it.hasNext()) {
4164                     if (it.next().isPrivileged()) {
4165                         return true;
4166                     }
4167                 }
4168             } else if (obj instanceof PackageSetting) {
4169                 final PackageSetting ps = (PackageSetting) obj;
4170                 return ps.isPrivileged();
4171             }
4172         }
4173         return false;
4174     }
4175 
4176     @Override
getAppOpPermissionPackages(String permissionName)4177     public String[] getAppOpPermissionPackages(String permissionName) {
4178         synchronized (mPackages) {
4179             ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
4180             if (pkgs == null) {
4181                 return null;
4182             }
4183             return pkgs.toArray(new String[pkgs.size()]);
4184         }
4185     }
4186 
4187     @Override
resolveIntent(Intent intent, String resolvedType, int flags, int userId)4188     public ResolveInfo resolveIntent(Intent intent, String resolvedType,
4189             int flags, int userId) {
4190         if (!sUserManager.exists(userId)) return null;
4191         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent");
4192         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
4193         return chooseBestActivity(intent, resolvedType, flags, query, userId);
4194     }
4195 
4196     @Override
setLastChosenActivity(Intent intent, String resolvedType, int flags, IntentFilter filter, int match, ComponentName activity)4197     public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
4198             IntentFilter filter, int match, ComponentName activity) {
4199         final int userId = UserHandle.getCallingUserId();
4200         if (DEBUG_PREFERRED) {
4201             Log.v(TAG, "setLastChosenActivity intent=" + intent
4202                 + " resolvedType=" + resolvedType
4203                 + " flags=" + flags
4204                 + " filter=" + filter
4205                 + " match=" + match
4206                 + " activity=" + activity);
4207             filter.dump(new PrintStreamPrinter(System.out), "    ");
4208         }
4209         intent.setComponent(null);
4210         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
4211         // Find any earlier preferred or last chosen entries and nuke them
4212         findPreferredActivity(intent, resolvedType,
4213                 flags, query, 0, false, true, false, userId);
4214         // Add the new activity as the last chosen for this filter
4215         addPreferredActivityInternal(filter, match, null, activity, false, userId,
4216                 "Setting last chosen");
4217     }
4218 
4219     @Override
getLastChosenActivity(Intent intent, String resolvedType, int flags)4220     public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
4221         final int userId = UserHandle.getCallingUserId();
4222         if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
4223         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
4224         return findPreferredActivity(intent, resolvedType, flags, query, 0,
4225                 false, false, false, userId);
4226     }
4227 
chooseBestActivity(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, int userId)4228     private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
4229             int flags, List<ResolveInfo> query, int userId) {
4230         if (query != null) {
4231             final int N = query.size();
4232             if (N == 1) {
4233                 return query.get(0);
4234             } else if (N > 1) {
4235                 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4236                 // If there is more than one activity with the same priority,
4237                 // then let the user decide between them.
4238                 ResolveInfo r0 = query.get(0);
4239                 ResolveInfo r1 = query.get(1);
4240                 if (DEBUG_INTENT_MATCHING || debug) {
4241                     Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
4242                             + r1.activityInfo.name + "=" + r1.priority);
4243                 }
4244                 // If the first activity has a higher priority, or a different
4245                 // default, then it is always desireable to pick it.
4246                 if (r0.priority != r1.priority
4247                         || r0.preferredOrder != r1.preferredOrder
4248                         || r0.isDefault != r1.isDefault) {
4249                     return query.get(0);
4250                 }
4251                 // If we have saved a preference for a preferred activity for
4252                 // this Intent, use that.
4253                 ResolveInfo ri = findPreferredActivity(intent, resolvedType,
4254                         flags, query, r0.priority, true, false, debug, userId);
4255                 if (ri != null) {
4256                     return ri;
4257                 }
4258                 ri = new ResolveInfo(mResolveInfo);
4259                 ri.activityInfo = new ActivityInfo(ri.activityInfo);
4260                 ri.activityInfo.applicationInfo = new ApplicationInfo(
4261                         ri.activityInfo.applicationInfo);
4262                 if (userId != 0) {
4263                     ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
4264                             UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
4265                 }
4266                 // Make sure that the resolver is displayable in car mode
4267                 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
4268                 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
4269                 return ri;
4270             }
4271         }
4272         return null;
4273     }
4274 
findPersistentPreferredActivityLP(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, boolean debug, int userId)4275     private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
4276             int flags, List<ResolveInfo> query, boolean debug, int userId) {
4277         final int N = query.size();
4278         PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
4279                 .get(userId);
4280         // Get the list of persistent preferred activities that handle the intent
4281         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
4282         List<PersistentPreferredActivity> pprefs = ppir != null
4283                 ? ppir.queryIntent(intent, resolvedType,
4284                         (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
4285                 : null;
4286         if (pprefs != null && pprefs.size() > 0) {
4287             final int M = pprefs.size();
4288             for (int i=0; i<M; i++) {
4289                 final PersistentPreferredActivity ppa = pprefs.get(i);
4290                 if (DEBUG_PREFERRED || debug) {
4291                     Slog.v(TAG, "Checking PersistentPreferredActivity ds="
4292                             + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
4293                             + "\n  component=" + ppa.mComponent);
4294                     ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4295                 }
4296                 final ActivityInfo ai = getActivityInfo(ppa.mComponent,
4297                         flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
4298                 if (DEBUG_PREFERRED || debug) {
4299                     Slog.v(TAG, "Found persistent preferred activity:");
4300                     if (ai != null) {
4301                         ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4302                     } else {
4303                         Slog.v(TAG, "  null");
4304                     }
4305                 }
4306                 if (ai == null) {
4307                     // This previously registered persistent preferred activity
4308                     // component is no longer known. Ignore it and do NOT remove it.
4309                     continue;
4310                 }
4311                 for (int j=0; j<N; j++) {
4312                     final ResolveInfo ri = query.get(j);
4313                     if (!ri.activityInfo.applicationInfo.packageName
4314                             .equals(ai.applicationInfo.packageName)) {
4315                         continue;
4316                     }
4317                     if (!ri.activityInfo.name.equals(ai.name)) {
4318                         continue;
4319                     }
4320                     //  Found a persistent preference that can handle the intent.
4321                     if (DEBUG_PREFERRED || debug) {
4322                         Slog.v(TAG, "Returning persistent preferred activity: " +
4323                                 ri.activityInfo.packageName + "/" + ri.activityInfo.name);
4324                     }
4325                     return ri;
4326                 }
4327             }
4328         }
4329         return null;
4330     }
4331 
findPreferredActivity(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, int priority, boolean always, boolean removeMatches, boolean debug, int userId)4332     ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
4333             List<ResolveInfo> query, int priority, boolean always,
4334             boolean removeMatches, boolean debug, int userId) {
4335         if (!sUserManager.exists(userId)) return null;
4336         // writer
4337         synchronized (mPackages) {
4338             if (intent.getSelector() != null) {
4339                 intent = intent.getSelector();
4340             }
4341             if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4342 
4343             // Try to find a matching persistent preferred activity.
4344             ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
4345                     debug, userId);
4346 
4347             // If a persistent preferred activity matched, use it.
4348             if (pri != null) {
4349                 return pri;
4350             }
4351 
4352             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
4353             // Get the list of preferred activities that handle the intent
4354             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
4355             List<PreferredActivity> prefs = pir != null
4356                     ? pir.queryIntent(intent, resolvedType,
4357                             (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
4358                     : null;
4359             if (prefs != null && prefs.size() > 0) {
4360                 boolean changed = false;
4361                 try {
4362                     // First figure out how good the original match set is.
4363                     // We will only allow preferred activities that came
4364                     // from the same match quality.
4365                     int match = 0;
4366 
4367                     if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
4368 
4369                     final int N = query.size();
4370                     for (int j=0; j<N; j++) {
4371                         final ResolveInfo ri = query.get(j);
4372                         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
4373                                 + ": 0x" + Integer.toHexString(match));
4374                         if (ri.match > match) {
4375                             match = ri.match;
4376                         }
4377                     }
4378 
4379                     if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
4380                             + Integer.toHexString(match));
4381 
4382                     match &= IntentFilter.MATCH_CATEGORY_MASK;
4383                     final int M = prefs.size();
4384                     for (int i=0; i<M; i++) {
4385                         final PreferredActivity pa = prefs.get(i);
4386                         if (DEBUG_PREFERRED || debug) {
4387                             Slog.v(TAG, "Checking PreferredActivity ds="
4388                                     + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
4389                                     + "\n  component=" + pa.mPref.mComponent);
4390                             pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4391                         }
4392                         if (pa.mPref.mMatch != match) {
4393                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
4394                                     + Integer.toHexString(pa.mPref.mMatch));
4395                             continue;
4396                         }
4397                         // If it's not an "always" type preferred activity and that's what we're
4398                         // looking for, skip it.
4399                         if (always && !pa.mPref.mAlways) {
4400                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
4401                             continue;
4402                         }
4403                         final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent,
4404                                 flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
4405                         if (DEBUG_PREFERRED || debug) {
4406                             Slog.v(TAG, "Found preferred activity:");
4407                             if (ai != null) {
4408                                 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4409                             } else {
4410                                 Slog.v(TAG, "  null");
4411                             }
4412                         }
4413                         if (ai == null) {
4414                             // This previously registered preferred activity
4415                             // component is no longer known.  Most likely an update
4416                             // to the app was installed and in the new version this
4417                             // component no longer exists.  Clean it up by removing
4418                             // it from the preferred activities list, and skip it.
4419                             Slog.w(TAG, "Removing dangling preferred activity: "
4420                                     + pa.mPref.mComponent);
4421                             pir.removeFilter(pa);
4422                             changed = true;
4423                             continue;
4424                         }
4425                         for (int j=0; j<N; j++) {
4426                             final ResolveInfo ri = query.get(j);
4427                             if (!ri.activityInfo.applicationInfo.packageName
4428                                     .equals(ai.applicationInfo.packageName)) {
4429                                 continue;
4430                             }
4431                             if (!ri.activityInfo.name.equals(ai.name)) {
4432                                 continue;
4433                             }
4434 
4435                             if (removeMatches) {
4436                                 pir.removeFilter(pa);
4437                                 changed = true;
4438                                 if (DEBUG_PREFERRED) {
4439                                     Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
4440                                 }
4441                                 break;
4442                             }
4443 
4444                             // Okay we found a previously set preferred or last chosen app.
4445                             // If the result set is different from when this
4446                             // was created, we need to clear it and re-ask the
4447                             // user their preference, if we're looking for an "always" type entry.
4448                             if (always && !pa.mPref.sameSet(query)) {
4449                                 Slog.i(TAG, "Result set changed, dropping preferred activity for "
4450                                         + intent + " type " + resolvedType);
4451                                 if (DEBUG_PREFERRED) {
4452                                     Slog.v(TAG, "Removing preferred activity since set changed "
4453                                             + pa.mPref.mComponent);
4454                                 }
4455                                 pir.removeFilter(pa);
4456                                 // Re-add the filter as a "last chosen" entry (!always)
4457                                 PreferredActivity lastChosen = new PreferredActivity(
4458                                         pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
4459                                 pir.addFilter(lastChosen);
4460                                 changed = true;
4461                                 return null;
4462                             }
4463 
4464                             // Yay! Either the set matched or we're looking for the last chosen
4465                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
4466                                     + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
4467                             return ri;
4468                         }
4469                     }
4470                 } finally {
4471                     if (changed) {
4472                         if (DEBUG_PREFERRED) {
4473                             Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
4474                         }
4475                         scheduleWritePackageRestrictionsLocked(userId);
4476                     }
4477                 }
4478             }
4479         }
4480         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
4481         return null;
4482     }
4483 
4484     /*
4485      * Returns if intent can be forwarded from the sourceUserId to the targetUserId
4486      */
4487     @Override
canForwardTo(Intent intent, String resolvedType, int sourceUserId, int targetUserId)4488     public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
4489             int targetUserId) {
4490         mContext.enforceCallingOrSelfPermission(
4491                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
4492         List<CrossProfileIntentFilter> matches =
4493                 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
4494         if (matches != null) {
4495             int size = matches.size();
4496             for (int i = 0; i < size; i++) {
4497                 if (matches.get(i).getTargetUserId() == targetUserId) return true;
4498             }
4499         }
4500         if (hasWebURI(intent)) {
4501             // cross-profile app linking works only towards the parent.
4502             final UserInfo parent = getProfileParent(sourceUserId);
4503             synchronized(mPackages) {
4504                 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
4505                         intent, resolvedType, 0, sourceUserId, parent.id);
4506                 return xpDomainInfo != null;
4507             }
4508         }
4509         return false;
4510     }
4511 
getProfileParent(int userId)4512     private UserInfo getProfileParent(int userId) {
4513         final long identity = Binder.clearCallingIdentity();
4514         try {
4515             return sUserManager.getProfileParent(userId);
4516         } finally {
4517             Binder.restoreCallingIdentity(identity);
4518         }
4519     }
4520 
getMatchingCrossProfileIntentFilters(Intent intent, String resolvedType, int userId)4521     private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
4522             String resolvedType, int userId) {
4523         CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
4524         if (resolver != null) {
4525             return resolver.queryIntent(intent, resolvedType, false, userId);
4526         }
4527         return null;
4528     }
4529 
4530     @Override
queryIntentActivities(Intent intent, String resolvedType, int flags, int userId)4531     public List<ResolveInfo> queryIntentActivities(Intent intent,
4532             String resolvedType, int flags, int userId) {
4533         if (!sUserManager.exists(userId)) return Collections.emptyList();
4534         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities");
4535         ComponentName comp = intent.getComponent();
4536         if (comp == null) {
4537             if (intent.getSelector() != null) {
4538                 intent = intent.getSelector();
4539                 comp = intent.getComponent();
4540             }
4541         }
4542 
4543         if (comp != null) {
4544             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
4545             final ActivityInfo ai = getActivityInfo(comp, flags, userId);
4546             if (ai != null) {
4547                 final ResolveInfo ri = new ResolveInfo();
4548                 ri.activityInfo = ai;
4549                 list.add(ri);
4550             }
4551             return list;
4552         }
4553 
4554         // reader
4555         synchronized (mPackages) {
4556             final String pkgName = intent.getPackage();
4557             if (pkgName == null) {
4558                 List<CrossProfileIntentFilter> matchingFilters =
4559                         getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
4560                 // Check for results that need to skip the current profile.
4561                 ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
4562                         resolvedType, flags, userId);
4563                 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
4564                     List<ResolveInfo> result = new ArrayList<ResolveInfo>(1);
4565                     result.add(xpResolveInfo);
4566                     return filterIfNotPrimaryUser(result, userId);
4567                 }
4568 
4569                 // Check for results in the current profile.
4570                 List<ResolveInfo> result = mActivities.queryIntent(
4571                         intent, resolvedType, flags, userId);
4572 
4573                 // Check for cross profile results.
4574                 xpResolveInfo = queryCrossProfileIntents(
4575                         matchingFilters, intent, resolvedType, flags, userId);
4576                 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
4577                     result.add(xpResolveInfo);
4578                     Collections.sort(result, mResolvePrioritySorter);
4579                 }
4580                 result = filterIfNotPrimaryUser(result, userId);
4581                 if (hasWebURI(intent)) {
4582                     CrossProfileDomainInfo xpDomainInfo = null;
4583                     final UserInfo parent = getProfileParent(userId);
4584                     if (parent != null) {
4585                         xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
4586                                 flags, userId, parent.id);
4587                     }
4588                     if (xpDomainInfo != null) {
4589                         if (xpResolveInfo != null) {
4590                             // If we didn't remove it, the cross-profile ResolveInfo would be twice
4591                             // in the result.
4592                             result.remove(xpResolveInfo);
4593                         }
4594                         if (result.size() == 0) {
4595                             result.add(xpDomainInfo.resolveInfo);
4596                             return result;
4597                         }
4598                     } else if (result.size() <= 1) {
4599                         return result;
4600                     }
4601                     result = filterCandidatesWithDomainPreferredActivitiesLPr(intent, flags, result,
4602                             xpDomainInfo, userId);
4603                     Collections.sort(result, mResolvePrioritySorter);
4604                 }
4605                 return result;
4606             }
4607             final PackageParser.Package pkg = mPackages.get(pkgName);
4608             if (pkg != null) {
4609                 return filterIfNotPrimaryUser(
4610                         mActivities.queryIntentForPackage(
4611                                 intent, resolvedType, flags, pkg.activities, userId),
4612                         userId);
4613             }
4614             return new ArrayList<ResolveInfo>();
4615         }
4616     }
4617 
4618     private static class CrossProfileDomainInfo {
4619         /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
4620         ResolveInfo resolveInfo;
4621         /* Best domain verification status of the activities found in the other profile */
4622         int bestDomainVerificationStatus;
4623     }
4624 
getCrossProfileDomainPreferredLpr(Intent intent, String resolvedType, int flags, int sourceUserId, int parentUserId)4625     private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
4626             String resolvedType, int flags, int sourceUserId, int parentUserId) {
4627         if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
4628                 sourceUserId)) {
4629             return null;
4630         }
4631         List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
4632                 resolvedType, flags, parentUserId);
4633 
4634         if (resultTargetUser == null || resultTargetUser.isEmpty()) {
4635             return null;
4636         }
4637         CrossProfileDomainInfo result = null;
4638         int size = resultTargetUser.size();
4639         for (int i = 0; i < size; i++) {
4640             ResolveInfo riTargetUser = resultTargetUser.get(i);
4641             // Intent filter verification is only for filters that specify a host. So don't return
4642             // those that handle all web uris.
4643             if (riTargetUser.handleAllWebDataURI) {
4644                 continue;
4645             }
4646             String packageName = riTargetUser.activityInfo.packageName;
4647             PackageSetting ps = mSettings.mPackages.get(packageName);
4648             if (ps == null) {
4649                 continue;
4650             }
4651             long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
4652             int status = (int)(verificationState >> 32);
4653             if (result == null) {
4654                 result = new CrossProfileDomainInfo();
4655                 result.resolveInfo =
4656                         createForwardingResolveInfo(new IntentFilter(), sourceUserId, parentUserId);
4657                 result.bestDomainVerificationStatus = status;
4658             } else {
4659                 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
4660                         result.bestDomainVerificationStatus);
4661             }
4662         }
4663         // Don't consider matches with status NEVER across profiles.
4664         if (result != null && result.bestDomainVerificationStatus
4665                 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
4666             return null;
4667         }
4668         return result;
4669     }
4670 
4671     /**
4672      * Verification statuses are ordered from the worse to the best, except for
4673      * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
4674      */
bestDomainVerificationStatus(int status1, int status2)4675     private int bestDomainVerificationStatus(int status1, int status2) {
4676         if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
4677             return status2;
4678         }
4679         if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
4680             return status1;
4681         }
4682         return (int) MathUtils.max(status1, status2);
4683     }
4684 
isUserEnabled(int userId)4685     private boolean isUserEnabled(int userId) {
4686         long callingId = Binder.clearCallingIdentity();
4687         try {
4688             UserInfo userInfo = sUserManager.getUserInfo(userId);
4689             return userInfo != null && userInfo.isEnabled();
4690         } finally {
4691             Binder.restoreCallingIdentity(callingId);
4692         }
4693     }
4694 
4695     /**
4696      * Filter out activities with primaryUserOnly flag set, when current user is not the owner.
4697      *
4698      * @return filtered list
4699      */
filterIfNotPrimaryUser(List<ResolveInfo> resolveInfos, int userId)4700     private List<ResolveInfo> filterIfNotPrimaryUser(List<ResolveInfo> resolveInfos, int userId) {
4701         if (userId == UserHandle.USER_OWNER) {
4702             return resolveInfos;
4703         }
4704         for (int i = resolveInfos.size() - 1; i >= 0; i--) {
4705             ResolveInfo info = resolveInfos.get(i);
4706             if ((info.activityInfo.flags & ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
4707                 resolveInfos.remove(i);
4708             }
4709         }
4710         return resolveInfos;
4711     }
4712 
hasWebURI(Intent intent)4713     private static boolean hasWebURI(Intent intent) {
4714         if (intent.getData() == null) {
4715             return false;
4716         }
4717         final String scheme = intent.getScheme();
4718         if (TextUtils.isEmpty(scheme)) {
4719             return false;
4720         }
4721         return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
4722     }
4723 
filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent, int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo, int userId)4724     private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
4725             int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
4726             int userId) {
4727         final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
4728 
4729         if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
4730             Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
4731                     candidates.size());
4732         }
4733 
4734         ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
4735         ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
4736         ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
4737         ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
4738         ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
4739         ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
4740 
4741         synchronized (mPackages) {
4742             final int count = candidates.size();
4743             // First, try to use linked apps. Partition the candidates into four lists:
4744             // one for the final results, one for the "do not use ever", one for "undefined status"
4745             // and finally one for "browser app type".
4746             for (int n=0; n<count; n++) {
4747                 ResolveInfo info = candidates.get(n);
4748                 String packageName = info.activityInfo.packageName;
4749                 PackageSetting ps = mSettings.mPackages.get(packageName);
4750                 if (ps != null) {
4751                     // Add to the special match all list (Browser use case)
4752                     if (info.handleAllWebDataURI) {
4753                         matchAllList.add(info);
4754                         continue;
4755                     }
4756                     // Try to get the status from User settings first
4757                     long packedStatus = getDomainVerificationStatusLPr(ps, userId);
4758                     int status = (int)(packedStatus >> 32);
4759                     int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
4760                     if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
4761                         if (DEBUG_DOMAIN_VERIFICATION) {
4762                             Slog.i(TAG, "  + always: " + info.activityInfo.packageName
4763                                     + " : linkgen=" + linkGeneration);
4764                         }
4765                         // Use link-enabled generation as preferredOrder, i.e.
4766                         // prefer newly-enabled over earlier-enabled.
4767                         info.preferredOrder = linkGeneration;
4768                         alwaysList.add(info);
4769                     } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
4770                         if (DEBUG_DOMAIN_VERIFICATION) {
4771                             Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
4772                         }
4773                         neverList.add(info);
4774                     } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
4775                         if (DEBUG_DOMAIN_VERIFICATION) {
4776                             Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
4777                         }
4778                         alwaysAskList.add(info);
4779                     } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
4780                             status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
4781                         if (DEBUG_DOMAIN_VERIFICATION) {
4782                             Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
4783                         }
4784                         undefinedList.add(info);
4785                     }
4786                 }
4787             }
4788 
4789             // We'll want to include browser possibilities in a few cases
4790             boolean includeBrowser = false;
4791 
4792             // First try to add the "always" resolution(s) for the current user, if any
4793             if (alwaysList.size() > 0) {
4794                 result.addAll(alwaysList);
4795             } else {
4796                 // Add all undefined apps as we want them to appear in the disambiguation dialog.
4797                 result.addAll(undefinedList);
4798                 // Maybe add one for the other profile.
4799                 if (xpDomainInfo != null && (
4800                         xpDomainInfo.bestDomainVerificationStatus
4801                         != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
4802                     result.add(xpDomainInfo.resolveInfo);
4803                 }
4804                 includeBrowser = true;
4805             }
4806 
4807             // The presence of any 'always ask' alternatives means we'll also offer browsers.
4808             // If there were 'always' entries their preferred order has been set, so we also
4809             // back that off to make the alternatives equivalent
4810             if (alwaysAskList.size() > 0) {
4811                 for (ResolveInfo i : result) {
4812                     i.preferredOrder = 0;
4813                 }
4814                 result.addAll(alwaysAskList);
4815                 includeBrowser = true;
4816             }
4817 
4818             if (includeBrowser) {
4819                 // Also add browsers (all of them or only the default one)
4820                 if (DEBUG_DOMAIN_VERIFICATION) {
4821                     Slog.v(TAG, "   ...including browsers in candidate set");
4822                 }
4823                 if ((matchFlags & MATCH_ALL) != 0) {
4824                     result.addAll(matchAllList);
4825                 } else {
4826                     // Browser/generic handling case.  If there's a default browser, go straight
4827                     // to that (but only if there is no other higher-priority match).
4828                     final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
4829                     int maxMatchPrio = 0;
4830                     ResolveInfo defaultBrowserMatch = null;
4831                     final int numCandidates = matchAllList.size();
4832                     for (int n = 0; n < numCandidates; n++) {
4833                         ResolveInfo info = matchAllList.get(n);
4834                         // track the highest overall match priority...
4835                         if (info.priority > maxMatchPrio) {
4836                             maxMatchPrio = info.priority;
4837                         }
4838                         // ...and the highest-priority default browser match
4839                         if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
4840                             if (defaultBrowserMatch == null
4841                                     || (defaultBrowserMatch.priority < info.priority)) {
4842                                 if (debug) {
4843                                     Slog.v(TAG, "Considering default browser match " + info);
4844                                 }
4845                                 defaultBrowserMatch = info;
4846                             }
4847                         }
4848                     }
4849                     if (defaultBrowserMatch != null
4850                             && defaultBrowserMatch.priority >= maxMatchPrio
4851                             && !TextUtils.isEmpty(defaultBrowserPackageName))
4852                     {
4853                         if (debug) {
4854                             Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
4855                         }
4856                         result.add(defaultBrowserMatch);
4857                     } else {
4858                         result.addAll(matchAllList);
4859                     }
4860                 }
4861 
4862                 // If there is nothing selected, add all candidates and remove the ones that the user
4863                 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
4864                 if (result.size() == 0) {
4865                     result.addAll(candidates);
4866                     result.removeAll(neverList);
4867                 }
4868             }
4869         }
4870         if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
4871             Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
4872                     result.size());
4873             for (ResolveInfo info : result) {
4874                 Slog.v(TAG, "  + " + info.activityInfo);
4875             }
4876         }
4877         return result;
4878     }
4879 
4880     // Returns a packed value as a long:
4881     //
4882     // high 'int'-sized word: link status: undefined/ask/never/always.
4883     // low 'int'-sized word: relative priority among 'always' results.
getDomainVerificationStatusLPr(PackageSetting ps, int userId)4884     private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
4885         long result = ps.getDomainVerificationStatusForUser(userId);
4886         // if none available, get the master status
4887         if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
4888             if (ps.getIntentFilterVerificationInfo() != null) {
4889                 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
4890             }
4891         }
4892         return result;
4893     }
4894 
querySkipCurrentProfileIntents( List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, int flags, int sourceUserId)4895     private ResolveInfo querySkipCurrentProfileIntents(
4896             List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
4897             int flags, int sourceUserId) {
4898         if (matchingFilters != null) {
4899             int size = matchingFilters.size();
4900             for (int i = 0; i < size; i ++) {
4901                 CrossProfileIntentFilter filter = matchingFilters.get(i);
4902                 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
4903                     // Checking if there are activities in the target user that can handle the
4904                     // intent.
4905                     ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType,
4906                             flags, sourceUserId);
4907                     if (resolveInfo != null) {
4908                         return resolveInfo;
4909                     }
4910                 }
4911             }
4912         }
4913         return null;
4914     }
4915 
4916     // Return matching ResolveInfo if any for skip current profile intent filters.
queryCrossProfileIntents( List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, int flags, int sourceUserId)4917     private ResolveInfo queryCrossProfileIntents(
4918             List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
4919             int flags, int sourceUserId) {
4920         if (matchingFilters != null) {
4921             // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
4922             // match the same intent. For performance reasons, it is better not to
4923             // run queryIntent twice for the same userId
4924             SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
4925             int size = matchingFilters.size();
4926             for (int i = 0; i < size; i++) {
4927                 CrossProfileIntentFilter filter = matchingFilters.get(i);
4928                 int targetUserId = filter.getTargetUserId();
4929                 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) == 0
4930                         && !alreadyTriedUserIds.get(targetUserId)) {
4931                     // Checking if there are activities in the target user that can handle the
4932                     // intent.
4933                     ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType,
4934                             flags, sourceUserId);
4935                     if (resolveInfo != null) return resolveInfo;
4936                     alreadyTriedUserIds.put(targetUserId, true);
4937                 }
4938             }
4939         }
4940         return null;
4941     }
4942 
checkTargetCanHandle(CrossProfileIntentFilter filter, Intent intent, String resolvedType, int flags, int sourceUserId)4943     private ResolveInfo checkTargetCanHandle(CrossProfileIntentFilter filter, Intent intent,
4944             String resolvedType, int flags, int sourceUserId) {
4945         List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
4946                 resolvedType, flags, filter.getTargetUserId());
4947         if (resultTargetUser != null && !resultTargetUser.isEmpty()) {
4948             return createForwardingResolveInfo(filter, sourceUserId, filter.getTargetUserId());
4949         }
4950         return null;
4951     }
4952 
createForwardingResolveInfo(IntentFilter filter, int sourceUserId, int targetUserId)4953     private ResolveInfo createForwardingResolveInfo(IntentFilter filter,
4954             int sourceUserId, int targetUserId) {
4955         ResolveInfo forwardingResolveInfo = new ResolveInfo();
4956         String className;
4957         if (targetUserId == UserHandle.USER_OWNER) {
4958             className = FORWARD_INTENT_TO_USER_OWNER;
4959         } else {
4960             className = FORWARD_INTENT_TO_MANAGED_PROFILE;
4961         }
4962         ComponentName forwardingActivityComponentName = new ComponentName(
4963                 mAndroidApplication.packageName, className);
4964         ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
4965                 sourceUserId);
4966         if (targetUserId == UserHandle.USER_OWNER) {
4967             forwardingActivityInfo.showUserIcon = UserHandle.USER_OWNER;
4968             forwardingResolveInfo.noResourceId = true;
4969         }
4970         forwardingResolveInfo.activityInfo = forwardingActivityInfo;
4971         forwardingResolveInfo.priority = 0;
4972         forwardingResolveInfo.preferredOrder = 0;
4973         forwardingResolveInfo.match = 0;
4974         forwardingResolveInfo.isDefault = true;
4975         forwardingResolveInfo.filter = filter;
4976         forwardingResolveInfo.targetUserId = targetUserId;
4977         return forwardingResolveInfo;
4978     }
4979 
4980     @Override
queryIntentActivityOptions(ComponentName caller, Intent[] specifics, String[] specificTypes, Intent intent, String resolvedType, int flags, int userId)4981     public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
4982             Intent[] specifics, String[] specificTypes, Intent intent,
4983             String resolvedType, int flags, int userId) {
4984         if (!sUserManager.exists(userId)) return Collections.emptyList();
4985         enforceCrossUserPermission(Binder.getCallingUid(), userId, false,
4986                 false, "query intent activity options");
4987         final String resultsAction = intent.getAction();
4988 
4989         List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags
4990                 | PackageManager.GET_RESOLVED_FILTER, userId);
4991 
4992         if (DEBUG_INTENT_MATCHING) {
4993             Log.v(TAG, "Query " + intent + ": " + results);
4994         }
4995 
4996         int specificsPos = 0;
4997         int N;
4998 
4999         // todo: note that the algorithm used here is O(N^2).  This
5000         // isn't a problem in our current environment, but if we start running
5001         // into situations where we have more than 5 or 10 matches then this
5002         // should probably be changed to something smarter...
5003 
5004         // First we go through and resolve each of the specific items
5005         // that were supplied, taking care of removing any corresponding
5006         // duplicate items in the generic resolve list.
5007         if (specifics != null) {
5008             for (int i=0; i<specifics.length; i++) {
5009                 final Intent sintent = specifics[i];
5010                 if (sintent == null) {
5011                     continue;
5012                 }
5013 
5014                 if (DEBUG_INTENT_MATCHING) {
5015                     Log.v(TAG, "Specific #" + i + ": " + sintent);
5016                 }
5017 
5018                 String action = sintent.getAction();
5019                 if (resultsAction != null && resultsAction.equals(action)) {
5020                     // If this action was explicitly requested, then don't
5021                     // remove things that have it.
5022                     action = null;
5023                 }
5024 
5025                 ResolveInfo ri = null;
5026                 ActivityInfo ai = null;
5027 
5028                 ComponentName comp = sintent.getComponent();
5029                 if (comp == null) {
5030                     ri = resolveIntent(
5031                         sintent,
5032                         specificTypes != null ? specificTypes[i] : null,
5033                             flags, userId);
5034                     if (ri == null) {
5035                         continue;
5036                     }
5037                     if (ri == mResolveInfo) {
5038                         // ACK!  Must do something better with this.
5039                     }
5040                     ai = ri.activityInfo;
5041                     comp = new ComponentName(ai.applicationInfo.packageName,
5042                             ai.name);
5043                 } else {
5044                     ai = getActivityInfo(comp, flags, userId);
5045                     if (ai == null) {
5046                         continue;
5047                     }
5048                 }
5049 
5050                 // Look for any generic query activities that are duplicates
5051                 // of this specific one, and remove them from the results.
5052                 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
5053                 N = results.size();
5054                 int j;
5055                 for (j=specificsPos; j<N; j++) {
5056                     ResolveInfo sri = results.get(j);
5057                     if ((sri.activityInfo.name.equals(comp.getClassName())
5058                             && sri.activityInfo.applicationInfo.packageName.equals(
5059                                     comp.getPackageName()))
5060                         || (action != null && sri.filter.matchAction(action))) {
5061                         results.remove(j);
5062                         if (DEBUG_INTENT_MATCHING) Log.v(
5063                             TAG, "Removing duplicate item from " + j
5064                             + " due to specific " + specificsPos);
5065                         if (ri == null) {
5066                             ri = sri;
5067                         }
5068                         j--;
5069                         N--;
5070                     }
5071                 }
5072 
5073                 // Add this specific item to its proper place.
5074                 if (ri == null) {
5075                     ri = new ResolveInfo();
5076                     ri.activityInfo = ai;
5077                 }
5078                 results.add(specificsPos, ri);
5079                 ri.specificIndex = i;
5080                 specificsPos++;
5081             }
5082         }
5083 
5084         // Now we go through the remaining generic results and remove any
5085         // duplicate actions that are found here.
5086         N = results.size();
5087         for (int i=specificsPos; i<N-1; i++) {
5088             final ResolveInfo rii = results.get(i);
5089             if (rii.filter == null) {
5090                 continue;
5091             }
5092 
5093             // Iterate over all of the actions of this result's intent
5094             // filter...  typically this should be just one.
5095             final Iterator<String> it = rii.filter.actionsIterator();
5096             if (it == null) {
5097                 continue;
5098             }
5099             while (it.hasNext()) {
5100                 final String action = it.next();
5101                 if (resultsAction != null && resultsAction.equals(action)) {
5102                     // If this action was explicitly requested, then don't
5103                     // remove things that have it.
5104                     continue;
5105                 }
5106                 for (int j=i+1; j<N; j++) {
5107                     final ResolveInfo rij = results.get(j);
5108                     if (rij.filter != null && rij.filter.hasAction(action)) {
5109                         results.remove(j);
5110                         if (DEBUG_INTENT_MATCHING) Log.v(
5111                             TAG, "Removing duplicate item from " + j
5112                             + " due to action " + action + " at " + i);
5113                         j--;
5114                         N--;
5115                     }
5116                 }
5117             }
5118 
5119             // If the caller didn't request filter information, drop it now
5120             // so we don't have to marshall/unmarshall it.
5121             if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
5122                 rii.filter = null;
5123             }
5124         }
5125 
5126         // Filter out the caller activity if so requested.
5127         if (caller != null) {
5128             N = results.size();
5129             for (int i=0; i<N; i++) {
5130                 ActivityInfo ainfo = results.get(i).activityInfo;
5131                 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
5132                         && caller.getClassName().equals(ainfo.name)) {
5133                     results.remove(i);
5134                     break;
5135                 }
5136             }
5137         }
5138 
5139         // If the caller didn't request filter information,
5140         // drop them now so we don't have to
5141         // marshall/unmarshall it.
5142         if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
5143             N = results.size();
5144             for (int i=0; i<N; i++) {
5145                 results.get(i).filter = null;
5146             }
5147         }
5148 
5149         if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
5150         return results;
5151     }
5152 
5153     @Override
queryIntentReceivers(Intent intent, String resolvedType, int flags, int userId)5154     public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags,
5155             int userId) {
5156         if (!sUserManager.exists(userId)) return Collections.emptyList();
5157         ComponentName comp = intent.getComponent();
5158         if (comp == null) {
5159             if (intent.getSelector() != null) {
5160                 intent = intent.getSelector();
5161                 comp = intent.getComponent();
5162             }
5163         }
5164         if (comp != null) {
5165             List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
5166             ActivityInfo ai = getReceiverInfo(comp, flags, userId);
5167             if (ai != null) {
5168                 ResolveInfo ri = new ResolveInfo();
5169                 ri.activityInfo = ai;
5170                 list.add(ri);
5171             }
5172             return list;
5173         }
5174 
5175         // reader
5176         synchronized (mPackages) {
5177             String pkgName = intent.getPackage();
5178             if (pkgName == null) {
5179                 return mReceivers.queryIntent(intent, resolvedType, flags, userId);
5180             }
5181             final PackageParser.Package pkg = mPackages.get(pkgName);
5182             if (pkg != null) {
5183                 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
5184                         userId);
5185             }
5186             return null;
5187         }
5188     }
5189 
5190     @Override
resolveService(Intent intent, String resolvedType, int flags, int userId)5191     public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
5192         List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId);
5193         if (!sUserManager.exists(userId)) return null;
5194         if (query != null) {
5195             if (query.size() >= 1) {
5196                 // If there is more than one service with the same priority,
5197                 // just arbitrarily pick the first one.
5198                 return query.get(0);
5199             }
5200         }
5201         return null;
5202     }
5203 
5204     @Override
queryIntentServices(Intent intent, String resolvedType, int flags, int userId)5205     public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags,
5206             int userId) {
5207         if (!sUserManager.exists(userId)) return Collections.emptyList();
5208         ComponentName comp = intent.getComponent();
5209         if (comp == null) {
5210             if (intent.getSelector() != null) {
5211                 intent = intent.getSelector();
5212                 comp = intent.getComponent();
5213             }
5214         }
5215         if (comp != null) {
5216             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
5217             final ServiceInfo si = getServiceInfo(comp, flags, userId);
5218             if (si != null) {
5219                 final ResolveInfo ri = new ResolveInfo();
5220                 ri.serviceInfo = si;
5221                 list.add(ri);
5222             }
5223             return list;
5224         }
5225 
5226         // reader
5227         synchronized (mPackages) {
5228             String pkgName = intent.getPackage();
5229             if (pkgName == null) {
5230                 return mServices.queryIntent(intent, resolvedType, flags, userId);
5231             }
5232             final PackageParser.Package pkg = mPackages.get(pkgName);
5233             if (pkg != null) {
5234                 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
5235                         userId);
5236             }
5237             return null;
5238         }
5239     }
5240 
5241     @Override
queryIntentContentProviders( Intent intent, String resolvedType, int flags, int userId)5242     public List<ResolveInfo> queryIntentContentProviders(
5243             Intent intent, String resolvedType, int flags, int userId) {
5244         if (!sUserManager.exists(userId)) return Collections.emptyList();
5245         ComponentName comp = intent.getComponent();
5246         if (comp == null) {
5247             if (intent.getSelector() != null) {
5248                 intent = intent.getSelector();
5249                 comp = intent.getComponent();
5250             }
5251         }
5252         if (comp != null) {
5253             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
5254             final ProviderInfo pi = getProviderInfo(comp, flags, userId);
5255             if (pi != null) {
5256                 final ResolveInfo ri = new ResolveInfo();
5257                 ri.providerInfo = pi;
5258                 list.add(ri);
5259             }
5260             return list;
5261         }
5262 
5263         // reader
5264         synchronized (mPackages) {
5265             String pkgName = intent.getPackage();
5266             if (pkgName == null) {
5267                 return mProviders.queryIntent(intent, resolvedType, flags, userId);
5268             }
5269             final PackageParser.Package pkg = mPackages.get(pkgName);
5270             if (pkg != null) {
5271                 return mProviders.queryIntentForPackage(
5272                         intent, resolvedType, flags, pkg.providers, userId);
5273             }
5274             return null;
5275         }
5276     }
5277 
5278     @Override
getInstalledPackages(int flags, int userId)5279     public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
5280         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
5281 
5282         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "get installed packages");
5283 
5284         // writer
5285         synchronized (mPackages) {
5286             ArrayList<PackageInfo> list;
5287             if (listUninstalled) {
5288                 list = new ArrayList<PackageInfo>(mSettings.mPackages.size());
5289                 for (PackageSetting ps : mSettings.mPackages.values()) {
5290                     PackageInfo pi;
5291                     if (ps.pkg != null) {
5292                         pi = generatePackageInfo(ps.pkg, flags, userId);
5293                     } else {
5294                         pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
5295                     }
5296                     if (pi != null) {
5297                         list.add(pi);
5298                     }
5299                 }
5300             } else {
5301                 list = new ArrayList<PackageInfo>(mPackages.size());
5302                 for (PackageParser.Package p : mPackages.values()) {
5303                     PackageInfo pi = generatePackageInfo(p, flags, userId);
5304                     if (pi != null) {
5305                         list.add(pi);
5306                     }
5307                 }
5308             }
5309 
5310             return new ParceledListSlice<PackageInfo>(list);
5311         }
5312     }
5313 
addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, String[] permissions, boolean[] tmp, int flags, int userId)5314     private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
5315             String[] permissions, boolean[] tmp, int flags, int userId) {
5316         int numMatch = 0;
5317         final PermissionsState permissionsState = ps.getPermissionsState();
5318         for (int i=0; i<permissions.length; i++) {
5319             final String permission = permissions[i];
5320             if (permissionsState.hasPermission(permission, userId)) {
5321                 tmp[i] = true;
5322                 numMatch++;
5323             } else {
5324                 tmp[i] = false;
5325             }
5326         }
5327         if (numMatch == 0) {
5328             return;
5329         }
5330         PackageInfo pi;
5331         if (ps.pkg != null) {
5332             pi = generatePackageInfo(ps.pkg, flags, userId);
5333         } else {
5334             pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
5335         }
5336         // The above might return null in cases of uninstalled apps or install-state
5337         // skew across users/profiles.
5338         if (pi != null) {
5339             if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
5340                 if (numMatch == permissions.length) {
5341                     pi.requestedPermissions = permissions;
5342                 } else {
5343                     pi.requestedPermissions = new String[numMatch];
5344                     numMatch = 0;
5345                     for (int i=0; i<permissions.length; i++) {
5346                         if (tmp[i]) {
5347                             pi.requestedPermissions[numMatch] = permissions[i];
5348                             numMatch++;
5349                         }
5350                     }
5351                 }
5352             }
5353             list.add(pi);
5354         }
5355     }
5356 
5357     @Override
getPackagesHoldingPermissions( String[] permissions, int flags, int userId)5358     public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
5359             String[] permissions, int flags, int userId) {
5360         if (!sUserManager.exists(userId)) return null;
5361         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
5362 
5363         // writer
5364         synchronized (mPackages) {
5365             ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
5366             boolean[] tmpBools = new boolean[permissions.length];
5367             if (listUninstalled) {
5368                 for (PackageSetting ps : mSettings.mPackages.values()) {
5369                     addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId);
5370                 }
5371             } else {
5372                 for (PackageParser.Package pkg : mPackages.values()) {
5373                     PackageSetting ps = (PackageSetting)pkg.mExtras;
5374                     if (ps != null) {
5375                         addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
5376                                 userId);
5377                     }
5378                 }
5379             }
5380 
5381             return new ParceledListSlice<PackageInfo>(list);
5382         }
5383     }
5384 
5385     @Override
getInstalledApplications(int flags, int userId)5386     public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
5387         if (!sUserManager.exists(userId)) return null;
5388         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
5389 
5390         // writer
5391         synchronized (mPackages) {
5392             ArrayList<ApplicationInfo> list;
5393             if (listUninstalled) {
5394                 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size());
5395                 for (PackageSetting ps : mSettings.mPackages.values()) {
5396                     ApplicationInfo ai;
5397                     if (ps.pkg != null) {
5398                         ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
5399                                 ps.readUserState(userId), userId);
5400                     } else {
5401                         ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
5402                     }
5403                     if (ai != null) {
5404                         list.add(ai);
5405                     }
5406                 }
5407             } else {
5408                 list = new ArrayList<ApplicationInfo>(mPackages.size());
5409                 for (PackageParser.Package p : mPackages.values()) {
5410                     if (p.mExtras != null) {
5411                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
5412                                 ((PackageSetting)p.mExtras).readUserState(userId), userId);
5413                         if (ai != null) {
5414                             list.add(ai);
5415                         }
5416                     }
5417                 }
5418             }
5419 
5420             return new ParceledListSlice<ApplicationInfo>(list);
5421         }
5422     }
5423 
getPersistentApplications(int flags)5424     public List<ApplicationInfo> getPersistentApplications(int flags) {
5425         final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
5426 
5427         // reader
5428         synchronized (mPackages) {
5429             final Iterator<PackageParser.Package> i = mPackages.values().iterator();
5430             final int userId = UserHandle.getCallingUserId();
5431             while (i.hasNext()) {
5432                 final PackageParser.Package p = i.next();
5433                 if (p.applicationInfo != null
5434                         && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0
5435                         && (!mSafeMode || isSystemApp(p))) {
5436                     PackageSetting ps = mSettings.mPackages.get(p.packageName);
5437                     if (ps != null) {
5438                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
5439                                 ps.readUserState(userId), userId);
5440                         if (ai != null) {
5441                             finalList.add(ai);
5442                         }
5443                     }
5444                 }
5445             }
5446         }
5447 
5448         return finalList;
5449     }
5450 
5451     @Override
resolveContentProvider(String name, int flags, int userId)5452     public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
5453         if (!sUserManager.exists(userId)) return null;
5454         // reader
5455         synchronized (mPackages) {
5456             final PackageParser.Provider provider = mProvidersByAuthority.get(name);
5457             PackageSetting ps = provider != null
5458                     ? mSettings.mPackages.get(provider.owner.packageName)
5459                     : null;
5460             return ps != null
5461                     && mSettings.isEnabledLPr(provider.info, flags, userId)
5462                     && (!mSafeMode || (provider.info.applicationInfo.flags
5463                             &ApplicationInfo.FLAG_SYSTEM) != 0)
5464                     ? PackageParser.generateProviderInfo(provider, flags,
5465                             ps.readUserState(userId), userId)
5466                     : null;
5467         }
5468     }
5469 
5470     /**
5471      * @deprecated
5472      */
5473     @Deprecated
querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo)5474     public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
5475         // reader
5476         synchronized (mPackages) {
5477             final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
5478                     .entrySet().iterator();
5479             final int userId = UserHandle.getCallingUserId();
5480             while (i.hasNext()) {
5481                 Map.Entry<String, PackageParser.Provider> entry = i.next();
5482                 PackageParser.Provider p = entry.getValue();
5483                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
5484 
5485                 if (ps != null && p.syncable
5486                         && (!mSafeMode || (p.info.applicationInfo.flags
5487                                 &ApplicationInfo.FLAG_SYSTEM) != 0)) {
5488                     ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
5489                             ps.readUserState(userId), userId);
5490                     if (info != null) {
5491                         outNames.add(entry.getKey());
5492                         outInfo.add(info);
5493                     }
5494                 }
5495             }
5496         }
5497     }
5498 
5499     @Override
queryContentProviders(String processName, int uid, int flags)5500     public ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
5501             int uid, int flags) {
5502         ArrayList<ProviderInfo> finalList = null;
5503         // reader
5504         synchronized (mPackages) {
5505             final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
5506             final int userId = processName != null ?
5507                     UserHandle.getUserId(uid) : UserHandle.getCallingUserId();
5508             while (i.hasNext()) {
5509                 final PackageParser.Provider p = i.next();
5510                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
5511                 if (ps != null && p.info.authority != null
5512                         && (processName == null
5513                                 || (p.info.processName.equals(processName)
5514                                         && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
5515                         && mSettings.isEnabledLPr(p.info, flags, userId)
5516                         && (!mSafeMode
5517                                 || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
5518                     if (finalList == null) {
5519                         finalList = new ArrayList<ProviderInfo>(3);
5520                     }
5521                     ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
5522                             ps.readUserState(userId), userId);
5523                     if (info != null) {
5524                         finalList.add(info);
5525                     }
5526                 }
5527             }
5528         }
5529 
5530         if (finalList != null) {
5531             Collections.sort(finalList, mProviderInitOrderSorter);
5532             return new ParceledListSlice<ProviderInfo>(finalList);
5533         }
5534 
5535         return null;
5536     }
5537 
5538     @Override
getInstrumentationInfo(ComponentName name, int flags)5539     public InstrumentationInfo getInstrumentationInfo(ComponentName name,
5540             int flags) {
5541         // reader
5542         synchronized (mPackages) {
5543             final PackageParser.Instrumentation i = mInstrumentation.get(name);
5544             return PackageParser.generateInstrumentationInfo(i, flags);
5545         }
5546     }
5547 
5548     @Override
queryInstrumentation(String targetPackage, int flags)5549     public List<InstrumentationInfo> queryInstrumentation(String targetPackage,
5550             int flags) {
5551         ArrayList<InstrumentationInfo> finalList =
5552             new ArrayList<InstrumentationInfo>();
5553 
5554         // reader
5555         synchronized (mPackages) {
5556             final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
5557             while (i.hasNext()) {
5558                 final PackageParser.Instrumentation p = i.next();
5559                 if (targetPackage == null
5560                         || targetPackage.equals(p.info.targetPackage)) {
5561                     InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
5562                             flags);
5563                     if (ii != null) {
5564                         finalList.add(ii);
5565                     }
5566                 }
5567             }
5568         }
5569 
5570         return finalList;
5571     }
5572 
createIdmapsForPackageLI(PackageParser.Package pkg)5573     private void createIdmapsForPackageLI(PackageParser.Package pkg) {
5574         ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName);
5575         if (overlays == null) {
5576             Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages");
5577             return;
5578         }
5579         for (PackageParser.Package opkg : overlays.values()) {
5580             // Not much to do if idmap fails: we already logged the error
5581             // and we certainly don't want to abort installation of pkg simply
5582             // because an overlay didn't fit properly. For these reasons,
5583             // ignore the return value of createIdmapForPackagePairLI.
5584             createIdmapForPackagePairLI(pkg, opkg);
5585         }
5586     }
5587 
createIdmapForPackagePairLI(PackageParser.Package pkg, PackageParser.Package opkg)5588     private boolean createIdmapForPackagePairLI(PackageParser.Package pkg,
5589             PackageParser.Package opkg) {
5590         if (!opkg.mTrustedOverlay) {
5591             Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " +
5592                     opkg.baseCodePath + ": overlay not trusted");
5593             return false;
5594         }
5595         ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName);
5596         if (overlaySet == null) {
5597             Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " +
5598                     opkg.baseCodePath + " but target package has no known overlays");
5599             return false;
5600         }
5601         final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
5602         // TODO: generate idmap for split APKs
5603         if (mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid) != 0) {
5604             Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and "
5605                     + opkg.baseCodePath);
5606             return false;
5607         }
5608         PackageParser.Package[] overlayArray =
5609             overlaySet.values().toArray(new PackageParser.Package[0]);
5610         Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
5611             public int compare(PackageParser.Package p1, PackageParser.Package p2) {
5612                 return p1.mOverlayPriority - p2.mOverlayPriority;
5613             }
5614         };
5615         Arrays.sort(overlayArray, cmp);
5616 
5617         pkg.applicationInfo.resourceDirs = new String[overlayArray.length];
5618         int i = 0;
5619         for (PackageParser.Package p : overlayArray) {
5620             pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath;
5621         }
5622         return true;
5623     }
5624 
scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime)5625     private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
5626         final File[] files = dir.listFiles();
5627         if (ArrayUtils.isEmpty(files)) {
5628             Log.d(TAG, "No files in app dir " + dir);
5629             return;
5630         }
5631 
5632         if (DEBUG_PACKAGE_SCANNING) {
5633             Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
5634                     + " flags=0x" + Integer.toHexString(parseFlags));
5635         }
5636 
5637         for (File file : files) {
5638             final boolean isPackage = (isApkFile(file) || file.isDirectory())
5639                     && !PackageInstallerService.isStageName(file.getName());
5640             if (!isPackage) {
5641                 // Ignore entries which are not packages
5642                 continue;
5643             }
5644             try {
5645                 scanPackageLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
5646                         scanFlags, currentTime, null);
5647             } catch (PackageManagerException e) {
5648                 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage());
5649 
5650                 // Delete invalid userdata apps
5651                 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
5652                         e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {
5653                     logCriticalInfo(Log.WARN, "Deleting invalid package at " + file);
5654                     if (file.isDirectory()) {
5655                         mInstaller.rmPackageDir(file.getAbsolutePath());
5656                     } else {
5657                         file.delete();
5658                     }
5659                 }
5660             }
5661         }
5662     }
5663 
getSettingsProblemFile()5664     private static File getSettingsProblemFile() {
5665         File dataDir = Environment.getDataDirectory();
5666         File systemDir = new File(dataDir, "system");
5667         File fname = new File(systemDir, "uiderrors.txt");
5668         return fname;
5669     }
5670 
reportSettingsProblem(int priority, String msg)5671     static void reportSettingsProblem(int priority, String msg) {
5672         logCriticalInfo(priority, msg);
5673     }
5674 
logCriticalInfo(int priority, String msg)5675     static void logCriticalInfo(int priority, String msg) {
5676         Slog.println(priority, TAG, msg);
5677         EventLogTags.writePmCriticalInfo(msg);
5678         try {
5679             File fname = getSettingsProblemFile();
5680             FileOutputStream out = new FileOutputStream(fname, true);
5681             PrintWriter pw = new FastPrintWriter(out);
5682             SimpleDateFormat formatter = new SimpleDateFormat();
5683             String dateString = formatter.format(new Date(System.currentTimeMillis()));
5684             pw.println(dateString + ": " + msg);
5685             pw.close();
5686             FileUtils.setPermissions(
5687                     fname.toString(),
5688                     FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
5689                     -1, -1);
5690         } catch (java.io.IOException e) {
5691         }
5692     }
5693 
collectCertificatesLI(PackageParser pp, PackageSetting ps, PackageParser.Package pkg, File srcFile, int parseFlags)5694     private void collectCertificatesLI(PackageParser pp, PackageSetting ps,
5695             PackageParser.Package pkg, File srcFile, int parseFlags)
5696             throws PackageManagerException {
5697         if (ps != null
5698                 && ps.codePath.equals(srcFile)
5699                 && ps.timeStamp == srcFile.lastModified()
5700                 && !isCompatSignatureUpdateNeeded(pkg)
5701                 && !isRecoverSignatureUpdateNeeded(pkg)) {
5702             long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
5703             KeySetManagerService ksms = mSettings.mKeySetManagerService;
5704             ArraySet<PublicKey> signingKs;
5705             synchronized (mPackages) {
5706                 signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
5707             }
5708             if (ps.signatures.mSignatures != null
5709                     && ps.signatures.mSignatures.length != 0
5710                     && signingKs != null) {
5711                 // Optimization: reuse the existing cached certificates
5712                 // if the package appears to be unchanged.
5713                 pkg.mSignatures = ps.signatures.mSignatures;
5714                 pkg.mSigningKeys = signingKs;
5715                 return;
5716             }
5717 
5718             Slog.w(TAG, "PackageSetting for " + ps.name
5719                     + " is missing signatures.  Collecting certs again to recover them.");
5720         } else {
5721             Log.i(TAG, srcFile.toString() + " changed; collecting certs");
5722         }
5723 
5724         try {
5725             pp.collectCertificates(pkg, parseFlags);
5726             pp.collectManifestDigest(pkg);
5727         } catch (PackageParserException e) {
5728             throw PackageManagerException.from(e);
5729         }
5730     }
5731 
5732     /*
5733      *  Scan a package and return the newly parsed package.
5734      *  Returns null in case of errors and the error code is stored in mLastScanError
5735      */
scanPackageLI(File scanFile, int parseFlags, int scanFlags, long currentTime, UserHandle user)5736     private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
5737             long currentTime, UserHandle user) throws PackageManagerException {
5738         if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
5739         parseFlags |= mDefParseFlags;
5740         PackageParser pp = new PackageParser();
5741         pp.setSeparateProcesses(mSeparateProcesses);
5742         pp.setOnlyCoreApps(mOnlyCore);
5743         pp.setDisplayMetrics(mMetrics);
5744 
5745         if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
5746             parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
5747         }
5748 
5749         final PackageParser.Package pkg;
5750         try {
5751             pkg = pp.parsePackage(scanFile, parseFlags);
5752         } catch (PackageParserException e) {
5753             throw PackageManagerException.from(e);
5754         }
5755 
5756         PackageSetting ps = null;
5757         PackageSetting updatedPkg;
5758         // reader
5759         synchronized (mPackages) {
5760             // Look to see if we already know about this package.
5761             String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
5762             if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
5763                 // This package has been renamed to its original name.  Let's
5764                 // use that.
5765                 ps = mSettings.peekPackageLPr(oldName);
5766             }
5767             // If there was no original package, see one for the real package name.
5768             if (ps == null) {
5769                 ps = mSettings.peekPackageLPr(pkg.packageName);
5770             }
5771             // Check to see if this package could be hiding/updating a system
5772             // package.  Must look for it either under the original or real
5773             // package name depending on our state.
5774             updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
5775             if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
5776         }
5777         boolean updatedPkgBetter = false;
5778         // First check if this is a system package that may involve an update
5779         if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
5780             // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
5781             // it needs to drop FLAG_PRIVILEGED.
5782             if (locationIsPrivileged(scanFile)) {
5783                 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
5784             } else {
5785                 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
5786             }
5787 
5788             if (ps != null && !ps.codePath.equals(scanFile)) {
5789                 // The path has changed from what was last scanned...  check the
5790                 // version of the new path against what we have stored to determine
5791                 // what to do.
5792                 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
5793                 if (pkg.mVersionCode <= ps.versionCode) {
5794                     // The system package has been updated and the code path does not match
5795                     // Ignore entry. Skip it.
5796                     if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile
5797                             + " ignored: updated version " + ps.versionCode
5798                             + " better than this " + pkg.mVersionCode);
5799                     if (!updatedPkg.codePath.equals(scanFile)) {
5800                         Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg : "
5801                                 + ps.name + " changing from " + updatedPkg.codePathString
5802                                 + " to " + scanFile);
5803                         updatedPkg.codePath = scanFile;
5804                         updatedPkg.codePathString = scanFile.toString();
5805                         updatedPkg.resourcePath = scanFile;
5806                         updatedPkg.resourcePathString = scanFile.toString();
5807                     }
5808                     updatedPkg.pkg = pkg;
5809                     throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
5810                             "Package " + ps.name + " at " + scanFile
5811                                     + " ignored: updated version " + ps.versionCode
5812                                     + " better than this " + pkg.mVersionCode);
5813                 } else {
5814                     // The current app on the system partition is better than
5815                     // what we have updated to on the data partition; switch
5816                     // back to the system partition version.
5817                     // At this point, its safely assumed that package installation for
5818                     // apps in system partition will go through. If not there won't be a working
5819                     // version of the app
5820                     // writer
5821                     synchronized (mPackages) {
5822                         // Just remove the loaded entries from package lists.
5823                         mPackages.remove(ps.name);
5824                     }
5825 
5826                     logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
5827                             + " reverting from " + ps.codePathString
5828                             + ": new version " + pkg.mVersionCode
5829                             + " better than installed " + ps.versionCode);
5830 
5831                     InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
5832                             ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
5833                     synchronized (mInstallLock) {
5834                         args.cleanUpResourcesLI();
5835                     }
5836                     synchronized (mPackages) {
5837                         mSettings.enableSystemPackageLPw(ps.name);
5838                     }
5839                     updatedPkgBetter = true;
5840                 }
5841             }
5842         }
5843 
5844         if (updatedPkg != null) {
5845             // An updated system app will not have the PARSE_IS_SYSTEM flag set
5846             // initially
5847             parseFlags |= PackageParser.PARSE_IS_SYSTEM;
5848 
5849             // An updated privileged app will not have the PARSE_IS_PRIVILEGED
5850             // flag set initially
5851             if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
5852                 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
5853             }
5854         }
5855 
5856         // Verify certificates against what was last scanned
5857         collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags);
5858 
5859         /*
5860          * A new system app appeared, but we already had a non-system one of the
5861          * same name installed earlier.
5862          */
5863         boolean shouldHideSystemApp = false;
5864         if (updatedPkg == null && ps != null
5865                 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
5866             /*
5867              * Check to make sure the signatures match first. If they don't,
5868              * wipe the installed application and its data.
5869              */
5870             if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
5871                     != PackageManager.SIGNATURE_MATCH) {
5872                 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
5873                         + " signatures don't match existing userdata copy; removing");
5874                 deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false);
5875                 ps = null;
5876             } else {
5877                 /*
5878                  * If the newly-added system app is an older version than the
5879                  * already installed version, hide it. It will be scanned later
5880                  * and re-added like an update.
5881                  */
5882                 if (pkg.mVersionCode <= ps.versionCode) {
5883                     shouldHideSystemApp = true;
5884                     logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
5885                             + " but new version " + pkg.mVersionCode + " better than installed "
5886                             + ps.versionCode + "; hiding system");
5887                 } else {
5888                     /*
5889                      * The newly found system app is a newer version that the
5890                      * one previously installed. Simply remove the
5891                      * already-installed application and replace it with our own
5892                      * while keeping the application data.
5893                      */
5894                     logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
5895                             + " reverting from " + ps.codePathString + ": new version "
5896                             + pkg.mVersionCode + " better than installed " + ps.versionCode);
5897                     InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
5898                             ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
5899                     synchronized (mInstallLock) {
5900                         args.cleanUpResourcesLI();
5901                     }
5902                 }
5903             }
5904         }
5905 
5906         // The apk is forward locked (not public) if its code and resources
5907         // are kept in different files. (except for app in either system or
5908         // vendor path).
5909         // TODO grab this value from PackageSettings
5910         if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
5911             if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
5912                 parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
5913             }
5914         }
5915 
5916         // TODO: extend to support forward-locked splits
5917         String resourcePath = null;
5918         String baseResourcePath = null;
5919         if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
5920             if (ps != null && ps.resourcePathString != null) {
5921                 resourcePath = ps.resourcePathString;
5922                 baseResourcePath = ps.resourcePathString;
5923             } else {
5924                 // Should not happen at all. Just log an error.
5925                 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName);
5926             }
5927         } else {
5928             resourcePath = pkg.codePath;
5929             baseResourcePath = pkg.baseCodePath;
5930         }
5931 
5932         // Set application objects path explicitly.
5933         pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
5934         pkg.applicationInfo.setCodePath(pkg.codePath);
5935         pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
5936         pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
5937         pkg.applicationInfo.setResourcePath(resourcePath);
5938         pkg.applicationInfo.setBaseResourcePath(baseResourcePath);
5939         pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
5940 
5941         // Note that we invoke the following method only if we are about to unpack an application
5942         PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags
5943                 | SCAN_UPDATE_SIGNATURE, currentTime, user);
5944 
5945         /*
5946          * If the system app should be overridden by a previously installed
5947          * data, hide the system app now and let the /data/app scan pick it up
5948          * again.
5949          */
5950         if (shouldHideSystemApp) {
5951             synchronized (mPackages) {
5952                 mSettings.disableSystemPackageLPw(pkg.packageName);
5953             }
5954         }
5955 
5956         return scannedPkg;
5957     }
5958 
fixProcessName(String defProcessName, String processName, int uid)5959     private static String fixProcessName(String defProcessName,
5960             String processName, int uid) {
5961         if (processName == null) {
5962             return defProcessName;
5963         }
5964         return processName;
5965     }
5966 
verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)5967     private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
5968             throws PackageManagerException {
5969         if (pkgSetting.signatures.mSignatures != null) {
5970             // Already existing package. Make sure signatures match
5971             boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
5972                     == PackageManager.SIGNATURE_MATCH;
5973             if (!match) {
5974                 match = compareSignaturesCompat(pkgSetting.signatures, pkg)
5975                         == PackageManager.SIGNATURE_MATCH;
5976             }
5977             if (!match) {
5978                 match = compareSignaturesRecover(pkgSetting.signatures, pkg)
5979                         == PackageManager.SIGNATURE_MATCH;
5980             }
5981             if (!match) {
5982                 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
5983                         + pkg.packageName + " signatures do not match the "
5984                         + "previously installed version; ignoring!");
5985             }
5986         }
5987 
5988         // Check for shared user signatures
5989         if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
5990             // Already existing package. Make sure signatures match
5991             boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
5992                     pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
5993             if (!match) {
5994                 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
5995                         == PackageManager.SIGNATURE_MATCH;
5996             }
5997             if (!match) {
5998                 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
5999                         == PackageManager.SIGNATURE_MATCH;
6000             }
6001             if (!match) {
6002                 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
6003                         "Package " + pkg.packageName
6004                         + " has no signatures that match those in shared user "
6005                         + pkgSetting.sharedUser.name + "; ignoring!");
6006             }
6007         }
6008     }
6009 
6010     /**
6011      * Enforces that only the system UID or root's UID can call a method exposed
6012      * via Binder.
6013      *
6014      * @param message used as message if SecurityException is thrown
6015      * @throws SecurityException if the caller is not system or root
6016      */
enforceSystemOrRoot(String message)6017     private static final void enforceSystemOrRoot(String message) {
6018         final int uid = Binder.getCallingUid();
6019         if (uid != Process.SYSTEM_UID && uid != 0) {
6020             throw new SecurityException(message);
6021         }
6022     }
6023 
6024     @Override
performBootDexOpt()6025     public void performBootDexOpt() {
6026         enforceSystemOrRoot("Only the system can request dexopt be performed");
6027 
6028         // Before everything else, see whether we need to fstrim.
6029         try {
6030             IMountService ms = PackageHelper.getMountService();
6031             if (ms != null) {
6032                 final boolean isUpgrade = isUpgrade();
6033                 boolean doTrim = isUpgrade;
6034                 if (doTrim) {
6035                     Slog.w(TAG, "Running disk maintenance immediately due to system update");
6036                 } else {
6037                     final long interval = android.provider.Settings.Global.getLong(
6038                             mContext.getContentResolver(),
6039                             android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
6040                             DEFAULT_MANDATORY_FSTRIM_INTERVAL);
6041                     if (interval > 0) {
6042                         final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance();
6043                         if (timeSinceLast > interval) {
6044                             doTrim = true;
6045                             Slog.w(TAG, "No disk maintenance in " + timeSinceLast
6046                                     + "; running immediately");
6047                         }
6048                     }
6049                 }
6050                 if (doTrim) {
6051                     if (!isFirstBoot()) {
6052                         try {
6053                             ActivityManagerNative.getDefault().showBootMessage(
6054                                     mContext.getResources().getString(
6055                                             R.string.android_upgrading_fstrim), true);
6056                         } catch (RemoteException e) {
6057                         }
6058                     }
6059                     ms.runMaintenance();
6060                 }
6061             } else {
6062                 Slog.e(TAG, "Mount service unavailable!");
6063             }
6064         } catch (RemoteException e) {
6065             // Can't happen; MountService is local
6066         }
6067 
6068         final ArraySet<PackageParser.Package> pkgs;
6069         synchronized (mPackages) {
6070             pkgs = mPackageDexOptimizer.clearDeferredDexOptPackages();
6071         }
6072 
6073         if (pkgs != null) {
6074             // Sort apps by importance for dexopt ordering. Important apps are given more priority
6075             // in case the device runs out of space.
6076             ArrayList<PackageParser.Package> sortedPkgs = new ArrayList<PackageParser.Package>();
6077             // Give priority to core apps.
6078             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
6079                 PackageParser.Package pkg = it.next();
6080                 if (pkg.coreApp) {
6081                     if (DEBUG_DEXOPT) {
6082                         Log.i(TAG, "Adding core app " + sortedPkgs.size() + ": " + pkg.packageName);
6083                     }
6084                     sortedPkgs.add(pkg);
6085                     it.remove();
6086                 }
6087             }
6088             // Give priority to system apps that listen for pre boot complete.
6089             Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6090             ArraySet<String> pkgNames = getPackageNamesForIntent(intent);
6091             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
6092                 PackageParser.Package pkg = it.next();
6093                 if (pkgNames.contains(pkg.packageName)) {
6094                     if (DEBUG_DEXOPT) {
6095                         Log.i(TAG, "Adding pre boot system app " + sortedPkgs.size() + ": " + pkg.packageName);
6096                     }
6097                     sortedPkgs.add(pkg);
6098                     it.remove();
6099                 }
6100             }
6101             // Filter out packages that aren't recently used.
6102             filterRecentlyUsedApps(pkgs);
6103             // Add all remaining apps.
6104             for (PackageParser.Package pkg : pkgs) {
6105                 if (DEBUG_DEXOPT) {
6106                     Log.i(TAG, "Adding app " + sortedPkgs.size() + ": " + pkg.packageName);
6107                 }
6108                 sortedPkgs.add(pkg);
6109             }
6110 
6111             // If we want to be lazy, filter everything that wasn't recently used.
6112             if (mLazyDexOpt) {
6113                 filterRecentlyUsedApps(sortedPkgs);
6114             }
6115 
6116             int i = 0;
6117             int total = sortedPkgs.size();
6118             File dataDir = Environment.getDataDirectory();
6119             long lowThreshold = StorageManager.from(mContext).getStorageLowBytes(dataDir);
6120             if (lowThreshold == 0) {
6121                 throw new IllegalStateException("Invalid low memory threshold");
6122             }
6123             for (PackageParser.Package pkg : sortedPkgs) {
6124                 long usableSpace = dataDir.getUsableSpace();
6125                 if (usableSpace < lowThreshold) {
6126                     Log.w(TAG, "Not running dexopt on remaining apps due to low memory: " + usableSpace);
6127                     break;
6128                 }
6129                 performBootDexOpt(pkg, ++i, total);
6130             }
6131         }
6132     }
6133 
filterRecentlyUsedApps(Collection<PackageParser.Package> pkgs)6134     private void filterRecentlyUsedApps(Collection<PackageParser.Package> pkgs) {
6135         // Filter out packages that aren't recently used.
6136         //
6137         // The exception is first boot of a non-eng device (aka !mLazyDexOpt), which
6138         // should do a full dexopt.
6139         if (mLazyDexOpt || (!isFirstBoot() && mPackageUsage.isHistoricalPackageUsageAvailable())) {
6140             int total = pkgs.size();
6141             int skipped = 0;
6142             long now = System.currentTimeMillis();
6143             for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) {
6144                 PackageParser.Package pkg = i.next();
6145                 long then = pkg.mLastPackageUsageTimeInMills;
6146                 if (then + mDexOptLRUThresholdInMills < now) {
6147                     if (DEBUG_DEXOPT) {
6148                         Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " +
6149                               ((then == 0) ? "never" : new Date(then)));
6150                     }
6151                     i.remove();
6152                     skipped++;
6153                 }
6154             }
6155             if (DEBUG_DEXOPT) {
6156                 Log.i(TAG, "Skipped optimizing " + skipped + " of " + total);
6157             }
6158         }
6159     }
6160 
getPackageNamesForIntent(Intent intent)6161     private ArraySet<String> getPackageNamesForIntent(Intent intent) {
6162         List<ResolveInfo> ris = null;
6163         try {
6164             ris = AppGlobals.getPackageManager().queryIntentReceivers(
6165                     intent, null, 0, UserHandle.USER_OWNER);
6166         } catch (RemoteException e) {
6167         }
6168         ArraySet<String> pkgNames = new ArraySet<String>();
6169         if (ris != null) {
6170             for (ResolveInfo ri : ris) {
6171                 pkgNames.add(ri.activityInfo.packageName);
6172             }
6173         }
6174         return pkgNames;
6175     }
6176 
performBootDexOpt(PackageParser.Package pkg, int curr, int total)6177     private void performBootDexOpt(PackageParser.Package pkg, int curr, int total) {
6178         if (DEBUG_DEXOPT) {
6179             Log.i(TAG, "Optimizing app " + curr + " of " + total + ": " + pkg.packageName);
6180         }
6181         if (!isFirstBoot()) {
6182             try {
6183                 ActivityManagerNative.getDefault().showBootMessage(
6184                         mContext.getResources().getString(R.string.android_upgrading_apk,
6185                                 curr, total), true);
6186             } catch (RemoteException e) {
6187             }
6188         }
6189         PackageParser.Package p = pkg;
6190         synchronized (mInstallLock) {
6191             mPackageDexOptimizer.performDexOpt(p, null /* instruction sets */,
6192                     false /* force dex */, false /* defer */, true /* include dependencies */,
6193                     false /* boot complete */);
6194         }
6195     }
6196 
6197     @Override
performDexOptIfNeeded(String packageName, String instructionSet)6198     public boolean performDexOptIfNeeded(String packageName, String instructionSet) {
6199         return performDexOpt(packageName, instructionSet, false);
6200     }
6201 
performDexOpt(String packageName, String instructionSet, boolean backgroundDexopt)6202     public boolean performDexOpt(String packageName, String instructionSet, boolean backgroundDexopt) {
6203         boolean dexopt = mLazyDexOpt || backgroundDexopt;
6204         boolean updateUsage = !backgroundDexopt;  // Don't update usage if this is just a backgroundDexopt
6205         if (!dexopt && !updateUsage) {
6206             // We aren't going to dexopt or update usage, so bail early.
6207             return false;
6208         }
6209         PackageParser.Package p;
6210         final String targetInstructionSet;
6211         synchronized (mPackages) {
6212             p = mPackages.get(packageName);
6213             if (p == null) {
6214                 return false;
6215             }
6216             if (updateUsage) {
6217                 p.mLastPackageUsageTimeInMills = System.currentTimeMillis();
6218             }
6219             mPackageUsage.write(false);
6220             if (!dexopt) {
6221                 // We aren't going to dexopt, so bail early.
6222                 return false;
6223             }
6224 
6225             targetInstructionSet = instructionSet != null ? instructionSet :
6226                     getPrimaryInstructionSet(p.applicationInfo);
6227             if (p.mDexOptPerformed.contains(targetInstructionSet)) {
6228                 return false;
6229             }
6230         }
6231         long callingId = Binder.clearCallingIdentity();
6232         try {
6233             synchronized (mInstallLock) {
6234                 final String[] instructionSets = new String[] { targetInstructionSet };
6235                 int result = mPackageDexOptimizer.performDexOpt(p, instructionSets,
6236                         false /* forceDex */, false /* defer */, true /* inclDependencies */,
6237                         true /* boot complete */);
6238                 return result == PackageDexOptimizer.DEX_OPT_PERFORMED;
6239             }
6240         } finally {
6241             Binder.restoreCallingIdentity(callingId);
6242         }
6243     }
6244 
getPackagesThatNeedDexOpt()6245     public ArraySet<String> getPackagesThatNeedDexOpt() {
6246         ArraySet<String> pkgs = null;
6247         synchronized (mPackages) {
6248             for (PackageParser.Package p : mPackages.values()) {
6249                 if (DEBUG_DEXOPT) {
6250                     Log.i(TAG, p.packageName + " mDexOptPerformed=" + p.mDexOptPerformed.toArray());
6251                 }
6252                 if (!p.mDexOptPerformed.isEmpty()) {
6253                     continue;
6254                 }
6255                 if (pkgs == null) {
6256                     pkgs = new ArraySet<String>();
6257                 }
6258                 pkgs.add(p.packageName);
6259             }
6260         }
6261         return pkgs;
6262     }
6263 
shutdown()6264     public void shutdown() {
6265         mPackageUsage.write(true);
6266     }
6267 
6268     @Override
forceDexOpt(String packageName)6269     public void forceDexOpt(String packageName) {
6270         enforceSystemOrRoot("forceDexOpt");
6271 
6272         PackageParser.Package pkg;
6273         synchronized (mPackages) {
6274             pkg = mPackages.get(packageName);
6275             if (pkg == null) {
6276                 throw new IllegalArgumentException("Missing package: " + packageName);
6277             }
6278         }
6279 
6280         synchronized (mInstallLock) {
6281             final String[] instructionSets = new String[] {
6282                     getPrimaryInstructionSet(pkg.applicationInfo) };
6283             final int res = mPackageDexOptimizer.performDexOpt(pkg, instructionSets,
6284                     true /*forceDex*/, false /* defer */, true /* inclDependencies */,
6285                     true /* boot complete */);
6286             if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
6287                 throw new IllegalStateException("Failed to dexopt: " + res);
6288             }
6289         }
6290     }
6291 
verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg)6292     private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
6293         if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6294             Slog.w(TAG, "Unable to update from " + oldPkg.name
6295                     + " to " + newPkg.packageName
6296                     + ": old package not in system partition");
6297             return false;
6298         } else if (mPackages.get(oldPkg.name) != null) {
6299             Slog.w(TAG, "Unable to update from " + oldPkg.name
6300                     + " to " + newPkg.packageName
6301                     + ": old package still exists");
6302             return false;
6303         }
6304         return true;
6305     }
6306 
createDataDirsLI(String volumeUuid, String packageName, int uid, String seinfo)6307     private int createDataDirsLI(String volumeUuid, String packageName, int uid, String seinfo) {
6308         int[] users = sUserManager.getUserIds();
6309         int res = mInstaller.install(volumeUuid, packageName, uid, uid, seinfo);
6310         if (res < 0) {
6311             return res;
6312         }
6313         for (int user : users) {
6314             if (user != 0) {
6315                 res = mInstaller.createUserData(volumeUuid, packageName,
6316                         UserHandle.getUid(user, uid), user, seinfo);
6317                 if (res < 0) {
6318                     return res;
6319                 }
6320             }
6321         }
6322         return res;
6323     }
6324 
removeDataDirsLI(String volumeUuid, String packageName)6325     private int removeDataDirsLI(String volumeUuid, String packageName) {
6326         int[] users = sUserManager.getUserIds();
6327         int res = 0;
6328         for (int user : users) {
6329             int resInner = mInstaller.remove(volumeUuid, packageName, user);
6330             if (resInner < 0) {
6331                 res = resInner;
6332             }
6333         }
6334 
6335         return res;
6336     }
6337 
deleteCodeCacheDirsLI(String volumeUuid, String packageName)6338     private int deleteCodeCacheDirsLI(String volumeUuid, String packageName) {
6339         int[] users = sUserManager.getUserIds();
6340         int res = 0;
6341         for (int user : users) {
6342             int resInner = mInstaller.deleteCodeCacheFiles(volumeUuid, packageName, user);
6343             if (resInner < 0) {
6344                 res = resInner;
6345             }
6346         }
6347         return res;
6348     }
6349 
addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, PackageParser.Package changingLib)6350     private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
6351             PackageParser.Package changingLib) {
6352         if (file.path != null) {
6353             usesLibraryFiles.add(file.path);
6354             return;
6355         }
6356         PackageParser.Package p = mPackages.get(file.apk);
6357         if (changingLib != null && changingLib.packageName.equals(file.apk)) {
6358             // If we are doing this while in the middle of updating a library apk,
6359             // then we need to make sure to use that new apk for determining the
6360             // dependencies here.  (We haven't yet finished committing the new apk
6361             // to the package manager state.)
6362             if (p == null || p.packageName.equals(changingLib.packageName)) {
6363                 p = changingLib;
6364             }
6365         }
6366         if (p != null) {
6367             usesLibraryFiles.addAll(p.getAllCodePaths());
6368         }
6369     }
6370 
updateSharedLibrariesLPw(PackageParser.Package pkg, PackageParser.Package changingLib)6371     private void updateSharedLibrariesLPw(PackageParser.Package pkg,
6372             PackageParser.Package changingLib) throws PackageManagerException {
6373         if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
6374             final ArraySet<String> usesLibraryFiles = new ArraySet<>();
6375             int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
6376             for (int i=0; i<N; i++) {
6377                 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i));
6378                 if (file == null) {
6379                     throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
6380                             "Package " + pkg.packageName + " requires unavailable shared library "
6381                             + pkg.usesLibraries.get(i) + "; failing!");
6382                 }
6383                 addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
6384             }
6385             N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
6386             for (int i=0; i<N; i++) {
6387                 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
6388                 if (file == null) {
6389                     Slog.w(TAG, "Package " + pkg.packageName
6390                             + " desires unavailable shared library "
6391                             + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
6392                 } else {
6393                     addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
6394                 }
6395             }
6396             N = usesLibraryFiles.size();
6397             if (N > 0) {
6398                 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]);
6399             } else {
6400                 pkg.usesLibraryFiles = null;
6401             }
6402         }
6403     }
6404 
hasString(List<String> list, List<String> which)6405     private static boolean hasString(List<String> list, List<String> which) {
6406         if (list == null) {
6407             return false;
6408         }
6409         for (int i=list.size()-1; i>=0; i--) {
6410             for (int j=which.size()-1; j>=0; j--) {
6411                 if (which.get(j).equals(list.get(i))) {
6412                     return true;
6413                 }
6414             }
6415         }
6416         return false;
6417     }
6418 
updateAllSharedLibrariesLPw()6419     private void updateAllSharedLibrariesLPw() {
6420         for (PackageParser.Package pkg : mPackages.values()) {
6421             try {
6422                 updateSharedLibrariesLPw(pkg, null);
6423             } catch (PackageManagerException e) {
6424                 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
6425             }
6426         }
6427     }
6428 
updateAllSharedLibrariesLPw( PackageParser.Package changingPkg)6429     private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
6430             PackageParser.Package changingPkg) {
6431         ArrayList<PackageParser.Package> res = null;
6432         for (PackageParser.Package pkg : mPackages.values()) {
6433             if (hasString(pkg.usesLibraries, changingPkg.libraryNames)
6434                     || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) {
6435                 if (res == null) {
6436                     res = new ArrayList<PackageParser.Package>();
6437                 }
6438                 res.add(pkg);
6439                 try {
6440                     updateSharedLibrariesLPw(pkg, changingPkg);
6441                 } catch (PackageManagerException e) {
6442                     Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
6443                 }
6444             }
6445         }
6446         return res;
6447     }
6448 
6449     /**
6450      * Derive the value of the {@code cpuAbiOverride} based on the provided
6451      * value and an optional stored value from the package settings.
6452      */
deriveAbiOverride(String abiOverride, PackageSetting settings)6453     private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
6454         String cpuAbiOverride = null;
6455 
6456         if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
6457             cpuAbiOverride = null;
6458         } else if (abiOverride != null) {
6459             cpuAbiOverride = abiOverride;
6460         } else if (settings != null) {
6461             cpuAbiOverride = settings.cpuAbiOverrideString;
6462         }
6463 
6464         return cpuAbiOverride;
6465     }
6466 
scanPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, long currentTime, UserHandle user)6467     private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags,
6468             int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
6469         boolean success = false;
6470         try {
6471             final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags,
6472                     currentTime, user);
6473             success = true;
6474             return res;
6475         } finally {
6476             if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
6477                 removeDataDirsLI(pkg.volumeUuid, pkg.packageName);
6478             }
6479         }
6480     }
6481 
scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags, int scanFlags, long currentTime, UserHandle user)6482     private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags,
6483             int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
6484         final File scanFile = new File(pkg.codePath);
6485         if (pkg.applicationInfo.getCodePath() == null ||
6486                 pkg.applicationInfo.getResourcePath() == null) {
6487             // Bail out. The resource and code paths haven't been set.
6488             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
6489                     "Code and resource paths haven't been set correctly");
6490         }
6491 
6492         if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
6493             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
6494         } else {
6495             // Only allow system apps to be flagged as core apps.
6496             pkg.coreApp = false;
6497         }
6498 
6499         if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
6500             pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
6501         }
6502 
6503         if (mCustomResolverComponentName != null &&
6504                 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
6505             setUpCustomResolverActivity(pkg);
6506         }
6507 
6508         if (pkg.packageName.equals("android")) {
6509             synchronized (mPackages) {
6510                 if (mAndroidApplication != null) {
6511                     Slog.w(TAG, "*************************************************");
6512                     Slog.w(TAG, "Core android package being redefined.  Skipping.");
6513                     Slog.w(TAG, " file=" + scanFile);
6514                     Slog.w(TAG, "*************************************************");
6515                     throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
6516                             "Core android package being redefined.  Skipping.");
6517                 }
6518 
6519                 // Set up information for our fall-back user intent resolution activity.
6520                 mPlatformPackage = pkg;
6521                 pkg.mVersionCode = mSdkVersion;
6522                 mAndroidApplication = pkg.applicationInfo;
6523 
6524                 if (!mResolverReplaced) {
6525                     mResolveActivity.applicationInfo = mAndroidApplication;
6526                     mResolveActivity.name = ResolverActivity.class.getName();
6527                     mResolveActivity.packageName = mAndroidApplication.packageName;
6528                     mResolveActivity.processName = "system:ui";
6529                     mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
6530                     mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
6531                     mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
6532                     mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert;
6533                     mResolveActivity.exported = true;
6534                     mResolveActivity.enabled = true;
6535                     mResolveInfo.activityInfo = mResolveActivity;
6536                     mResolveInfo.priority = 0;
6537                     mResolveInfo.preferredOrder = 0;
6538                     mResolveInfo.match = 0;
6539                     mResolveComponentName = new ComponentName(
6540                             mAndroidApplication.packageName, mResolveActivity.name);
6541                 }
6542             }
6543         }
6544 
6545         if (DEBUG_PACKAGE_SCANNING) {
6546             if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
6547                 Log.d(TAG, "Scanning package " + pkg.packageName);
6548         }
6549 
6550         if (mPackages.containsKey(pkg.packageName)
6551                 || mSharedLibraries.containsKey(pkg.packageName)) {
6552             throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
6553                     "Application package " + pkg.packageName
6554                     + " already installed.  Skipping duplicate.");
6555         }
6556 
6557         // If we're only installing presumed-existing packages, require that the
6558         // scanned APK is both already known and at the path previously established
6559         // for it.  Previously unknown packages we pick up normally, but if we have an
6560         // a priori expectation about this package's install presence, enforce it.
6561         // With a singular exception for new system packages. When an OTA contains
6562         // a new system package, we allow the codepath to change from a system location
6563         // to the user-installed location. If we don't allow this change, any newer,
6564         // user-installed version of the application will be ignored.
6565         if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
6566             if (mExpectingBetter.containsKey(pkg.packageName)) {
6567                 logCriticalInfo(Log.WARN,
6568                         "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
6569             } else {
6570                 PackageSetting known = mSettings.peekPackageLPr(pkg.packageName);
6571                 if (known != null) {
6572                     if (DEBUG_PACKAGE_SCANNING) {
6573                         Log.d(TAG, "Examining " + pkg.codePath
6574                                 + " and requiring known paths " + known.codePathString
6575                                 + " & " + known.resourcePathString);
6576                     }
6577                     if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
6578                             || !pkg.applicationInfo.getResourcePath().equals(known.resourcePathString)) {
6579                         throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
6580                                 "Application package " + pkg.packageName
6581                                 + " found at " + pkg.applicationInfo.getCodePath()
6582                                 + " but expected at " + known.codePathString + "; ignoring.");
6583                     }
6584                 }
6585             }
6586         }
6587 
6588         // Initialize package source and resource directories
6589         File destCodeFile = new File(pkg.applicationInfo.getCodePath());
6590         File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
6591 
6592         SharedUserSetting suid = null;
6593         PackageSetting pkgSetting = null;
6594 
6595         if (!isSystemApp(pkg)) {
6596             // Only system apps can use these features.
6597             pkg.mOriginalPackages = null;
6598             pkg.mRealPackage = null;
6599             pkg.mAdoptPermissions = null;
6600         }
6601 
6602         // writer
6603         synchronized (mPackages) {
6604             if (pkg.mSharedUserId != null) {
6605                 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true);
6606                 if (suid == null) {
6607                     throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
6608                             "Creating application package " + pkg.packageName
6609                             + " for shared user failed");
6610                 }
6611                 if (DEBUG_PACKAGE_SCANNING) {
6612                     if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
6613                         Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
6614                                 + "): packages=" + suid.packages);
6615                 }
6616             }
6617 
6618             // Check if we are renaming from an original package name.
6619             PackageSetting origPackage = null;
6620             String realName = null;
6621             if (pkg.mOriginalPackages != null) {
6622                 // This package may need to be renamed to a previously
6623                 // installed name.  Let's check on that...
6624                 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
6625                 if (pkg.mOriginalPackages.contains(renamed)) {
6626                     // This package had originally been installed as the
6627                     // original name, and we have already taken care of
6628                     // transitioning to the new one.  Just update the new
6629                     // one to continue using the old name.
6630                     realName = pkg.mRealPackage;
6631                     if (!pkg.packageName.equals(renamed)) {
6632                         // Callers into this function may have already taken
6633                         // care of renaming the package; only do it here if
6634                         // it is not already done.
6635                         pkg.setPackageName(renamed);
6636                     }
6637 
6638                 } else {
6639                     for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
6640                         if ((origPackage = mSettings.peekPackageLPr(
6641                                 pkg.mOriginalPackages.get(i))) != null) {
6642                             // We do have the package already installed under its
6643                             // original name...  should we use it?
6644                             if (!verifyPackageUpdateLPr(origPackage, pkg)) {
6645                                 // New package is not compatible with original.
6646                                 origPackage = null;
6647                                 continue;
6648                             } else if (origPackage.sharedUser != null) {
6649                                 // Make sure uid is compatible between packages.
6650                                 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
6651                                     Slog.w(TAG, "Unable to migrate data from " + origPackage.name
6652                                             + " to " + pkg.packageName + ": old uid "
6653                                             + origPackage.sharedUser.name
6654                                             + " differs from " + pkg.mSharedUserId);
6655                                     origPackage = null;
6656                                     continue;
6657                                 }
6658                             } else {
6659                                 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
6660                                         + pkg.packageName + " to old name " + origPackage.name);
6661                             }
6662                             break;
6663                         }
6664                     }
6665                 }
6666             }
6667 
6668             if (mTransferedPackages.contains(pkg.packageName)) {
6669                 Slog.w(TAG, "Package " + pkg.packageName
6670                         + " was transferred to another, but its .apk remains");
6671             }
6672 
6673             // Just create the setting, don't add it yet. For already existing packages
6674             // the PkgSetting exists already and doesn't have to be created.
6675             pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
6676                     destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
6677                     pkg.applicationInfo.primaryCpuAbi,
6678                     pkg.applicationInfo.secondaryCpuAbi,
6679                     pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
6680                     user, false);
6681             if (pkgSetting == null) {
6682                 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
6683                         "Creating application package " + pkg.packageName + " failed");
6684             }
6685 
6686             if (pkgSetting.origPackage != null) {
6687                 // If we are first transitioning from an original package,
6688                 // fix up the new package's name now.  We need to do this after
6689                 // looking up the package under its new name, so getPackageLP
6690                 // can take care of fiddling things correctly.
6691                 pkg.setPackageName(origPackage.name);
6692 
6693                 // File a report about this.
6694                 String msg = "New package " + pkgSetting.realName
6695                         + " renamed to replace old package " + pkgSetting.name;
6696                 reportSettingsProblem(Log.WARN, msg);
6697 
6698                 // Make a note of it.
6699                 mTransferedPackages.add(origPackage.name);
6700 
6701                 // No longer need to retain this.
6702                 pkgSetting.origPackage = null;
6703             }
6704 
6705             if (realName != null) {
6706                 // Make a note of it.
6707                 mTransferedPackages.add(pkg.packageName);
6708             }
6709 
6710             if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
6711                 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
6712             }
6713 
6714             if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
6715                 // Check all shared libraries and map to their actual file path.
6716                 // We only do this here for apps not on a system dir, because those
6717                 // are the only ones that can fail an install due to this.  We
6718                 // will take care of the system apps by updating all of their
6719                 // library paths after the scan is done.
6720                 updateSharedLibrariesLPw(pkg, null);
6721             }
6722 
6723             if (mFoundPolicyFile) {
6724                 SELinuxMMAC.assignSeinfoValue(pkg);
6725             }
6726 
6727             pkg.applicationInfo.uid = pkgSetting.appId;
6728             pkg.mExtras = pkgSetting;
6729             if (shouldCheckUpgradeKeySetLP(pkgSetting, scanFlags)) {
6730                 if (checkUpgradeKeySetLP(pkgSetting, pkg)) {
6731                     // We just determined the app is signed correctly, so bring
6732                     // over the latest parsed certs.
6733                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
6734                 } else {
6735                     if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
6736                         throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
6737                                 "Package " + pkg.packageName + " upgrade keys do not match the "
6738                                 + "previously installed version");
6739                     } else {
6740                         pkgSetting.signatures.mSignatures = pkg.mSignatures;
6741                         String msg = "System package " + pkg.packageName
6742                             + " signature changed; retaining data.";
6743                         reportSettingsProblem(Log.WARN, msg);
6744                     }
6745                 }
6746             } else {
6747                 try {
6748                     verifySignaturesLP(pkgSetting, pkg);
6749                     // We just determined the app is signed correctly, so bring
6750                     // over the latest parsed certs.
6751                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
6752                 } catch (PackageManagerException e) {
6753                     if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
6754                         throw e;
6755                     }
6756                     // The signature has changed, but this package is in the system
6757                     // image...  let's recover!
6758                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
6759                     // However...  if this package is part of a shared user, but it
6760                     // doesn't match the signature of the shared user, let's fail.
6761                     // What this means is that you can't change the signatures
6762                     // associated with an overall shared user, which doesn't seem all
6763                     // that unreasonable.
6764                     if (pkgSetting.sharedUser != null) {
6765                         if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
6766                                               pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
6767                             throw new PackageManagerException(
6768                                     INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
6769                                             "Signature mismatch for shared user : "
6770                                             + pkgSetting.sharedUser);
6771                         }
6772                     }
6773                     // File a report about this.
6774                     String msg = "System package " + pkg.packageName
6775                         + " signature changed; retaining data.";
6776                     reportSettingsProblem(Log.WARN, msg);
6777                 }
6778             }
6779             // Verify that this new package doesn't have any content providers
6780             // that conflict with existing packages.  Only do this if the
6781             // package isn't already installed, since we don't want to break
6782             // things that are installed.
6783             if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
6784                 final int N = pkg.providers.size();
6785                 int i;
6786                 for (i=0; i<N; i++) {
6787                     PackageParser.Provider p = pkg.providers.get(i);
6788                     if (p.info.authority != null) {
6789                         String names[] = p.info.authority.split(";");
6790                         for (int j = 0; j < names.length; j++) {
6791                             if (mProvidersByAuthority.containsKey(names[j])) {
6792                                 PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
6793                                 final String otherPackageName =
6794                                         ((other != null && other.getComponentName() != null) ?
6795                                                 other.getComponentName().getPackageName() : "?");
6796                                 throw new PackageManagerException(
6797                                         INSTALL_FAILED_CONFLICTING_PROVIDER,
6798                                                 "Can't install because provider name " + names[j]
6799                                                 + " (in package " + pkg.applicationInfo.packageName
6800                                                 + ") is already used by " + otherPackageName);
6801                             }
6802                         }
6803                     }
6804                 }
6805             }
6806 
6807             if (pkg.mAdoptPermissions != null) {
6808                 // This package wants to adopt ownership of permissions from
6809                 // another package.
6810                 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
6811                     final String origName = pkg.mAdoptPermissions.get(i);
6812                     final PackageSetting orig = mSettings.peekPackageLPr(origName);
6813                     if (orig != null) {
6814                         if (verifyPackageUpdateLPr(orig, pkg)) {
6815                             Slog.i(TAG, "Adopting permissions from " + origName + " to "
6816                                     + pkg.packageName);
6817                             mSettings.transferPermissionsLPw(origName, pkg.packageName);
6818                         }
6819                     }
6820                 }
6821             }
6822         }
6823 
6824         final String pkgName = pkg.packageName;
6825 
6826         final long scanFileTime = scanFile.lastModified();
6827         final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0;
6828         pkg.applicationInfo.processName = fixProcessName(
6829                 pkg.applicationInfo.packageName,
6830                 pkg.applicationInfo.processName,
6831                 pkg.applicationInfo.uid);
6832 
6833         File dataPath;
6834         if (mPlatformPackage == pkg) {
6835             // The system package is special.
6836             dataPath = new File(Environment.getDataDirectory(), "system");
6837 
6838             pkg.applicationInfo.dataDir = dataPath.getPath();
6839 
6840         } else {
6841             // This is a normal package, need to make its data directory.
6842             dataPath = Environment.getDataUserPackageDirectory(pkg.volumeUuid,
6843                     UserHandle.USER_OWNER, pkg.packageName);
6844 
6845             boolean uidError = false;
6846             if (dataPath.exists()) {
6847                 int currentUid = 0;
6848                 try {
6849                     StructStat stat = Os.stat(dataPath.getPath());
6850                     currentUid = stat.st_uid;
6851                 } catch (ErrnoException e) {
6852                     Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e);
6853                 }
6854 
6855                 // If we have mismatched owners for the data path, we have a problem.
6856                 if (currentUid != pkg.applicationInfo.uid) {
6857                     boolean recovered = false;
6858                     if (currentUid == 0) {
6859                         // The directory somehow became owned by root.  Wow.
6860                         // This is probably because the system was stopped while
6861                         // installd was in the middle of messing with its libs
6862                         // directory.  Ask installd to fix that.
6863                         int ret = mInstaller.fixUid(pkg.volumeUuid, pkgName,
6864                                 pkg.applicationInfo.uid, pkg.applicationInfo.uid);
6865                         if (ret >= 0) {
6866                             recovered = true;
6867                             String msg = "Package " + pkg.packageName
6868                                     + " unexpectedly changed to uid 0; recovered to " +
6869                                     + pkg.applicationInfo.uid;
6870                             reportSettingsProblem(Log.WARN, msg);
6871                         }
6872                     }
6873                     if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
6874                             || (scanFlags&SCAN_BOOTING) != 0)) {
6875                         // If this is a system app, we can at least delete its
6876                         // current data so the application will still work.
6877                         int ret = removeDataDirsLI(pkg.volumeUuid, pkgName);
6878                         if (ret >= 0) {
6879                             // TODO: Kill the processes first
6880                             // Old data gone!
6881                             String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
6882                                     ? "System package " : "Third party package ";
6883                             String msg = prefix + pkg.packageName
6884                                     + " has changed from uid: "
6885                                     + currentUid + " to "
6886                                     + pkg.applicationInfo.uid + "; old data erased";
6887                             reportSettingsProblem(Log.WARN, msg);
6888                             recovered = true;
6889 
6890                             // And now re-install the app.
6891                             ret = createDataDirsLI(pkg.volumeUuid, pkgName, pkg.applicationInfo.uid,
6892                                     pkg.applicationInfo.seinfo);
6893                             if (ret == -1) {
6894                                 // Ack should not happen!
6895                                 msg = prefix + pkg.packageName
6896                                         + " could not have data directory re-created after delete.";
6897                                 reportSettingsProblem(Log.WARN, msg);
6898                                 throw new PackageManagerException(
6899                                         INSTALL_FAILED_INSUFFICIENT_STORAGE, msg);
6900                             }
6901                         }
6902                         if (!recovered) {
6903                             mHasSystemUidErrors = true;
6904                         }
6905                     } else if (!recovered) {
6906                         // If we allow this install to proceed, we will be broken.
6907                         // Abort, abort!
6908                         throw new PackageManagerException(INSTALL_FAILED_UID_CHANGED,
6909                                 "scanPackageLI");
6910                     }
6911                     if (!recovered) {
6912                         pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
6913                             + pkg.applicationInfo.uid + "/fs_"
6914                             + currentUid;
6915                         pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
6916                         pkg.applicationInfo.nativeLibraryRootDir = pkg.applicationInfo.dataDir;
6917                         String msg = "Package " + pkg.packageName
6918                                 + " has mismatched uid: "
6919                                 + currentUid + " on disk, "
6920                                 + pkg.applicationInfo.uid + " in settings";
6921                         // writer
6922                         synchronized (mPackages) {
6923                             mSettings.mReadMessages.append(msg);
6924                             mSettings.mReadMessages.append('\n');
6925                             uidError = true;
6926                             if (!pkgSetting.uidError) {
6927                                 reportSettingsProblem(Log.ERROR, msg);
6928                             }
6929                         }
6930                     }
6931                 }
6932                 pkg.applicationInfo.dataDir = dataPath.getPath();
6933                 if (mShouldRestoreconData) {
6934                     Slog.i(TAG, "SELinux relabeling of " + pkg.packageName + " issued.");
6935                     mInstaller.restoreconData(pkg.volumeUuid, pkg.packageName,
6936                             pkg.applicationInfo.seinfo, pkg.applicationInfo.uid);
6937                 }
6938             } else {
6939                 if (DEBUG_PACKAGE_SCANNING) {
6940                     if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
6941                         Log.v(TAG, "Want this data dir: " + dataPath);
6942                 }
6943                 //invoke installer to do the actual installation
6944                 int ret = createDataDirsLI(pkg.volumeUuid, pkgName, pkg.applicationInfo.uid,
6945                         pkg.applicationInfo.seinfo);
6946                 if (ret < 0) {
6947                     // Error from installer
6948                     throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
6949                             "Unable to create data dirs [errorCode=" + ret + "]");
6950                 }
6951 
6952                 if (dataPath.exists()) {
6953                     pkg.applicationInfo.dataDir = dataPath.getPath();
6954                 } else {
6955                     Slog.w(TAG, "Unable to create data directory: " + dataPath);
6956                     pkg.applicationInfo.dataDir = null;
6957                 }
6958             }
6959 
6960             pkgSetting.uidError = uidError;
6961         }
6962 
6963         final String path = scanFile.getPath();
6964         final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
6965 
6966         if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
6967             derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */);
6968 
6969             // Some system apps still use directory structure for native libraries
6970             // in which case we might end up not detecting abi solely based on apk
6971             // structure. Try to detect abi based on directory structure.
6972             if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
6973                     pkg.applicationInfo.primaryCpuAbi == null) {
6974                 setBundledAppAbisAndRoots(pkg, pkgSetting);
6975                 setNativeLibraryPaths(pkg);
6976             }
6977 
6978         } else {
6979             if ((scanFlags & SCAN_MOVE) != 0) {
6980                 // We haven't run dex-opt for this move (since we've moved the compiled output too)
6981                 // but we already have this packages package info in the PackageSetting. We just
6982                 // use that and derive the native library path based on the new codepath.
6983                 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
6984                 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
6985             }
6986 
6987             // Set native library paths again. For moves, the path will be updated based on the
6988             // ABIs we've determined above. For non-moves, the path will be updated based on the
6989             // ABIs we determined during compilation, but the path will depend on the final
6990             // package path (after the rename away from the stage path).
6991             setNativeLibraryPaths(pkg);
6992         }
6993 
6994         if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path);
6995         final int[] userIds = sUserManager.getUserIds();
6996         synchronized (mInstallLock) {
6997             // Make sure all user data directories are ready to roll; we're okay
6998             // if they already exist
6999             if (!TextUtils.isEmpty(pkg.volumeUuid)) {
7000                 for (int userId : userIds) {
7001                     if (userId != 0) {
7002                         mInstaller.createUserData(pkg.volumeUuid, pkg.packageName,
7003                                 UserHandle.getUid(userId, pkg.applicationInfo.uid), userId,
7004                                 pkg.applicationInfo.seinfo);
7005                     }
7006                 }
7007             }
7008 
7009             // Create a native library symlink only if we have native libraries
7010             // and if the native libraries are 32 bit libraries. We do not provide
7011             // this symlink for 64 bit libraries.
7012             if (pkg.applicationInfo.primaryCpuAbi != null &&
7013                     !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
7014                 final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
7015                 for (int userId : userIds) {
7016                     if (mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName,
7017                             nativeLibPath, userId) < 0) {
7018                         throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
7019                                 "Failed linking native library dir (user=" + userId + ")");
7020                     }
7021                 }
7022             }
7023         }
7024 
7025         // This is a special case for the "system" package, where the ABI is
7026         // dictated by the zygote configuration (and init.rc). We should keep track
7027         // of this ABI so that we can deal with "normal" applications that run under
7028         // the same UID correctly.
7029         if (mPlatformPackage == pkg) {
7030             pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
7031                     Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
7032         }
7033 
7034         // If there's a mismatch between the abi-override in the package setting
7035         // and the abiOverride specified for the install. Warn about this because we
7036         // would've already compiled the app without taking the package setting into
7037         // account.
7038         if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
7039             if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
7040                 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
7041                         " for package: " + pkg.packageName);
7042             }
7043         }
7044 
7045         pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
7046         pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
7047         pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
7048 
7049         // Copy the derived override back to the parsed package, so that we can
7050         // update the package settings accordingly.
7051         pkg.cpuAbiOverride = cpuAbiOverride;
7052 
7053         if (DEBUG_ABI_SELECTION) {
7054             Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
7055                     + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
7056                     + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
7057         }
7058 
7059         // Push the derived path down into PackageSettings so we know what to
7060         // clean up at uninstall time.
7061         pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
7062 
7063         if (DEBUG_ABI_SELECTION) {
7064             Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
7065                     " primary=" + pkg.applicationInfo.primaryCpuAbi +
7066                     " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
7067         }
7068 
7069         if ((scanFlags&SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
7070             // We don't do this here during boot because we can do it all
7071             // at once after scanning all existing packages.
7072             //
7073             // We also do this *before* we perform dexopt on this package, so that
7074             // we can avoid redundant dexopts, and also to make sure we've got the
7075             // code and package path correct.
7076             adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages,
7077                     pkg, forceDex, (scanFlags & SCAN_DEFER_DEX) != 0, true /* boot complete */);
7078         }
7079 
7080         if ((scanFlags & SCAN_NO_DEX) == 0) {
7081             int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instruction sets */,
7082                     forceDex, (scanFlags & SCAN_DEFER_DEX) != 0, false /* inclDependencies */,
7083                     (scanFlags & SCAN_BOOTING) == 0);
7084             if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
7085                 throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI");
7086             }
7087         }
7088         if (mFactoryTest && pkg.requestedPermissions.contains(
7089                 android.Manifest.permission.FACTORY_TEST)) {
7090             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
7091         }
7092 
7093         ArrayList<PackageParser.Package> clientLibPkgs = null;
7094 
7095         // writer
7096         synchronized (mPackages) {
7097             if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7098                 // Only system apps can add new shared libraries.
7099                 if (pkg.libraryNames != null) {
7100                     for (int i=0; i<pkg.libraryNames.size(); i++) {
7101                         String name = pkg.libraryNames.get(i);
7102                         boolean allowed = false;
7103                         if (pkg.isUpdatedSystemApp()) {
7104                             // New library entries can only be added through the
7105                             // system image.  This is important to get rid of a lot
7106                             // of nasty edge cases: for example if we allowed a non-
7107                             // system update of the app to add a library, then uninstalling
7108                             // the update would make the library go away, and assumptions
7109                             // we made such as through app install filtering would now
7110                             // have allowed apps on the device which aren't compatible
7111                             // with it.  Better to just have the restriction here, be
7112                             // conservative, and create many fewer cases that can negatively
7113                             // impact the user experience.
7114                             final PackageSetting sysPs = mSettings
7115                                     .getDisabledSystemPkgLPr(pkg.packageName);
7116                             if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
7117                                 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) {
7118                                     if (name.equals(sysPs.pkg.libraryNames.get(j))) {
7119                                         allowed = true;
7120                                         allowed = true;
7121                                         break;
7122                                     }
7123                                 }
7124                             }
7125                         } else {
7126                             allowed = true;
7127                         }
7128                         if (allowed) {
7129                             if (!mSharedLibraries.containsKey(name)) {
7130                                 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName));
7131                             } else if (!name.equals(pkg.packageName)) {
7132                                 Slog.w(TAG, "Package " + pkg.packageName + " library "
7133                                         + name + " already exists; skipping");
7134                             }
7135                         } else {
7136                             Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
7137                                     + name + " that is not declared on system image; skipping");
7138                         }
7139                     }
7140                     if ((scanFlags&SCAN_BOOTING) == 0) {
7141                         // If we are not booting, we need to update any applications
7142                         // that are clients of our shared library.  If we are booting,
7143                         // this will all be done once the scan is complete.
7144                         clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
7145                     }
7146                 }
7147             }
7148         }
7149 
7150         // We also need to dexopt any apps that are dependent on this library.  Note that
7151         // if these fail, we should abort the install since installing the library will
7152         // result in some apps being broken.
7153         if (clientLibPkgs != null) {
7154             if ((scanFlags & SCAN_NO_DEX) == 0) {
7155                 for (int i = 0; i < clientLibPkgs.size(); i++) {
7156                     PackageParser.Package clientPkg = clientLibPkgs.get(i);
7157                     int result = mPackageDexOptimizer.performDexOpt(clientPkg,
7158                             null /* instruction sets */, forceDex,
7159                             (scanFlags & SCAN_DEFER_DEX) != 0, false,
7160                             (scanFlags & SCAN_BOOTING) == 0);
7161                     if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
7162                         throw new PackageManagerException(INSTALL_FAILED_DEXOPT,
7163                                 "scanPackageLI failed to dexopt clientLibPkgs");
7164                     }
7165                 }
7166             }
7167         }
7168 
7169         // Request the ActivityManager to kill the process(only for existing packages)
7170         // so that we do not end up in a confused state while the user is still using the older
7171         // version of the application while the new one gets installed.
7172         if ((scanFlags & SCAN_REPLACING) != 0) {
7173             killApplication(pkg.applicationInfo.packageName,
7174                         pkg.applicationInfo.uid, "replace pkg");
7175         }
7176 
7177         // Also need to kill any apps that are dependent on the library.
7178         if (clientLibPkgs != null) {
7179             for (int i=0; i<clientLibPkgs.size(); i++) {
7180                 PackageParser.Package clientPkg = clientLibPkgs.get(i);
7181                 killApplication(clientPkg.applicationInfo.packageName,
7182                         clientPkg.applicationInfo.uid, "update lib");
7183             }
7184         }
7185 
7186         // Make sure we're not adding any bogus keyset info
7187         KeySetManagerService ksms = mSettings.mKeySetManagerService;
7188         ksms.assertScannedPackageValid(pkg);
7189 
7190         // writer
7191         synchronized (mPackages) {
7192             // We don't expect installation to fail beyond this point
7193 
7194             // Add the new setting to mSettings
7195             mSettings.insertPackageSettingLPw(pkgSetting, pkg);
7196             // Add the new setting to mPackages
7197             mPackages.put(pkg.applicationInfo.packageName, pkg);
7198             // Make sure we don't accidentally delete its data.
7199             final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
7200             while (iter.hasNext()) {
7201                 PackageCleanItem item = iter.next();
7202                 if (pkgName.equals(item.packageName)) {
7203                     iter.remove();
7204                 }
7205             }
7206 
7207             // Take care of first install / last update times.
7208             if (currentTime != 0) {
7209                 if (pkgSetting.firstInstallTime == 0) {
7210                     pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
7211                 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) {
7212                     pkgSetting.lastUpdateTime = currentTime;
7213                 }
7214             } else if (pkgSetting.firstInstallTime == 0) {
7215                 // We need *something*.  Take time time stamp of the file.
7216                 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
7217             } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
7218                 if (scanFileTime != pkgSetting.timeStamp) {
7219                     // A package on the system image has changed; consider this
7220                     // to be an update.
7221                     pkgSetting.lastUpdateTime = scanFileTime;
7222                 }
7223             }
7224 
7225             // Add the package's KeySets to the global KeySetManagerService
7226             ksms.addScannedPackageLPw(pkg);
7227 
7228             int N = pkg.providers.size();
7229             StringBuilder r = null;
7230             int i;
7231             for (i=0; i<N; i++) {
7232                 PackageParser.Provider p = pkg.providers.get(i);
7233                 p.info.processName = fixProcessName(pkg.applicationInfo.processName,
7234                         p.info.processName, pkg.applicationInfo.uid);
7235                 mProviders.addProvider(p);
7236                 p.syncable = p.info.isSyncable;
7237                 if (p.info.authority != null) {
7238                     String names[] = p.info.authority.split(";");
7239                     p.info.authority = null;
7240                     for (int j = 0; j < names.length; j++) {
7241                         if (j == 1 && p.syncable) {
7242                             // We only want the first authority for a provider to possibly be
7243                             // syncable, so if we already added this provider using a different
7244                             // authority clear the syncable flag. We copy the provider before
7245                             // changing it because the mProviders object contains a reference
7246                             // to a provider that we don't want to change.
7247                             // Only do this for the second authority since the resulting provider
7248                             // object can be the same for all future authorities for this provider.
7249                             p = new PackageParser.Provider(p);
7250                             p.syncable = false;
7251                         }
7252                         if (!mProvidersByAuthority.containsKey(names[j])) {
7253                             mProvidersByAuthority.put(names[j], p);
7254                             if (p.info.authority == null) {
7255                                 p.info.authority = names[j];
7256                             } else {
7257                                 p.info.authority = p.info.authority + ";" + names[j];
7258                             }
7259                             if (DEBUG_PACKAGE_SCANNING) {
7260                                 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
7261                                     Log.d(TAG, "Registered content provider: " + names[j]
7262                                             + ", className = " + p.info.name + ", isSyncable = "
7263                                             + p.info.isSyncable);
7264                             }
7265                         } else {
7266                             PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
7267                             Slog.w(TAG, "Skipping provider name " + names[j] +
7268                                     " (in package " + pkg.applicationInfo.packageName +
7269                                     "): name already used by "
7270                                     + ((other != null && other.getComponentName() != null)
7271                                             ? other.getComponentName().getPackageName() : "?"));
7272                         }
7273                     }
7274                 }
7275                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7276                     if (r == null) {
7277                         r = new StringBuilder(256);
7278                     } else {
7279                         r.append(' ');
7280                     }
7281                     r.append(p.info.name);
7282                 }
7283             }
7284             if (r != null) {
7285                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
7286             }
7287 
7288             N = pkg.services.size();
7289             r = null;
7290             for (i=0; i<N; i++) {
7291                 PackageParser.Service s = pkg.services.get(i);
7292                 s.info.processName = fixProcessName(pkg.applicationInfo.processName,
7293                         s.info.processName, pkg.applicationInfo.uid);
7294                 mServices.addService(s);
7295                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7296                     if (r == null) {
7297                         r = new StringBuilder(256);
7298                     } else {
7299                         r.append(' ');
7300                     }
7301                     r.append(s.info.name);
7302                 }
7303             }
7304             if (r != null) {
7305                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
7306             }
7307 
7308             N = pkg.receivers.size();
7309             r = null;
7310             for (i=0; i<N; i++) {
7311                 PackageParser.Activity a = pkg.receivers.get(i);
7312                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
7313                         a.info.processName, pkg.applicationInfo.uid);
7314                 mReceivers.addActivity(a, "receiver");
7315                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7316                     if (r == null) {
7317                         r = new StringBuilder(256);
7318                     } else {
7319                         r.append(' ');
7320                     }
7321                     r.append(a.info.name);
7322                 }
7323             }
7324             if (r != null) {
7325                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
7326             }
7327 
7328             N = pkg.activities.size();
7329             r = null;
7330             for (i=0; i<N; i++) {
7331                 PackageParser.Activity a = pkg.activities.get(i);
7332                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
7333                         a.info.processName, pkg.applicationInfo.uid);
7334                 mActivities.addActivity(a, "activity");
7335                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7336                     if (r == null) {
7337                         r = new StringBuilder(256);
7338                     } else {
7339                         r.append(' ');
7340                     }
7341                     r.append(a.info.name);
7342                 }
7343             }
7344             if (r != null) {
7345                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
7346             }
7347 
7348             N = pkg.permissionGroups.size();
7349             r = null;
7350             for (i=0; i<N; i++) {
7351                 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
7352                 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
7353                 if (cur == null) {
7354                     mPermissionGroups.put(pg.info.name, pg);
7355                     if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7356                         if (r == null) {
7357                             r = new StringBuilder(256);
7358                         } else {
7359                             r.append(' ');
7360                         }
7361                         r.append(pg.info.name);
7362                     }
7363                 } else {
7364                     Slog.w(TAG, "Permission group " + pg.info.name + " from package "
7365                             + pg.info.packageName + " ignored: original from "
7366                             + cur.info.packageName);
7367                     if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7368                         if (r == null) {
7369                             r = new StringBuilder(256);
7370                         } else {
7371                             r.append(' ');
7372                         }
7373                         r.append("DUP:");
7374                         r.append(pg.info.name);
7375                     }
7376                 }
7377             }
7378             if (r != null) {
7379                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
7380             }
7381 
7382             N = pkg.permissions.size();
7383             r = null;
7384             for (i=0; i<N; i++) {
7385                 PackageParser.Permission p = pkg.permissions.get(i);
7386 
7387                 // Assume by default that we did not install this permission into the system.
7388                 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
7389 
7390                 // Now that permission groups have a special meaning, we ignore permission
7391                 // groups for legacy apps to prevent unexpected behavior. In particular,
7392                 // permissions for one app being granted to someone just becuase they happen
7393                 // to be in a group defined by another app (before this had no implications).
7394                 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
7395                     p.group = mPermissionGroups.get(p.info.group);
7396                     // Warn for a permission in an unknown group.
7397                     if (p.info.group != null && p.group == null) {
7398                         Slog.w(TAG, "Permission " + p.info.name + " from package "
7399                                 + p.info.packageName + " in an unknown group " + p.info.group);
7400                     }
7401                 }
7402 
7403                 ArrayMap<String, BasePermission> permissionMap =
7404                         p.tree ? mSettings.mPermissionTrees
7405                                 : mSettings.mPermissions;
7406                 BasePermission bp = permissionMap.get(p.info.name);
7407 
7408                 // Allow system apps to redefine non-system permissions
7409                 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
7410                     final boolean currentOwnerIsSystem = (bp.perm != null
7411                             && isSystemApp(bp.perm.owner));
7412                     if (isSystemApp(p.owner)) {
7413                         if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
7414                             // It's a built-in permission and no owner, take ownership now
7415                             bp.packageSetting = pkgSetting;
7416                             bp.perm = p;
7417                             bp.uid = pkg.applicationInfo.uid;
7418                             bp.sourcePackage = p.info.packageName;
7419                             p.info.flags |= PermissionInfo.FLAG_INSTALLED;
7420                         } else if (!currentOwnerIsSystem) {
7421                             String msg = "New decl " + p.owner + " of permission  "
7422                                     + p.info.name + " is system; overriding " + bp.sourcePackage;
7423                             reportSettingsProblem(Log.WARN, msg);
7424                             bp = null;
7425                         }
7426                     }
7427                 }
7428 
7429                 if (bp == null) {
7430                     bp = new BasePermission(p.info.name, p.info.packageName,
7431                             BasePermission.TYPE_NORMAL);
7432                     permissionMap.put(p.info.name, bp);
7433                 }
7434 
7435                 if (bp.perm == null) {
7436                     if (bp.sourcePackage == null
7437                             || bp.sourcePackage.equals(p.info.packageName)) {
7438                         BasePermission tree = findPermissionTreeLP(p.info.name);
7439                         if (tree == null
7440                                 || tree.sourcePackage.equals(p.info.packageName)) {
7441                             bp.packageSetting = pkgSetting;
7442                             bp.perm = p;
7443                             bp.uid = pkg.applicationInfo.uid;
7444                             bp.sourcePackage = p.info.packageName;
7445                             p.info.flags |= PermissionInfo.FLAG_INSTALLED;
7446                             if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7447                                 if (r == null) {
7448                                     r = new StringBuilder(256);
7449                                 } else {
7450                                     r.append(' ');
7451                                 }
7452                                 r.append(p.info.name);
7453                             }
7454                         } else {
7455                             Slog.w(TAG, "Permission " + p.info.name + " from package "
7456                                     + p.info.packageName + " ignored: base tree "
7457                                     + tree.name + " is from package "
7458                                     + tree.sourcePackage);
7459                         }
7460                     } else {
7461                         Slog.w(TAG, "Permission " + p.info.name + " from package "
7462                                 + p.info.packageName + " ignored: original from "
7463                                 + bp.sourcePackage);
7464                     }
7465                 } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7466                     if (r == null) {
7467                         r = new StringBuilder(256);
7468                     } else {
7469                         r.append(' ');
7470                     }
7471                     r.append("DUP:");
7472                     r.append(p.info.name);
7473                 }
7474                 if (bp.perm == p) {
7475                     bp.protectionLevel = p.info.protectionLevel;
7476                 }
7477             }
7478 
7479             if (r != null) {
7480                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
7481             }
7482 
7483             N = pkg.instrumentation.size();
7484             r = null;
7485             for (i=0; i<N; i++) {
7486                 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
7487                 a.info.packageName = pkg.applicationInfo.packageName;
7488                 a.info.sourceDir = pkg.applicationInfo.sourceDir;
7489                 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
7490                 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
7491                 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
7492                 a.info.dataDir = pkg.applicationInfo.dataDir;
7493 
7494                 // TODO: Update instrumentation.nativeLibraryDir as well ? Does it
7495                 // need other information about the application, like the ABI and what not ?
7496                 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
7497                 mInstrumentation.put(a.getComponentName(), a);
7498                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7499                     if (r == null) {
7500                         r = new StringBuilder(256);
7501                     } else {
7502                         r.append(' ');
7503                     }
7504                     r.append(a.info.name);
7505                 }
7506             }
7507             if (r != null) {
7508                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
7509             }
7510 
7511             if (pkg.protectedBroadcasts != null) {
7512                 N = pkg.protectedBroadcasts.size();
7513                 for (i=0; i<N; i++) {
7514                     mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
7515                 }
7516             }
7517 
7518             pkgSetting.setTimeStamp(scanFileTime);
7519 
7520             // Create idmap files for pairs of (packages, overlay packages).
7521             // Note: "android", ie framework-res.apk, is handled by native layers.
7522             if (pkg.mOverlayTarget != null) {
7523                 // This is an overlay package.
7524                 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) {
7525                     if (!mOverlays.containsKey(pkg.mOverlayTarget)) {
7526                         mOverlays.put(pkg.mOverlayTarget,
7527                                 new ArrayMap<String, PackageParser.Package>());
7528                     }
7529                     ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget);
7530                     map.put(pkg.packageName, pkg);
7531                     PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget);
7532                     if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) {
7533                         throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
7534                                 "scanPackageLI failed to createIdmap");
7535                     }
7536                 }
7537             } else if (mOverlays.containsKey(pkg.packageName) &&
7538                     !pkg.packageName.equals("android")) {
7539                 // This is a regular package, with one or more known overlay packages.
7540                 createIdmapsForPackageLI(pkg);
7541             }
7542         }
7543 
7544         return pkg;
7545     }
7546 
7547     /**
7548      * Derive the ABI of a non-system package located at {@code scanFile}. This information
7549      * is derived purely on the basis of the contents of {@code scanFile} and
7550      * {@code cpuAbiOverride}.
7551      *
7552      * If {@code extractLibs} is true, native libraries are extracted from the app if required.
7553      */
derivePackageAbi(PackageParser.Package pkg, File scanFile, String cpuAbiOverride, boolean extractLibs)7554     public void derivePackageAbi(PackageParser.Package pkg, File scanFile,
7555                                  String cpuAbiOverride, boolean extractLibs)
7556             throws PackageManagerException {
7557         // TODO: We can probably be smarter about this stuff. For installed apps,
7558         // we can calculate this information at install time once and for all. For
7559         // system apps, we can probably assume that this information doesn't change
7560         // after the first boot scan. As things stand, we do lots of unnecessary work.
7561 
7562         // Give ourselves some initial paths; we'll come back for another
7563         // pass once we've determined ABI below.
7564         setNativeLibraryPaths(pkg);
7565 
7566         // We would never need to extract libs for forward-locked and external packages,
7567         // since the container service will do it for us. We shouldn't attempt to
7568         // extract libs from system app when it was not updated.
7569         if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
7570                 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
7571             extractLibs = false;
7572         }
7573 
7574         final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
7575         final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
7576 
7577         NativeLibraryHelper.Handle handle = null;
7578         try {
7579             handle = NativeLibraryHelper.Handle.create(scanFile);
7580             // TODO(multiArch): This can be null for apps that didn't go through the
7581             // usual installation process. We can calculate it again, like we
7582             // do during install time.
7583             //
7584             // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
7585             // unnecessary.
7586             final File nativeLibraryRoot = new File(nativeLibraryRootStr);
7587 
7588             // Null out the abis so that they can be recalculated.
7589             pkg.applicationInfo.primaryCpuAbi = null;
7590             pkg.applicationInfo.secondaryCpuAbi = null;
7591             if (isMultiArch(pkg.applicationInfo)) {
7592                 // Warn if we've set an abiOverride for multi-lib packages..
7593                 // By definition, we need to copy both 32 and 64 bit libraries for
7594                 // such packages.
7595                 if (pkg.cpuAbiOverride != null
7596                         && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
7597                     Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
7598                 }
7599 
7600                 int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
7601                 int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
7602                 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
7603                     if (extractLibs) {
7604                         abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
7605                                 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
7606                                 useIsaSpecificSubdirs);
7607                     } else {
7608                         abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
7609                     }
7610                 }
7611 
7612                 maybeThrowExceptionForMultiArchCopy(
7613                         "Error unpackaging 32 bit native libs for multiarch app.", abi32);
7614 
7615                 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
7616                     if (extractLibs) {
7617                         abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
7618                                 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
7619                                 useIsaSpecificSubdirs);
7620                     } else {
7621                         abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
7622                     }
7623                 }
7624 
7625                 maybeThrowExceptionForMultiArchCopy(
7626                         "Error unpackaging 64 bit native libs for multiarch app.", abi64);
7627 
7628                 if (abi64 >= 0) {
7629                     pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
7630                 }
7631 
7632                 if (abi32 >= 0) {
7633                     final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
7634                     if (abi64 >= 0) {
7635                         pkg.applicationInfo.secondaryCpuAbi = abi;
7636                     } else {
7637                         pkg.applicationInfo.primaryCpuAbi = abi;
7638                     }
7639                 }
7640             } else {
7641                 String[] abiList = (cpuAbiOverride != null) ?
7642                         new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
7643 
7644                 // Enable gross and lame hacks for apps that are built with old
7645                 // SDK tools. We must scan their APKs for renderscript bitcode and
7646                 // not launch them if it's present. Don't bother checking on devices
7647                 // that don't have 64 bit support.
7648                 boolean needsRenderScriptOverride = false;
7649                 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
7650                         NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
7651                     abiList = Build.SUPPORTED_32_BIT_ABIS;
7652                     needsRenderScriptOverride = true;
7653                 }
7654 
7655                 final int copyRet;
7656                 if (extractLibs) {
7657                     copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
7658                             nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
7659                 } else {
7660                     copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
7661                 }
7662 
7663                 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
7664                     throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
7665                             "Error unpackaging native libs for app, errorCode=" + copyRet);
7666                 }
7667 
7668                 if (copyRet >= 0) {
7669                     pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
7670                 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
7671                     pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
7672                 } else if (needsRenderScriptOverride) {
7673                     pkg.applicationInfo.primaryCpuAbi = abiList[0];
7674                 }
7675             }
7676         } catch (IOException ioe) {
7677             Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
7678         } finally {
7679             IoUtils.closeQuietly(handle);
7680         }
7681 
7682         // Now that we've calculated the ABIs and determined if it's an internal app,
7683         // we will go ahead and populate the nativeLibraryPath.
7684         setNativeLibraryPaths(pkg);
7685     }
7686 
7687     /**
7688      * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
7689      * i.e, so that all packages can be run inside a single process if required.
7690      *
7691      * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
7692      * this function will either try and make the ABI for all packages in {@code packagesForUser}
7693      * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
7694      * the ABI selected for {@code packagesForUser}. This variant is used when installing or
7695      * updating a package that belongs to a shared user.
7696      *
7697      * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
7698      * adds unnecessary complexity.
7699      */
adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt, boolean bootComplete)7700     private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
7701             PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt,
7702             boolean bootComplete) {
7703         String requiredInstructionSet = null;
7704         if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
7705             requiredInstructionSet = VMRuntime.getInstructionSet(
7706                      scannedPackage.applicationInfo.primaryCpuAbi);
7707         }
7708 
7709         PackageSetting requirer = null;
7710         for (PackageSetting ps : packagesForUser) {
7711             // If packagesForUser contains scannedPackage, we skip it. This will happen
7712             // when scannedPackage is an update of an existing package. Without this check,
7713             // we will never be able to change the ABI of any package belonging to a shared
7714             // user, even if it's compatible with other packages.
7715             if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
7716                 if (ps.primaryCpuAbiString == null) {
7717                     continue;
7718                 }
7719 
7720                 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
7721                 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
7722                     // We have a mismatch between instruction sets (say arm vs arm64) warn about
7723                     // this but there's not much we can do.
7724                     String errorMessage = "Instruction set mismatch, "
7725                             + ((requirer == null) ? "[caller]" : requirer)
7726                             + " requires " + requiredInstructionSet + " whereas " + ps
7727                             + " requires " + instructionSet;
7728                     Slog.w(TAG, errorMessage);
7729                 }
7730 
7731                 if (requiredInstructionSet == null) {
7732                     requiredInstructionSet = instructionSet;
7733                     requirer = ps;
7734                 }
7735             }
7736         }
7737 
7738         if (requiredInstructionSet != null) {
7739             String adjustedAbi;
7740             if (requirer != null) {
7741                 // requirer != null implies that either scannedPackage was null or that scannedPackage
7742                 // did not require an ABI, in which case we have to adjust scannedPackage to match
7743                 // the ABI of the set (which is the same as requirer's ABI)
7744                 adjustedAbi = requirer.primaryCpuAbiString;
7745                 if (scannedPackage != null) {
7746                     scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
7747                 }
7748             } else {
7749                 // requirer == null implies that we're updating all ABIs in the set to
7750                 // match scannedPackage.
7751                 adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
7752             }
7753 
7754             for (PackageSetting ps : packagesForUser) {
7755                 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
7756                     if (ps.primaryCpuAbiString != null) {
7757                         continue;
7758                     }
7759 
7760                     ps.primaryCpuAbiString = adjustedAbi;
7761                     if (ps.pkg != null && ps.pkg.applicationInfo != null) {
7762                         ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
7763                         Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + adjustedAbi);
7764 
7765                         int result = mPackageDexOptimizer.performDexOpt(ps.pkg,
7766                                 null /* instruction sets */, forceDexOpt, deferDexOpt, true,
7767                                 bootComplete);
7768                         if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
7769                             ps.primaryCpuAbiString = null;
7770                             ps.pkg.applicationInfo.primaryCpuAbi = null;
7771                             return;
7772                         } else {
7773                             mInstaller.rmdex(ps.codePathString,
7774                                     getDexCodeInstructionSet(getPreferredInstructionSet()));
7775                         }
7776                     }
7777                 }
7778             }
7779         }
7780     }
7781 
setUpCustomResolverActivity(PackageParser.Package pkg)7782     private void setUpCustomResolverActivity(PackageParser.Package pkg) {
7783         synchronized (mPackages) {
7784             mResolverReplaced = true;
7785             // Set up information for custom user intent resolution activity.
7786             mResolveActivity.applicationInfo = pkg.applicationInfo;
7787             mResolveActivity.name = mCustomResolverComponentName.getClassName();
7788             mResolveActivity.packageName = pkg.applicationInfo.packageName;
7789             mResolveActivity.processName = pkg.applicationInfo.packageName;
7790             mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
7791             mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
7792                     ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
7793             mResolveActivity.theme = 0;
7794             mResolveActivity.exported = true;
7795             mResolveActivity.enabled = true;
7796             mResolveInfo.activityInfo = mResolveActivity;
7797             mResolveInfo.priority = 0;
7798             mResolveInfo.preferredOrder = 0;
7799             mResolveInfo.match = 0;
7800             mResolveComponentName = mCustomResolverComponentName;
7801             Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
7802                     mResolveComponentName);
7803         }
7804     }
7805 
calculateBundledApkRoot(final String codePathString)7806     private static String calculateBundledApkRoot(final String codePathString) {
7807         final File codePath = new File(codePathString);
7808         final File codeRoot;
7809         if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
7810             codeRoot = Environment.getRootDirectory();
7811         } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
7812             codeRoot = Environment.getOemDirectory();
7813         } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
7814             codeRoot = Environment.getVendorDirectory();
7815         } else {
7816             // Unrecognized code path; take its top real segment as the apk root:
7817             // e.g. /something/app/blah.apk => /something
7818             try {
7819                 File f = codePath.getCanonicalFile();
7820                 File parent = f.getParentFile();    // non-null because codePath is a file
7821                 File tmp;
7822                 while ((tmp = parent.getParentFile()) != null) {
7823                     f = parent;
7824                     parent = tmp;
7825                 }
7826                 codeRoot = f;
7827                 Slog.w(TAG, "Unrecognized code path "
7828                         + codePath + " - using " + codeRoot);
7829             } catch (IOException e) {
7830                 // Can't canonicalize the code path -- shenanigans?
7831                 Slog.w(TAG, "Can't canonicalize code path " + codePath);
7832                 return Environment.getRootDirectory().getPath();
7833             }
7834         }
7835         return codeRoot.getPath();
7836     }
7837 
7838     /**
7839      * Derive and set the location of native libraries for the given package,
7840      * which varies depending on where and how the package was installed.
7841      */
setNativeLibraryPaths(PackageParser.Package pkg)7842     private void setNativeLibraryPaths(PackageParser.Package pkg) {
7843         final ApplicationInfo info = pkg.applicationInfo;
7844         final String codePath = pkg.codePath;
7845         final File codeFile = new File(codePath);
7846         final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
7847         final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
7848 
7849         info.nativeLibraryRootDir = null;
7850         info.nativeLibraryRootRequiresIsa = false;
7851         info.nativeLibraryDir = null;
7852         info.secondaryNativeLibraryDir = null;
7853 
7854         if (isApkFile(codeFile)) {
7855             // Monolithic install
7856             if (bundledApp) {
7857                 // If "/system/lib64/apkname" exists, assume that is the per-package
7858                 // native library directory to use; otherwise use "/system/lib/apkname".
7859                 final String apkRoot = calculateBundledApkRoot(info.sourceDir);
7860                 final boolean is64Bit = VMRuntime.is64BitInstructionSet(
7861                         getPrimaryInstructionSet(info));
7862 
7863                 // This is a bundled system app so choose the path based on the ABI.
7864                 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
7865                 // is just the default path.
7866                 final String apkName = deriveCodePathName(codePath);
7867                 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
7868                 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
7869                         apkName).getAbsolutePath();
7870 
7871                 if (info.secondaryCpuAbi != null) {
7872                     final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
7873                     info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
7874                             secondaryLibDir, apkName).getAbsolutePath();
7875                 }
7876             } else if (asecApp) {
7877                 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
7878                         .getAbsolutePath();
7879             } else {
7880                 final String apkName = deriveCodePathName(codePath);
7881                 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName)
7882                         .getAbsolutePath();
7883             }
7884 
7885             info.nativeLibraryRootRequiresIsa = false;
7886             info.nativeLibraryDir = info.nativeLibraryRootDir;
7887         } else {
7888             // Cluster install
7889             info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
7890             info.nativeLibraryRootRequiresIsa = true;
7891 
7892             info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
7893                     getPrimaryInstructionSet(info)).getAbsolutePath();
7894 
7895             if (info.secondaryCpuAbi != null) {
7896                 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
7897                         VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
7898             }
7899         }
7900     }
7901 
7902     /**
7903      * Calculate the abis and roots for a bundled app. These can uniquely
7904      * be determined from the contents of the system partition, i.e whether
7905      * it contains 64 or 32 bit shared libraries etc. We do not validate any
7906      * of this information, and instead assume that the system was built
7907      * sensibly.
7908      */
setBundledAppAbisAndRoots(PackageParser.Package pkg, PackageSetting pkgSetting)7909     private void setBundledAppAbisAndRoots(PackageParser.Package pkg,
7910                                            PackageSetting pkgSetting) {
7911         final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
7912 
7913         // If "/system/lib64/apkname" exists, assume that is the per-package
7914         // native library directory to use; otherwise use "/system/lib/apkname".
7915         final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
7916         setBundledAppAbi(pkg, apkRoot, apkName);
7917         // pkgSetting might be null during rescan following uninstall of updates
7918         // to a bundled app, so accommodate that possibility.  The settings in
7919         // that case will be established later from the parsed package.
7920         //
7921         // If the settings aren't null, sync them up with what we've just derived.
7922         // note that apkRoot isn't stored in the package settings.
7923         if (pkgSetting != null) {
7924             pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
7925             pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
7926         }
7927     }
7928 
7929     /**
7930      * Deduces the ABI of a bundled app and sets the relevant fields on the
7931      * parsed pkg object.
7932      *
7933      * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
7934      *        under which system libraries are installed.
7935      * @param apkName the name of the installed package.
7936      */
setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName)7937     private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
7938         final File codeFile = new File(pkg.codePath);
7939 
7940         final boolean has64BitLibs;
7941         final boolean has32BitLibs;
7942         if (isApkFile(codeFile)) {
7943             // Monolithic install
7944             has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
7945             has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
7946         } else {
7947             // Cluster install
7948             final File rootDir = new File(codeFile, LIB_DIR_NAME);
7949             if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
7950                     && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
7951                 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
7952                 has64BitLibs = (new File(rootDir, isa)).exists();
7953             } else {
7954                 has64BitLibs = false;
7955             }
7956             if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
7957                     && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
7958                 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
7959                 has32BitLibs = (new File(rootDir, isa)).exists();
7960             } else {
7961                 has32BitLibs = false;
7962             }
7963         }
7964 
7965         if (has64BitLibs && !has32BitLibs) {
7966             // The package has 64 bit libs, but not 32 bit libs. Its primary
7967             // ABI should be 64 bit. We can safely assume here that the bundled
7968             // native libraries correspond to the most preferred ABI in the list.
7969 
7970             pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
7971             pkg.applicationInfo.secondaryCpuAbi = null;
7972         } else if (has32BitLibs && !has64BitLibs) {
7973             // The package has 32 bit libs but not 64 bit libs. Its primary
7974             // ABI should be 32 bit.
7975 
7976             pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
7977             pkg.applicationInfo.secondaryCpuAbi = null;
7978         } else if (has32BitLibs && has64BitLibs) {
7979             // The application has both 64 and 32 bit bundled libraries. We check
7980             // here that the app declares multiArch support, and warn if it doesn't.
7981             //
7982             // We will be lenient here and record both ABIs. The primary will be the
7983             // ABI that's higher on the list, i.e, a device that's configured to prefer
7984             // 64 bit apps will see a 64 bit primary ABI,
7985 
7986             if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
7987                 Slog.e(TAG, "Package: " + pkg + " has multiple bundled libs, but is not multiarch.");
7988             }
7989 
7990             if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
7991                 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
7992                 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
7993             } else {
7994                 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
7995                 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
7996             }
7997         } else {
7998             pkg.applicationInfo.primaryCpuAbi = null;
7999             pkg.applicationInfo.secondaryCpuAbi = null;
8000         }
8001     }
8002 
killApplication(String pkgName, int appId, String reason)8003     private void killApplication(String pkgName, int appId, String reason) {
8004         // Request the ActivityManager to kill the process(only for existing packages)
8005         // so that we do not end up in a confused state while the user is still using the older
8006         // version of the application while the new one gets installed.
8007         IActivityManager am = ActivityManagerNative.getDefault();
8008         if (am != null) {
8009             try {
8010                 am.killApplicationWithAppId(pkgName, appId, reason);
8011             } catch (RemoteException e) {
8012             }
8013         }
8014     }
8015 
removePackageLI(PackageSetting ps, boolean chatty)8016     void removePackageLI(PackageSetting ps, boolean chatty) {
8017         if (DEBUG_INSTALL) {
8018             if (chatty)
8019                 Log.d(TAG, "Removing package " + ps.name);
8020         }
8021 
8022         // writer
8023         synchronized (mPackages) {
8024             mPackages.remove(ps.name);
8025             final PackageParser.Package pkg = ps.pkg;
8026             if (pkg != null) {
8027                 cleanPackageDataStructuresLILPw(pkg, chatty);
8028             }
8029         }
8030     }
8031 
removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty)8032     void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
8033         if (DEBUG_INSTALL) {
8034             if (chatty)
8035                 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
8036         }
8037 
8038         // writer
8039         synchronized (mPackages) {
8040             mPackages.remove(pkg.applicationInfo.packageName);
8041             cleanPackageDataStructuresLILPw(pkg, chatty);
8042         }
8043     }
8044 
cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty)8045     void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
8046         int N = pkg.providers.size();
8047         StringBuilder r = null;
8048         int i;
8049         for (i=0; i<N; i++) {
8050             PackageParser.Provider p = pkg.providers.get(i);
8051             mProviders.removeProvider(p);
8052             if (p.info.authority == null) {
8053 
8054                 /* There was another ContentProvider with this authority when
8055                  * this app was installed so this authority is null,
8056                  * Ignore it as we don't have to unregister the provider.
8057                  */
8058                 continue;
8059             }
8060             String names[] = p.info.authority.split(";");
8061             for (int j = 0; j < names.length; j++) {
8062                 if (mProvidersByAuthority.get(names[j]) == p) {
8063                     mProvidersByAuthority.remove(names[j]);
8064                     if (DEBUG_REMOVE) {
8065                         if (chatty)
8066                             Log.d(TAG, "Unregistered content provider: " + names[j]
8067                                     + ", className = " + p.info.name + ", isSyncable = "
8068                                     + p.info.isSyncable);
8069                     }
8070                 }
8071             }
8072             if (DEBUG_REMOVE && chatty) {
8073                 if (r == null) {
8074                     r = new StringBuilder(256);
8075                 } else {
8076                     r.append(' ');
8077                 }
8078                 r.append(p.info.name);
8079             }
8080         }
8081         if (r != null) {
8082             if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
8083         }
8084 
8085         N = pkg.services.size();
8086         r = null;
8087         for (i=0; i<N; i++) {
8088             PackageParser.Service s = pkg.services.get(i);
8089             mServices.removeService(s);
8090             if (chatty) {
8091                 if (r == null) {
8092                     r = new StringBuilder(256);
8093                 } else {
8094                     r.append(' ');
8095                 }
8096                 r.append(s.info.name);
8097             }
8098         }
8099         if (r != null) {
8100             if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
8101         }
8102 
8103         N = pkg.receivers.size();
8104         r = null;
8105         for (i=0; i<N; i++) {
8106             PackageParser.Activity a = pkg.receivers.get(i);
8107             mReceivers.removeActivity(a, "receiver");
8108             if (DEBUG_REMOVE && chatty) {
8109                 if (r == null) {
8110                     r = new StringBuilder(256);
8111                 } else {
8112                     r.append(' ');
8113                 }
8114                 r.append(a.info.name);
8115             }
8116         }
8117         if (r != null) {
8118             if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
8119         }
8120 
8121         N = pkg.activities.size();
8122         r = null;
8123         for (i=0; i<N; i++) {
8124             PackageParser.Activity a = pkg.activities.get(i);
8125             mActivities.removeActivity(a, "activity");
8126             if (DEBUG_REMOVE && chatty) {
8127                 if (r == null) {
8128                     r = new StringBuilder(256);
8129                 } else {
8130                     r.append(' ');
8131                 }
8132                 r.append(a.info.name);
8133             }
8134         }
8135         if (r != null) {
8136             if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
8137         }
8138 
8139         N = pkg.permissions.size();
8140         r = null;
8141         for (i=0; i<N; i++) {
8142             PackageParser.Permission p = pkg.permissions.get(i);
8143             BasePermission bp = mSettings.mPermissions.get(p.info.name);
8144             if (bp == null) {
8145                 bp = mSettings.mPermissionTrees.get(p.info.name);
8146             }
8147             if (bp != null && bp.perm == p) {
8148                 bp.perm = null;
8149                 if (DEBUG_REMOVE && chatty) {
8150                     if (r == null) {
8151                         r = new StringBuilder(256);
8152                     } else {
8153                         r.append(' ');
8154                     }
8155                     r.append(p.info.name);
8156                 }
8157             }
8158             if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
8159                 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(p.info.name);
8160                 if (appOpPerms != null) {
8161                     appOpPerms.remove(pkg.packageName);
8162                 }
8163             }
8164         }
8165         if (r != null) {
8166             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
8167         }
8168 
8169         N = pkg.requestedPermissions.size();
8170         r = null;
8171         for (i=0; i<N; i++) {
8172             String perm = pkg.requestedPermissions.get(i);
8173             BasePermission bp = mSettings.mPermissions.get(perm);
8174             if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
8175                 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(perm);
8176                 if (appOpPerms != null) {
8177                     appOpPerms.remove(pkg.packageName);
8178                     if (appOpPerms.isEmpty()) {
8179                         mAppOpPermissionPackages.remove(perm);
8180                     }
8181                 }
8182             }
8183         }
8184         if (r != null) {
8185             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
8186         }
8187 
8188         N = pkg.instrumentation.size();
8189         r = null;
8190         for (i=0; i<N; i++) {
8191             PackageParser.Instrumentation a = pkg.instrumentation.get(i);
8192             mInstrumentation.remove(a.getComponentName());
8193             if (DEBUG_REMOVE && chatty) {
8194                 if (r == null) {
8195                     r = new StringBuilder(256);
8196                 } else {
8197                     r.append(' ');
8198                 }
8199                 r.append(a.info.name);
8200             }
8201         }
8202         if (r != null) {
8203             if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
8204         }
8205 
8206         r = null;
8207         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
8208             // Only system apps can hold shared libraries.
8209             if (pkg.libraryNames != null) {
8210                 for (i=0; i<pkg.libraryNames.size(); i++) {
8211                     String name = pkg.libraryNames.get(i);
8212                     SharedLibraryEntry cur = mSharedLibraries.get(name);
8213                     if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) {
8214                         mSharedLibraries.remove(name);
8215                         if (DEBUG_REMOVE && chatty) {
8216                             if (r == null) {
8217                                 r = new StringBuilder(256);
8218                             } else {
8219                                 r.append(' ');
8220                             }
8221                             r.append(name);
8222                         }
8223                     }
8224                 }
8225             }
8226         }
8227         if (r != null) {
8228             if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
8229         }
8230     }
8231 
hasPermission(PackageParser.Package pkgInfo, String perm)8232     private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
8233         for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
8234             if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
8235                 return true;
8236             }
8237         }
8238         return false;
8239     }
8240 
8241     static final int UPDATE_PERMISSIONS_ALL = 1<<0;
8242     static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
8243     static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
8244 
updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, int flags)8245     private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
8246             int flags) {
8247         final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
8248         updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
8249     }
8250 
updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags)8251     private void updatePermissionsLPw(String changingPkg,
8252             PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
8253         // Make sure there are no dangling permission trees.
8254         Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
8255         while (it.hasNext()) {
8256             final BasePermission bp = it.next();
8257             if (bp.packageSetting == null) {
8258                 // We may not yet have parsed the package, so just see if
8259                 // we still know about its settings.
8260                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
8261             }
8262             if (bp.packageSetting == null) {
8263                 Slog.w(TAG, "Removing dangling permission tree: " + bp.name
8264                         + " from package " + bp.sourcePackage);
8265                 it.remove();
8266             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
8267                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
8268                     Slog.i(TAG, "Removing old permission tree: " + bp.name
8269                             + " from package " + bp.sourcePackage);
8270                     flags |= UPDATE_PERMISSIONS_ALL;
8271                     it.remove();
8272                 }
8273             }
8274         }
8275 
8276         // Make sure all dynamic permissions have been assigned to a package,
8277         // and make sure there are no dangling permissions.
8278         it = mSettings.mPermissions.values().iterator();
8279         while (it.hasNext()) {
8280             final BasePermission bp = it.next();
8281             if (bp.type == BasePermission.TYPE_DYNAMIC) {
8282                 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
8283                         + bp.name + " pkg=" + bp.sourcePackage
8284                         + " info=" + bp.pendingInfo);
8285                 if (bp.packageSetting == null && bp.pendingInfo != null) {
8286                     final BasePermission tree = findPermissionTreeLP(bp.name);
8287                     if (tree != null && tree.perm != null) {
8288                         bp.packageSetting = tree.packageSetting;
8289                         bp.perm = new PackageParser.Permission(tree.perm.owner,
8290                                 new PermissionInfo(bp.pendingInfo));
8291                         bp.perm.info.packageName = tree.perm.info.packageName;
8292                         bp.perm.info.name = bp.name;
8293                         bp.uid = tree.uid;
8294                     }
8295                 }
8296             }
8297             if (bp.packageSetting == null) {
8298                 // We may not yet have parsed the package, so just see if
8299                 // we still know about its settings.
8300                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
8301             }
8302             if (bp.packageSetting == null) {
8303                 Slog.w(TAG, "Removing dangling permission: " + bp.name
8304                         + " from package " + bp.sourcePackage);
8305                 it.remove();
8306             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
8307                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
8308                     Slog.i(TAG, "Removing old permission: " + bp.name
8309                             + " from package " + bp.sourcePackage);
8310                     flags |= UPDATE_PERMISSIONS_ALL;
8311                     it.remove();
8312                 }
8313             }
8314         }
8315 
8316         // Now update the permissions for all packages, in particular
8317         // replace the granted permissions of the system packages.
8318         if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
8319             for (PackageParser.Package pkg : mPackages.values()) {
8320                 if (pkg != pkgInfo) {
8321                     // Only replace for packages on requested volume
8322                     final String volumeUuid = getVolumeUuidForPackage(pkg);
8323                     final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
8324                             && Objects.equals(replaceVolumeUuid, volumeUuid);
8325                     grantPermissionsLPw(pkg, replace, changingPkg);
8326                 }
8327             }
8328         }
8329 
8330         if (pkgInfo != null) {
8331             // Only replace for packages on requested volume
8332             final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
8333             final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
8334                     && Objects.equals(replaceVolumeUuid, volumeUuid);
8335             grantPermissionsLPw(pkgInfo, replace, changingPkg);
8336         }
8337     }
8338 
grantPermissionsLPw(PackageParser.Package pkg, boolean replace, String packageOfInterest)8339     private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
8340             String packageOfInterest) {
8341         // IMPORTANT: There are two types of permissions: install and runtime.
8342         // Install time permissions are granted when the app is installed to
8343         // all device users and users added in the future. Runtime permissions
8344         // are granted at runtime explicitly to specific users. Normal and signature
8345         // protected permissions are install time permissions. Dangerous permissions
8346         // are install permissions if the app's target SDK is Lollipop MR1 or older,
8347         // otherwise they are runtime permissions. This function does not manage
8348         // runtime permissions except for the case an app targeting Lollipop MR1
8349         // being upgraded to target a newer SDK, in which case dangerous permissions
8350         // are transformed from install time to runtime ones.
8351 
8352         final PackageSetting ps = (PackageSetting) pkg.mExtras;
8353         if (ps == null) {
8354             return;
8355         }
8356 
8357         PermissionsState permissionsState = ps.getPermissionsState();
8358         PermissionsState origPermissions = permissionsState;
8359 
8360         final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
8361 
8362         boolean runtimePermissionsRevoked = false;
8363         int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
8364 
8365         boolean changedInstallPermission = false;
8366 
8367         if (replace) {
8368             ps.installPermissionsFixed = false;
8369             if (!ps.isSharedUser()) {
8370                 origPermissions = new PermissionsState(permissionsState);
8371                 permissionsState.reset();
8372             } else {
8373                 // We need to know only about runtime permission changes since the
8374                 // calling code always writes the install permissions state but
8375                 // the runtime ones are written only if changed. The only cases of
8376                 // changed runtime permissions here are promotion of an install to
8377                 // runtime and revocation of a runtime from a shared user.
8378                 changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
8379                         ps.sharedUser, UserManagerService.getInstance().getUserIds());
8380                 if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
8381                     runtimePermissionsRevoked = true;
8382                 }
8383             }
8384         }
8385 
8386         permissionsState.setGlobalGids(mGlobalGids);
8387 
8388         final int N = pkg.requestedPermissions.size();
8389         for (int i=0; i<N; i++) {
8390             final String name = pkg.requestedPermissions.get(i);
8391             final BasePermission bp = mSettings.mPermissions.get(name);
8392 
8393             if (DEBUG_INSTALL) {
8394                 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
8395             }
8396 
8397             if (bp == null || bp.packageSetting == null) {
8398                 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
8399                     Slog.w(TAG, "Unknown permission " + name
8400                             + " in package " + pkg.packageName);
8401                 }
8402                 continue;
8403             }
8404 
8405             final String perm = bp.name;
8406             boolean allowedSig = false;
8407             int grant = GRANT_DENIED;
8408 
8409             // Keep track of app op permissions.
8410             if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
8411                 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
8412                 if (pkgs == null) {
8413                     pkgs = new ArraySet<>();
8414                     mAppOpPermissionPackages.put(bp.name, pkgs);
8415                 }
8416                 pkgs.add(pkg.packageName);
8417             }
8418 
8419             final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
8420             switch (level) {
8421                 case PermissionInfo.PROTECTION_NORMAL: {
8422                     // For all apps normal permissions are install time ones.
8423                     grant = GRANT_INSTALL;
8424                 } break;
8425 
8426                 case PermissionInfo.PROTECTION_DANGEROUS: {
8427                     if (pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1) {
8428                         // For legacy apps dangerous permissions are install time ones.
8429                         grant = GRANT_INSTALL_LEGACY;
8430                     } else if (origPermissions.hasInstallPermission(bp.name)) {
8431                         // For legacy apps that became modern, install becomes runtime.
8432                         grant = GRANT_UPGRADE;
8433                     } else if (mPromoteSystemApps
8434                             && isSystemApp(ps)
8435                             && mExistingSystemPackages.contains(ps.name)) {
8436                         // For legacy system apps, install becomes runtime.
8437                         // We cannot check hasInstallPermission() for system apps since those
8438                         // permissions were granted implicitly and not persisted pre-M.
8439                         grant = GRANT_UPGRADE;
8440                     } else {
8441                         // For modern apps keep runtime permissions unchanged.
8442                         grant = GRANT_RUNTIME;
8443                     }
8444                 } break;
8445 
8446                 case PermissionInfo.PROTECTION_SIGNATURE: {
8447                     // For all apps signature permissions are install time ones.
8448                     allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
8449                     if (allowedSig) {
8450                         grant = GRANT_INSTALL;
8451                     }
8452                 } break;
8453             }
8454 
8455             if (DEBUG_INSTALL) {
8456                 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
8457             }
8458 
8459             if (grant != GRANT_DENIED) {
8460                 if (!isSystemApp(ps) && ps.installPermissionsFixed) {
8461                     // If this is an existing, non-system package, then
8462                     // we can't add any new permissions to it.
8463                     if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
8464                         // Except...  if this is a permission that was added
8465                         // to the platform (note: need to only do this when
8466                         // updating the platform).
8467                         if (!isNewPlatformPermissionForPackage(perm, pkg)) {
8468                             grant = GRANT_DENIED;
8469                         }
8470                     }
8471                 }
8472 
8473                 switch (grant) {
8474                     case GRANT_INSTALL: {
8475                         // Revoke this as runtime permission to handle the case of
8476                         // a runtime permission being downgraded to an install one.
8477                         for (int userId : UserManagerService.getInstance().getUserIds()) {
8478                             if (origPermissions.getRuntimePermissionState(
8479                                     bp.name, userId) != null) {
8480                                 // Revoke the runtime permission and clear the flags.
8481                                 origPermissions.revokeRuntimePermission(bp, userId);
8482                                 origPermissions.updatePermissionFlags(bp, userId,
8483                                       PackageManager.MASK_PERMISSION_FLAGS, 0);
8484                                 // If we revoked a permission permission, we have to write.
8485                                 changedRuntimePermissionUserIds = ArrayUtils.appendInt(
8486                                         changedRuntimePermissionUserIds, userId);
8487                             }
8488                         }
8489                         // Grant an install permission.
8490                         if (permissionsState.grantInstallPermission(bp) !=
8491                                 PermissionsState.PERMISSION_OPERATION_FAILURE) {
8492                             changedInstallPermission = true;
8493                         }
8494                     } break;
8495 
8496                     case GRANT_INSTALL_LEGACY: {
8497                         // Grant an install permission.
8498                         if (permissionsState.grantInstallPermission(bp) !=
8499                                 PermissionsState.PERMISSION_OPERATION_FAILURE) {
8500                             changedInstallPermission = true;
8501                         }
8502                     } break;
8503 
8504                     case GRANT_RUNTIME: {
8505                         // Grant previously granted runtime permissions.
8506                         for (int userId : UserManagerService.getInstance().getUserIds()) {
8507                             PermissionState permissionState = origPermissions
8508                                     .getRuntimePermissionState(bp.name, userId);
8509                             final int flags = permissionState != null
8510                                     ? permissionState.getFlags() : 0;
8511                             if (origPermissions.hasRuntimePermission(bp.name, userId)) {
8512                                 if (permissionsState.grantRuntimePermission(bp, userId) ==
8513                                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
8514                                     // If we cannot put the permission as it was, we have to write.
8515                                     changedRuntimePermissionUserIds = ArrayUtils.appendInt(
8516                                             changedRuntimePermissionUserIds, userId);
8517                                 }
8518                             }
8519                             // Propagate the permission flags.
8520                             permissionsState.updatePermissionFlags(bp, userId, flags, flags);
8521                         }
8522                     } break;
8523 
8524                     case GRANT_UPGRADE: {
8525                         // Grant runtime permissions for a previously held install permission.
8526                         PermissionState permissionState = origPermissions
8527                                 .getInstallPermissionState(bp.name);
8528                         final int flags = permissionState != null ? permissionState.getFlags() : 0;
8529 
8530                         if (origPermissions.revokeInstallPermission(bp)
8531                                 != PermissionsState.PERMISSION_OPERATION_FAILURE) {
8532                             // We will be transferring the permission flags, so clear them.
8533                             origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
8534                                     PackageManager.MASK_PERMISSION_FLAGS, 0);
8535                             changedInstallPermission = true;
8536                         }
8537 
8538                         // If the permission is not to be promoted to runtime we ignore it and
8539                         // also its other flags as they are not applicable to install permissions.
8540                         if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
8541                             for (int userId : currentUserIds) {
8542                                 if (permissionsState.grantRuntimePermission(bp, userId) !=
8543                                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
8544                                     // Transfer the permission flags.
8545                                     permissionsState.updatePermissionFlags(bp, userId,
8546                                             flags, flags);
8547                                     // If we granted the permission, we have to write.
8548                                     changedRuntimePermissionUserIds = ArrayUtils.appendInt(
8549                                             changedRuntimePermissionUserIds, userId);
8550                                 }
8551                             }
8552                         }
8553                     } break;
8554 
8555                     default: {
8556                         if (packageOfInterest == null
8557                                 || packageOfInterest.equals(pkg.packageName)) {
8558                             Slog.w(TAG, "Not granting permission " + perm
8559                                     + " to package " + pkg.packageName
8560                                     + " because it was previously installed without");
8561                         }
8562                     } break;
8563                 }
8564             } else {
8565                 if (permissionsState.revokeInstallPermission(bp) !=
8566                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
8567                     // Also drop the permission flags.
8568                     permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
8569                             PackageManager.MASK_PERMISSION_FLAGS, 0);
8570                     changedInstallPermission = true;
8571                     Slog.i(TAG, "Un-granting permission " + perm
8572                             + " from package " + pkg.packageName
8573                             + " (protectionLevel=" + bp.protectionLevel
8574                             + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
8575                             + ")");
8576                 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
8577                     // Don't print warning for app op permissions, since it is fine for them
8578                     // not to be granted, there is a UI for the user to decide.
8579                     if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
8580                         Slog.w(TAG, "Not granting permission " + perm
8581                                 + " to package " + pkg.packageName
8582                                 + " (protectionLevel=" + bp.protectionLevel
8583                                 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
8584                                 + ")");
8585                     }
8586                 }
8587             }
8588         }
8589 
8590         if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
8591                 !isSystemApp(ps) || isUpdatedSystemApp(ps)){
8592             // This is the first that we have heard about this package, so the
8593             // permissions we have now selected are fixed until explicitly
8594             // changed.
8595             ps.installPermissionsFixed = true;
8596         }
8597 
8598         // Persist the runtime permissions state for users with changes. If permissions
8599         // were revoked because no app in the shared user declares them we have to
8600         // write synchronously to avoid losing runtime permissions state.
8601         for (int userId : changedRuntimePermissionUserIds) {
8602             mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
8603         }
8604     }
8605 
isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg)8606     private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
8607         boolean allowed = false;
8608         final int NP = PackageParser.NEW_PERMISSIONS.length;
8609         for (int ip=0; ip<NP; ip++) {
8610             final PackageParser.NewPermissionInfo npi
8611                     = PackageParser.NEW_PERMISSIONS[ip];
8612             if (npi.name.equals(perm)
8613                     && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
8614                 allowed = true;
8615                 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
8616                         + pkg.packageName);
8617                 break;
8618             }
8619         }
8620         return allowed;
8621     }
8622 
grantSignaturePermission(String perm, PackageParser.Package pkg, BasePermission bp, PermissionsState origPermissions)8623     private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
8624             BasePermission bp, PermissionsState origPermissions) {
8625         boolean allowed;
8626         allowed = (compareSignatures(
8627                 bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
8628                         == PackageManager.SIGNATURE_MATCH)
8629                 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
8630                         == PackageManager.SIGNATURE_MATCH);
8631         if (!allowed && (bp.protectionLevel
8632                 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) {
8633             if (isSystemApp(pkg)) {
8634                 // For updated system applications, a system permission
8635                 // is granted only if it had been defined by the original application.
8636                 if (pkg.isUpdatedSystemApp()) {
8637                     final PackageSetting sysPs = mSettings
8638                             .getDisabledSystemPkgLPr(pkg.packageName);
8639                     if (sysPs.getPermissionsState().hasInstallPermission(perm)) {
8640                         // If the original was granted this permission, we take
8641                         // that grant decision as read and propagate it to the
8642                         // update.
8643                         if (sysPs.isPrivileged()) {
8644                             allowed = true;
8645                         }
8646                     } else {
8647                         // The system apk may have been updated with an older
8648                         // version of the one on the data partition, but which
8649                         // granted a new system permission that it didn't have
8650                         // before.  In this case we do want to allow the app to
8651                         // now get the new permission if the ancestral apk is
8652                         // privileged to get it.
8653                         if (sysPs.pkg != null && sysPs.isPrivileged()) {
8654                             for (int j=0;
8655                                     j<sysPs.pkg.requestedPermissions.size(); j++) {
8656                                 if (perm.equals(
8657                                         sysPs.pkg.requestedPermissions.get(j))) {
8658                                     allowed = true;
8659                                     break;
8660                                 }
8661                             }
8662                         }
8663                     }
8664                 } else {
8665                     allowed = isPrivilegedApp(pkg);
8666                 }
8667             }
8668         }
8669         if (!allowed) {
8670             if (!allowed && (bp.protectionLevel
8671                     & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
8672                     && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
8673                 // If this was a previously normal/dangerous permission that got moved
8674                 // to a system permission as part of the runtime permission redesign, then
8675                 // we still want to blindly grant it to old apps.
8676                 allowed = true;
8677             }
8678             if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
8679                     && pkg.packageName.equals(mRequiredInstallerPackage)) {
8680                 // If this permission is to be granted to the system installer and
8681                 // this app is an installer, then it gets the permission.
8682                 allowed = true;
8683             }
8684             if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
8685                     && pkg.packageName.equals(mRequiredVerifierPackage)) {
8686                 // If this permission is to be granted to the system verifier and
8687                 // this app is a verifier, then it gets the permission.
8688                 allowed = true;
8689             }
8690             if (!allowed && (bp.protectionLevel
8691                     & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
8692                     && isSystemApp(pkg)) {
8693                 // Any pre-installed system app is allowed to get this permission.
8694                 allowed = true;
8695             }
8696             if (!allowed && (bp.protectionLevel
8697                     & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
8698                 // For development permissions, a development permission
8699                 // is granted only if it was already granted.
8700                 allowed = origPermissions.hasInstallPermission(perm);
8701             }
8702         }
8703         return allowed;
8704     }
8705 
8706     final class ActivityIntentResolver
8707             extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId)8708         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
8709                 boolean defaultOnly, int userId) {
8710             if (!sUserManager.exists(userId)) return null;
8711             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
8712             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
8713         }
8714 
queryIntent(Intent intent, String resolvedType, int flags, int userId)8715         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
8716                 int userId) {
8717             if (!sUserManager.exists(userId)) return null;
8718             mFlags = flags;
8719             return super.queryIntent(intent, resolvedType,
8720                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
8721         }
8722 
queryIntentForPackage(Intent intent, String resolvedType, int flags, ArrayList<PackageParser.Activity> packageActivities, int userId)8723         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
8724                 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
8725             if (!sUserManager.exists(userId)) return null;
8726             if (packageActivities == null) {
8727                 return null;
8728             }
8729             mFlags = flags;
8730             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
8731             final int N = packageActivities.size();
8732             ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
8733                 new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
8734 
8735             ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
8736             for (int i = 0; i < N; ++i) {
8737                 intentFilters = packageActivities.get(i).intents;
8738                 if (intentFilters != null && intentFilters.size() > 0) {
8739                     PackageParser.ActivityIntentInfo[] array =
8740                             new PackageParser.ActivityIntentInfo[intentFilters.size()];
8741                     intentFilters.toArray(array);
8742                     listCut.add(array);
8743                 }
8744             }
8745             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
8746         }
8747 
8748         /**
8749          * Finds a privileged activity that matches the specified activity names.
8750          */
findMatchingActivity( List<PackageParser.Activity> activityList, ActivityInfo activityInfo)8751         private PackageParser.Activity findMatchingActivity(
8752                 List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
8753             for (PackageParser.Activity sysActivity : activityList) {
8754                 if (sysActivity.info.name.equals(activityInfo.name)) {
8755                     return sysActivity;
8756                 }
8757                 if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
8758                     return sysActivity;
8759                 }
8760                 if (sysActivity.info.targetActivity != null) {
8761                     if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
8762                         return sysActivity;
8763                     }
8764                     if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
8765                         return sysActivity;
8766                     }
8767                 }
8768             }
8769             return null;
8770         }
8771 
8772         public class IterGenerator<E> {
generate(ActivityIntentInfo info)8773             public Iterator<E> generate(ActivityIntentInfo info) {
8774                 return null;
8775             }
8776         }
8777 
8778         public class ActionIterGenerator extends IterGenerator<String> {
8779             @Override
generate(ActivityIntentInfo info)8780             public Iterator<String> generate(ActivityIntentInfo info) {
8781                 return info.actionsIterator();
8782             }
8783         }
8784 
8785         public class CategoriesIterGenerator extends IterGenerator<String> {
8786             @Override
generate(ActivityIntentInfo info)8787             public Iterator<String> generate(ActivityIntentInfo info) {
8788                 return info.categoriesIterator();
8789             }
8790         }
8791 
8792         public class SchemesIterGenerator extends IterGenerator<String> {
8793             @Override
generate(ActivityIntentInfo info)8794             public Iterator<String> generate(ActivityIntentInfo info) {
8795                 return info.schemesIterator();
8796             }
8797         }
8798 
8799         public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
8800             @Override
generate(ActivityIntentInfo info)8801             public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
8802                 return info.authoritiesIterator();
8803             }
8804         }
8805 
8806         /**
8807          * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
8808          * MODIFIED. Do not pass in a list that should not be changed.
8809          */
getIntentListSubset(List<ActivityIntentInfo> intentList, IterGenerator<T> generator, Iterator<T> searchIterator)8810         private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
8811                 IterGenerator<T> generator, Iterator<T> searchIterator) {
8812             // loop through the set of actions; every one must be found in the intent filter
8813             while (searchIterator.hasNext()) {
8814                 // we must have at least one filter in the list to consider a match
8815                 if (intentList.size() == 0) {
8816                     break;
8817                 }
8818 
8819                 final T searchAction = searchIterator.next();
8820 
8821                 // loop through the set of intent filters
8822                 final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
8823                 while (intentIter.hasNext()) {
8824                     final ActivityIntentInfo intentInfo = intentIter.next();
8825                     boolean selectionFound = false;
8826 
8827                     // loop through the intent filter's selection criteria; at least one
8828                     // of them must match the searched criteria
8829                     final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
8830                     while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
8831                         final T intentSelection = intentSelectionIter.next();
8832                         if (intentSelection != null && intentSelection.equals(searchAction)) {
8833                             selectionFound = true;
8834                             break;
8835                         }
8836                     }
8837 
8838                     // the selection criteria wasn't found in this filter's set; this filter
8839                     // is not a potential match
8840                     if (!selectionFound) {
8841                         intentIter.remove();
8842                     }
8843                 }
8844             }
8845         }
8846 
8847         /**
8848          * Adjusts the priority of the given intent filter according to policy.
8849          * <p>
8850          * <ul>
8851          * <li>The priority for unbundled updates to system applications is capped to the
8852          *      priority defined on the system partition</li>
8853          * </ul>
8854          */
adjustPriority( List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent)8855         private void adjustPriority(
8856                 List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
8857             // nothing to do; priority is fine as-is
8858             if (intent.getPriority() <= 0) {
8859                 return;
8860             }
8861 
8862             final ActivityInfo activityInfo = intent.activity.info;
8863             final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
8864 
8865             final boolean systemApp = applicationInfo.isSystemApp();
8866             if (!systemApp) {
8867                 // non-system applications can never define a priority >0
8868                 Slog.w(TAG, "Non-system app; cap priority to 0;"
8869                         + " package: " + applicationInfo.packageName
8870                         + " activity: " + intent.activity.className
8871                         + " origPrio: " + intent.getPriority());
8872                 intent.setPriority(0);
8873                 return;
8874             }
8875 
8876             if (systemActivities == null) {
8877                 // the system package is not disabled; we're parsing the system partition
8878                 // apps on the system image get whatever priority they request
8879                 return;
8880             }
8881 
8882             // system app unbundled update ... try to find the same activity
8883             final PackageParser.Activity foundActivity =
8884                     findMatchingActivity(systemActivities, activityInfo);
8885             if (foundActivity == null) {
8886                 // this is a new activity; it cannot obtain >0 priority
8887                 if (DEBUG_FILTERS) {
8888                     Slog.i(TAG, "New activity; cap priority to 0;"
8889                             + " package: " + applicationInfo.packageName
8890                             + " activity: " + intent.activity.className
8891                             + " origPrio: " + intent.getPriority());
8892                 }
8893                 intent.setPriority(0);
8894                 return;
8895             }
8896 
8897             // found activity, now check for filter equivalence
8898 
8899             // a shallow copy is enough; we modify the list, not its contents
8900             final List<ActivityIntentInfo> intentListCopy =
8901                     new ArrayList<>(foundActivity.intents);
8902             final List<ActivityIntentInfo> foundFilters = findFilters(intent);
8903 
8904             // find matching action subsets
8905             final Iterator<String> actionsIterator = intent.actionsIterator();
8906             if (actionsIterator != null) {
8907                 getIntentListSubset(
8908                         intentListCopy, new ActionIterGenerator(), actionsIterator);
8909                 if (intentListCopy.size() == 0) {
8910                     // no more intents to match; we're not equivalent
8911                     if (DEBUG_FILTERS) {
8912                         Slog.i(TAG, "Mismatched action; cap priority to 0;"
8913                                 + " package: " + applicationInfo.packageName
8914                                 + " activity: " + intent.activity.className
8915                                 + " origPrio: " + intent.getPriority());
8916                     }
8917                     intent.setPriority(0);
8918                     return;
8919                 }
8920             }
8921 
8922             // find matching category subsets
8923             final Iterator<String> categoriesIterator = intent.categoriesIterator();
8924             if (categoriesIterator != null) {
8925                 getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
8926                         categoriesIterator);
8927                 if (intentListCopy.size() == 0) {
8928                     // no more intents to match; we're not equivalent
8929                     if (DEBUG_FILTERS) {
8930                         Slog.i(TAG, "Mismatched category; cap priority to 0;"
8931                                 + " package: " + applicationInfo.packageName
8932                                 + " activity: " + intent.activity.className
8933                                 + " origPrio: " + intent.getPriority());
8934                     }
8935                     intent.setPriority(0);
8936                     return;
8937                 }
8938             }
8939 
8940             // find matching schemes subsets
8941             final Iterator<String> schemesIterator = intent.schemesIterator();
8942             if (schemesIterator != null) {
8943                 getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
8944                         schemesIterator);
8945                 if (intentListCopy.size() == 0) {
8946                     // no more intents to match; we're not equivalent
8947                     if (DEBUG_FILTERS) {
8948                         Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
8949                                 + " package: " + applicationInfo.packageName
8950                                 + " activity: " + intent.activity.className
8951                                 + " origPrio: " + intent.getPriority());
8952                     }
8953                     intent.setPriority(0);
8954                     return;
8955                 }
8956             }
8957 
8958             // find matching authorities subsets
8959             final Iterator<IntentFilter.AuthorityEntry>
8960                     authoritiesIterator = intent.authoritiesIterator();
8961             if (authoritiesIterator != null) {
8962                 getIntentListSubset(intentListCopy,
8963                         new AuthoritiesIterGenerator(),
8964                         authoritiesIterator);
8965                 if (intentListCopy.size() == 0) {
8966                     // no more intents to match; we're not equivalent
8967                     if (DEBUG_FILTERS) {
8968                         Slog.i(TAG, "Mismatched authority; cap priority to 0;"
8969                                 + " package: " + applicationInfo.packageName
8970                                 + " activity: " + intent.activity.className
8971                                 + " origPrio: " + intent.getPriority());
8972                     }
8973                     intent.setPriority(0);
8974                     return;
8975                 }
8976             }
8977 
8978             // we found matching filter(s); app gets the max priority of all intents
8979             int cappedPriority = 0;
8980             for (int i = intentListCopy.size() - 1; i >= 0; --i) {
8981                 cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
8982             }
8983             if (intent.getPriority() > cappedPriority) {
8984                 if (DEBUG_FILTERS) {
8985                     Slog.i(TAG, "Found matching filter(s);"
8986                             + " cap priority to " + cappedPriority + ";"
8987                             + " package: " + applicationInfo.packageName
8988                             + " activity: " + intent.activity.className
8989                             + " origPrio: " + intent.getPriority());
8990                 }
8991                 intent.setPriority(cappedPriority);
8992                 return;
8993             }
8994             // all this for nothing; the requested priority was <= what was on the system
8995         }
8996 
addActivity(PackageParser.Activity a, String type)8997         public final void addActivity(PackageParser.Activity a, String type) {
8998             final boolean systemApp = a.info.applicationInfo.isSystemApp();
8999             mActivities.put(a.getComponentName(), a);
9000             if (DEBUG_SHOW_INFO)
9001                 Log.v(
9002                 TAG, "  " + type + " " +
9003                 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
9004             if (DEBUG_SHOW_INFO)
9005                 Log.v(TAG, "    Class=" + a.info.name);
9006             final int NI = a.intents.size();
9007             for (int j=0; j<NI; j++) {
9008                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
9009                 if ("activity".equals(type)) {
9010                     final PackageSetting ps =
9011                             mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
9012                     final List<PackageParser.Activity> systemActivities =
9013                             ps != null && ps.pkg != null ? ps.pkg.activities : null;
9014                     adjustPriority(systemActivities, intent);
9015                 }
9016                 if (DEBUG_SHOW_INFO) {
9017                     Log.v(TAG, "    IntentFilter:");
9018                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9019                 }
9020                 if (!intent.debugCheck()) {
9021                     Log.w(TAG, "==> For Activity " + a.info.name);
9022                 }
9023                 addFilter(intent);
9024             }
9025         }
9026 
removeActivity(PackageParser.Activity a, String type)9027         public final void removeActivity(PackageParser.Activity a, String type) {
9028             mActivities.remove(a.getComponentName());
9029             if (DEBUG_SHOW_INFO) {
9030                 Log.v(TAG, "  " + type + " "
9031                         + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
9032                                 : a.info.name) + ":");
9033                 Log.v(TAG, "    Class=" + a.info.name);
9034             }
9035             final int NI = a.intents.size();
9036             for (int j=0; j<NI; j++) {
9037                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
9038                 if (DEBUG_SHOW_INFO) {
9039                     Log.v(TAG, "    IntentFilter:");
9040                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9041                 }
9042                 removeFilter(intent);
9043             }
9044         }
9045 
9046         @Override
allowFilterResult( PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest)9047         protected boolean allowFilterResult(
9048                 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
9049             ActivityInfo filterAi = filter.activity.info;
9050             for (int i=dest.size()-1; i>=0; i--) {
9051                 ActivityInfo destAi = dest.get(i).activityInfo;
9052                 if (destAi.name == filterAi.name
9053                         && destAi.packageName == filterAi.packageName) {
9054                     return false;
9055                 }
9056             }
9057             return true;
9058         }
9059 
9060         @Override
newArray(int size)9061         protected ActivityIntentInfo[] newArray(int size) {
9062             return new ActivityIntentInfo[size];
9063         }
9064 
9065         @Override
isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId)9066         protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
9067             if (!sUserManager.exists(userId)) return true;
9068             PackageParser.Package p = filter.activity.owner;
9069             if (p != null) {
9070                 PackageSetting ps = (PackageSetting)p.mExtras;
9071                 if (ps != null) {
9072                     // System apps are never considered stopped for purposes of
9073                     // filtering, because there may be no way for the user to
9074                     // actually re-launch them.
9075                     return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
9076                             && ps.getStopped(userId);
9077                 }
9078             }
9079             return false;
9080         }
9081 
9082         @Override
isPackageForFilter(String packageName, PackageParser.ActivityIntentInfo info)9083         protected boolean isPackageForFilter(String packageName,
9084                 PackageParser.ActivityIntentInfo info) {
9085             return packageName.equals(info.activity.owner.packageName);
9086         }
9087 
9088         @Override
newResult(PackageParser.ActivityIntentInfo info, int match, int userId)9089         protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
9090                 int match, int userId) {
9091             if (!sUserManager.exists(userId)) return null;
9092             if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) {
9093                 return null;
9094             }
9095             final PackageParser.Activity activity = info.activity;
9096             if (mSafeMode && (activity.info.applicationInfo.flags
9097                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
9098                 return null;
9099             }
9100             PackageSetting ps = (PackageSetting) activity.owner.mExtras;
9101             if (ps == null) {
9102                 return null;
9103             }
9104             ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags,
9105                     ps.readUserState(userId), userId);
9106             if (ai == null) {
9107                 return null;
9108             }
9109             final ResolveInfo res = new ResolveInfo();
9110             res.activityInfo = ai;
9111             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
9112                 res.filter = info;
9113             }
9114             if (info != null) {
9115                 res.handleAllWebDataURI = info.handleAllWebDataURI();
9116             }
9117             res.priority = info.getPriority();
9118             res.preferredOrder = activity.owner.mPreferredOrder;
9119             //System.out.println("Result: " + res.activityInfo.className +
9120             //                   " = " + res.priority);
9121             res.match = match;
9122             res.isDefault = info.hasDefault;
9123             res.labelRes = info.labelRes;
9124             res.nonLocalizedLabel = info.nonLocalizedLabel;
9125             if (userNeedsBadging(userId)) {
9126                 res.noResourceId = true;
9127             } else {
9128                 res.icon = info.icon;
9129             }
9130             res.iconResourceId = info.icon;
9131             res.system = res.activityInfo.applicationInfo.isSystemApp();
9132             return res;
9133         }
9134 
9135         @Override
sortResults(List<ResolveInfo> results)9136         protected void sortResults(List<ResolveInfo> results) {
9137             Collections.sort(results, mResolvePrioritySorter);
9138         }
9139 
9140         @Override
dumpFilter(PrintWriter out, String prefix, PackageParser.ActivityIntentInfo filter)9141         protected void dumpFilter(PrintWriter out, String prefix,
9142                 PackageParser.ActivityIntentInfo filter) {
9143             out.print(prefix); out.print(
9144                     Integer.toHexString(System.identityHashCode(filter.activity)));
9145                     out.print(' ');
9146                     filter.activity.printComponentShortName(out);
9147                     out.print(" filter ");
9148                     out.println(Integer.toHexString(System.identityHashCode(filter)));
9149         }
9150 
9151         @Override
filterToLabel(PackageParser.ActivityIntentInfo filter)9152         protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
9153             return filter.activity;
9154         }
9155 
dumpFilterLabel(PrintWriter out, String prefix, Object label, int count)9156         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
9157             PackageParser.Activity activity = (PackageParser.Activity)label;
9158             out.print(prefix); out.print(
9159                     Integer.toHexString(System.identityHashCode(activity)));
9160                     out.print(' ');
9161                     activity.printComponentShortName(out);
9162             if (count > 1) {
9163                 out.print(" ("); out.print(count); out.print(" filters)");
9164             }
9165             out.println();
9166         }
9167 
9168         // Keys are String (activity class name), values are Activity.
9169         private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
9170                 = new ArrayMap<ComponentName, PackageParser.Activity>();
9171         private int mFlags;
9172     }
9173 
9174     private final class ServiceIntentResolver
9175             extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId)9176         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
9177                 boolean defaultOnly, int userId) {
9178             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
9179             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
9180         }
9181 
queryIntent(Intent intent, String resolvedType, int flags, int userId)9182         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
9183                 int userId) {
9184             if (!sUserManager.exists(userId)) return null;
9185             mFlags = flags;
9186             return super.queryIntent(intent, resolvedType,
9187                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
9188         }
9189 
queryIntentForPackage(Intent intent, String resolvedType, int flags, ArrayList<PackageParser.Service> packageServices, int userId)9190         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
9191                 int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
9192             if (!sUserManager.exists(userId)) return null;
9193             if (packageServices == null) {
9194                 return null;
9195             }
9196             mFlags = flags;
9197             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
9198             final int N = packageServices.size();
9199             ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
9200                 new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
9201 
9202             ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
9203             for (int i = 0; i < N; ++i) {
9204                 intentFilters = packageServices.get(i).intents;
9205                 if (intentFilters != null && intentFilters.size() > 0) {
9206                     PackageParser.ServiceIntentInfo[] array =
9207                             new PackageParser.ServiceIntentInfo[intentFilters.size()];
9208                     intentFilters.toArray(array);
9209                     listCut.add(array);
9210                 }
9211             }
9212             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
9213         }
9214 
addService(PackageParser.Service s)9215         public final void addService(PackageParser.Service s) {
9216             mServices.put(s.getComponentName(), s);
9217             if (DEBUG_SHOW_INFO) {
9218                 Log.v(TAG, "  "
9219                         + (s.info.nonLocalizedLabel != null
9220                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
9221                 Log.v(TAG, "    Class=" + s.info.name);
9222             }
9223             final int NI = s.intents.size();
9224             int j;
9225             for (j=0; j<NI; j++) {
9226                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
9227                 if (DEBUG_SHOW_INFO) {
9228                     Log.v(TAG, "    IntentFilter:");
9229                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9230                 }
9231                 if (!intent.debugCheck()) {
9232                     Log.w(TAG, "==> For Service " + s.info.name);
9233                 }
9234                 addFilter(intent);
9235             }
9236         }
9237 
removeService(PackageParser.Service s)9238         public final void removeService(PackageParser.Service s) {
9239             mServices.remove(s.getComponentName());
9240             if (DEBUG_SHOW_INFO) {
9241                 Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
9242                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
9243                 Log.v(TAG, "    Class=" + s.info.name);
9244             }
9245             final int NI = s.intents.size();
9246             int j;
9247             for (j=0; j<NI; j++) {
9248                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
9249                 if (DEBUG_SHOW_INFO) {
9250                     Log.v(TAG, "    IntentFilter:");
9251                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9252                 }
9253                 removeFilter(intent);
9254             }
9255         }
9256 
9257         @Override
allowFilterResult( PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest)9258         protected boolean allowFilterResult(
9259                 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
9260             ServiceInfo filterSi = filter.service.info;
9261             for (int i=dest.size()-1; i>=0; i--) {
9262                 ServiceInfo destAi = dest.get(i).serviceInfo;
9263                 if (destAi.name == filterSi.name
9264                         && destAi.packageName == filterSi.packageName) {
9265                     return false;
9266                 }
9267             }
9268             return true;
9269         }
9270 
9271         @Override
newArray(int size)9272         protected PackageParser.ServiceIntentInfo[] newArray(int size) {
9273             return new PackageParser.ServiceIntentInfo[size];
9274         }
9275 
9276         @Override
isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId)9277         protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
9278             if (!sUserManager.exists(userId)) return true;
9279             PackageParser.Package p = filter.service.owner;
9280             if (p != null) {
9281                 PackageSetting ps = (PackageSetting)p.mExtras;
9282                 if (ps != null) {
9283                     // System apps are never considered stopped for purposes of
9284                     // filtering, because there may be no way for the user to
9285                     // actually re-launch them.
9286                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
9287                             && ps.getStopped(userId);
9288                 }
9289             }
9290             return false;
9291         }
9292 
9293         @Override
isPackageForFilter(String packageName, PackageParser.ServiceIntentInfo info)9294         protected boolean isPackageForFilter(String packageName,
9295                 PackageParser.ServiceIntentInfo info) {
9296             return packageName.equals(info.service.owner.packageName);
9297         }
9298 
9299         @Override
newResult(PackageParser.ServiceIntentInfo filter, int match, int userId)9300         protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
9301                 int match, int userId) {
9302             if (!sUserManager.exists(userId)) return null;
9303             final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
9304             if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) {
9305                 return null;
9306             }
9307             final PackageParser.Service service = info.service;
9308             if (mSafeMode && (service.info.applicationInfo.flags
9309                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
9310                 return null;
9311             }
9312             PackageSetting ps = (PackageSetting) service.owner.mExtras;
9313             if (ps == null) {
9314                 return null;
9315             }
9316             ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
9317                     ps.readUserState(userId), userId);
9318             if (si == null) {
9319                 return null;
9320             }
9321             final ResolveInfo res = new ResolveInfo();
9322             res.serviceInfo = si;
9323             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
9324                 res.filter = filter;
9325             }
9326             res.priority = info.getPriority();
9327             res.preferredOrder = service.owner.mPreferredOrder;
9328             res.match = match;
9329             res.isDefault = info.hasDefault;
9330             res.labelRes = info.labelRes;
9331             res.nonLocalizedLabel = info.nonLocalizedLabel;
9332             res.icon = info.icon;
9333             res.system = res.serviceInfo.applicationInfo.isSystemApp();
9334             return res;
9335         }
9336 
9337         @Override
sortResults(List<ResolveInfo> results)9338         protected void sortResults(List<ResolveInfo> results) {
9339             Collections.sort(results, mResolvePrioritySorter);
9340         }
9341 
9342         @Override
dumpFilter(PrintWriter out, String prefix, PackageParser.ServiceIntentInfo filter)9343         protected void dumpFilter(PrintWriter out, String prefix,
9344                 PackageParser.ServiceIntentInfo filter) {
9345             out.print(prefix); out.print(
9346                     Integer.toHexString(System.identityHashCode(filter.service)));
9347                     out.print(' ');
9348                     filter.service.printComponentShortName(out);
9349                     out.print(" filter ");
9350                     out.println(Integer.toHexString(System.identityHashCode(filter)));
9351         }
9352 
9353         @Override
filterToLabel(PackageParser.ServiceIntentInfo filter)9354         protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
9355             return filter.service;
9356         }
9357 
dumpFilterLabel(PrintWriter out, String prefix, Object label, int count)9358         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
9359             PackageParser.Service service = (PackageParser.Service)label;
9360             out.print(prefix); out.print(
9361                     Integer.toHexString(System.identityHashCode(service)));
9362                     out.print(' ');
9363                     service.printComponentShortName(out);
9364             if (count > 1) {
9365                 out.print(" ("); out.print(count); out.print(" filters)");
9366             }
9367             out.println();
9368         }
9369 
9370 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
9371 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
9372 //            final List<ResolveInfo> retList = Lists.newArrayList();
9373 //            while (i.hasNext()) {
9374 //                final ResolveInfo resolveInfo = (ResolveInfo) i;
9375 //                if (isEnabledLP(resolveInfo.serviceInfo)) {
9376 //                    retList.add(resolveInfo);
9377 //                }
9378 //            }
9379 //            return retList;
9380 //        }
9381 
9382         // Keys are String (activity class name), values are Activity.
9383         private final ArrayMap<ComponentName, PackageParser.Service> mServices
9384                 = new ArrayMap<ComponentName, PackageParser.Service>();
9385         private int mFlags;
9386     };
9387 
9388     private final class ProviderIntentResolver
9389             extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId)9390         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
9391                 boolean defaultOnly, int userId) {
9392             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
9393             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
9394         }
9395 
queryIntent(Intent intent, String resolvedType, int flags, int userId)9396         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
9397                 int userId) {
9398             if (!sUserManager.exists(userId))
9399                 return null;
9400             mFlags = flags;
9401             return super.queryIntent(intent, resolvedType,
9402                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
9403         }
9404 
queryIntentForPackage(Intent intent, String resolvedType, int flags, ArrayList<PackageParser.Provider> packageProviders, int userId)9405         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
9406                 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
9407             if (!sUserManager.exists(userId))
9408                 return null;
9409             if (packageProviders == null) {
9410                 return null;
9411             }
9412             mFlags = flags;
9413             final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
9414             final int N = packageProviders.size();
9415             ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
9416                     new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
9417 
9418             ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
9419             for (int i = 0; i < N; ++i) {
9420                 intentFilters = packageProviders.get(i).intents;
9421                 if (intentFilters != null && intentFilters.size() > 0) {
9422                     PackageParser.ProviderIntentInfo[] array =
9423                             new PackageParser.ProviderIntentInfo[intentFilters.size()];
9424                     intentFilters.toArray(array);
9425                     listCut.add(array);
9426                 }
9427             }
9428             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
9429         }
9430 
addProvider(PackageParser.Provider p)9431         public final void addProvider(PackageParser.Provider p) {
9432             if (mProviders.containsKey(p.getComponentName())) {
9433                 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
9434                 return;
9435             }
9436 
9437             mProviders.put(p.getComponentName(), p);
9438             if (DEBUG_SHOW_INFO) {
9439                 Log.v(TAG, "  "
9440                         + (p.info.nonLocalizedLabel != null
9441                                 ? p.info.nonLocalizedLabel : p.info.name) + ":");
9442                 Log.v(TAG, "    Class=" + p.info.name);
9443             }
9444             final int NI = p.intents.size();
9445             int j;
9446             for (j = 0; j < NI; j++) {
9447                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
9448                 if (DEBUG_SHOW_INFO) {
9449                     Log.v(TAG, "    IntentFilter:");
9450                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9451                 }
9452                 if (!intent.debugCheck()) {
9453                     Log.w(TAG, "==> For Provider " + p.info.name);
9454                 }
9455                 addFilter(intent);
9456             }
9457         }
9458 
removeProvider(PackageParser.Provider p)9459         public final void removeProvider(PackageParser.Provider p) {
9460             mProviders.remove(p.getComponentName());
9461             if (DEBUG_SHOW_INFO) {
9462                 Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
9463                         ? p.info.nonLocalizedLabel : p.info.name) + ":");
9464                 Log.v(TAG, "    Class=" + p.info.name);
9465             }
9466             final int NI = p.intents.size();
9467             int j;
9468             for (j = 0; j < NI; j++) {
9469                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
9470                 if (DEBUG_SHOW_INFO) {
9471                     Log.v(TAG, "    IntentFilter:");
9472                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9473                 }
9474                 removeFilter(intent);
9475             }
9476         }
9477 
9478         @Override
allowFilterResult( PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest)9479         protected boolean allowFilterResult(
9480                 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
9481             ProviderInfo filterPi = filter.provider.info;
9482             for (int i = dest.size() - 1; i >= 0; i--) {
9483                 ProviderInfo destPi = dest.get(i).providerInfo;
9484                 if (destPi.name == filterPi.name
9485                         && destPi.packageName == filterPi.packageName) {
9486                     return false;
9487                 }
9488             }
9489             return true;
9490         }
9491 
9492         @Override
newArray(int size)9493         protected PackageParser.ProviderIntentInfo[] newArray(int size) {
9494             return new PackageParser.ProviderIntentInfo[size];
9495         }
9496 
9497         @Override
isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId)9498         protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
9499             if (!sUserManager.exists(userId))
9500                 return true;
9501             PackageParser.Package p = filter.provider.owner;
9502             if (p != null) {
9503                 PackageSetting ps = (PackageSetting) p.mExtras;
9504                 if (ps != null) {
9505                     // System apps are never considered stopped for purposes of
9506                     // filtering, because there may be no way for the user to
9507                     // actually re-launch them.
9508                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
9509                             && ps.getStopped(userId);
9510                 }
9511             }
9512             return false;
9513         }
9514 
9515         @Override
isPackageForFilter(String packageName, PackageParser.ProviderIntentInfo info)9516         protected boolean isPackageForFilter(String packageName,
9517                 PackageParser.ProviderIntentInfo info) {
9518             return packageName.equals(info.provider.owner.packageName);
9519         }
9520 
9521         @Override
newResult(PackageParser.ProviderIntentInfo filter, int match, int userId)9522         protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
9523                 int match, int userId) {
9524             if (!sUserManager.exists(userId))
9525                 return null;
9526             final PackageParser.ProviderIntentInfo info = filter;
9527             if (!mSettings.isEnabledLPr(info.provider.info, mFlags, userId)) {
9528                 return null;
9529             }
9530             final PackageParser.Provider provider = info.provider;
9531             if (mSafeMode && (provider.info.applicationInfo.flags
9532                     & ApplicationInfo.FLAG_SYSTEM) == 0) {
9533                 return null;
9534             }
9535             PackageSetting ps = (PackageSetting) provider.owner.mExtras;
9536             if (ps == null) {
9537                 return null;
9538             }
9539             ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
9540                     ps.readUserState(userId), userId);
9541             if (pi == null) {
9542                 return null;
9543             }
9544             final ResolveInfo res = new ResolveInfo();
9545             res.providerInfo = pi;
9546             if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
9547                 res.filter = filter;
9548             }
9549             res.priority = info.getPriority();
9550             res.preferredOrder = provider.owner.mPreferredOrder;
9551             res.match = match;
9552             res.isDefault = info.hasDefault;
9553             res.labelRes = info.labelRes;
9554             res.nonLocalizedLabel = info.nonLocalizedLabel;
9555             res.icon = info.icon;
9556             res.system = res.providerInfo.applicationInfo.isSystemApp();
9557             return res;
9558         }
9559 
9560         @Override
sortResults(List<ResolveInfo> results)9561         protected void sortResults(List<ResolveInfo> results) {
9562             Collections.sort(results, mResolvePrioritySorter);
9563         }
9564 
9565         @Override
dumpFilter(PrintWriter out, String prefix, PackageParser.ProviderIntentInfo filter)9566         protected void dumpFilter(PrintWriter out, String prefix,
9567                 PackageParser.ProviderIntentInfo filter) {
9568             out.print(prefix);
9569             out.print(
9570                     Integer.toHexString(System.identityHashCode(filter.provider)));
9571             out.print(' ');
9572             filter.provider.printComponentShortName(out);
9573             out.print(" filter ");
9574             out.println(Integer.toHexString(System.identityHashCode(filter)));
9575         }
9576 
9577         @Override
filterToLabel(PackageParser.ProviderIntentInfo filter)9578         protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
9579             return filter.provider;
9580         }
9581 
dumpFilterLabel(PrintWriter out, String prefix, Object label, int count)9582         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
9583             PackageParser.Provider provider = (PackageParser.Provider)label;
9584             out.print(prefix); out.print(
9585                     Integer.toHexString(System.identityHashCode(provider)));
9586                     out.print(' ');
9587                     provider.printComponentShortName(out);
9588             if (count > 1) {
9589                 out.print(" ("); out.print(count); out.print(" filters)");
9590             }
9591             out.println();
9592         }
9593 
9594         private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
9595                 = new ArrayMap<ComponentName, PackageParser.Provider>();
9596         private int mFlags;
9597     };
9598 
9599     private static final Comparator<ResolveInfo> mResolvePrioritySorter =
9600             new Comparator<ResolveInfo>() {
9601         public int compare(ResolveInfo r1, ResolveInfo r2) {
9602             int v1 = r1.priority;
9603             int v2 = r2.priority;
9604             //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
9605             if (v1 != v2) {
9606                 return (v1 > v2) ? -1 : 1;
9607             }
9608             v1 = r1.preferredOrder;
9609             v2 = r2.preferredOrder;
9610             if (v1 != v2) {
9611                 return (v1 > v2) ? -1 : 1;
9612             }
9613             if (r1.isDefault != r2.isDefault) {
9614                 return r1.isDefault ? -1 : 1;
9615             }
9616             v1 = r1.match;
9617             v2 = r2.match;
9618             //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
9619             if (v1 != v2) {
9620                 return (v1 > v2) ? -1 : 1;
9621             }
9622             if (r1.system != r2.system) {
9623                 return r1.system ? -1 : 1;
9624             }
9625             return 0;
9626         }
9627     };
9628 
9629     private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
9630             new Comparator<ProviderInfo>() {
9631         public int compare(ProviderInfo p1, ProviderInfo p2) {
9632             final int v1 = p1.initOrder;
9633             final int v2 = p2.initOrder;
9634             return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
9635         }
9636     };
9637 
sendPackageBroadcast(final String action, final String pkg, final Bundle extras, final String targetPkg, final IIntentReceiver finishedReceiver, final int[] userIds)9638     final void sendPackageBroadcast(final String action, final String pkg,
9639             final Bundle extras, final String targetPkg, final IIntentReceiver finishedReceiver,
9640             final int[] userIds) {
9641         mHandler.post(new Runnable() {
9642             @Override
9643             public void run() {
9644                 try {
9645                     final IActivityManager am = ActivityManagerNative.getDefault();
9646                     if (am == null) return;
9647                     final int[] resolvedUserIds;
9648                     if (userIds == null) {
9649                         resolvedUserIds = am.getRunningUserIds();
9650                     } else {
9651                         resolvedUserIds = userIds;
9652                     }
9653                     for (int id : resolvedUserIds) {
9654                         final Intent intent = new Intent(action,
9655                                 pkg != null ? Uri.fromParts("package", pkg, null) : null);
9656                         if (extras != null) {
9657                             intent.putExtras(extras);
9658                         }
9659                         if (targetPkg != null) {
9660                             intent.setPackage(targetPkg);
9661                         }
9662                         // Modify the UID when posting to other users
9663                         int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
9664                         if (uid > 0 && UserHandle.getUserId(uid) != id) {
9665                             uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
9666                             intent.putExtra(Intent.EXTRA_UID, uid);
9667                         }
9668                         intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
9669                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
9670                         if (DEBUG_BROADCASTS) {
9671                             RuntimeException here = new RuntimeException("here");
9672                             here.fillInStackTrace();
9673                             Slog.d(TAG, "Sending to user " + id + ": "
9674                                     + intent.toShortString(false, true, false, false)
9675                                     + " " + intent.getExtras(), here);
9676                         }
9677                         am.broadcastIntent(null, intent, null, finishedReceiver,
9678                                 0, null, null, null, android.app.AppOpsManager.OP_NONE,
9679                                 null, finishedReceiver != null, false, id);
9680                     }
9681                 } catch (RemoteException ex) {
9682                 }
9683             }
9684         });
9685     }
9686 
9687     /**
9688      * Check if the external storage media is available. This is true if there
9689      * is a mounted external storage medium or if the external storage is
9690      * emulated.
9691      */
isExternalMediaAvailable()9692     private boolean isExternalMediaAvailable() {
9693         return mMediaMounted || Environment.isExternalStorageEmulated();
9694     }
9695 
9696     @Override
nextPackageToClean(PackageCleanItem lastPackage)9697     public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
9698         // writer
9699         synchronized (mPackages) {
9700             if (!isExternalMediaAvailable()) {
9701                 // If the external storage is no longer mounted at this point,
9702                 // the caller may not have been able to delete all of this
9703                 // packages files and can not delete any more.  Bail.
9704                 return null;
9705             }
9706             final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
9707             if (lastPackage != null) {
9708                 pkgs.remove(lastPackage);
9709             }
9710             if (pkgs.size() > 0) {
9711                 return pkgs.get(0);
9712             }
9713         }
9714         return null;
9715     }
9716 
schedulePackageCleaning(String packageName, int userId, boolean andCode)9717     void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
9718         final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
9719                 userId, andCode ? 1 : 0, packageName);
9720         if (mSystemReady) {
9721             msg.sendToTarget();
9722         } else {
9723             if (mPostSystemReadyMessages == null) {
9724                 mPostSystemReadyMessages = new ArrayList<>();
9725             }
9726             mPostSystemReadyMessages.add(msg);
9727         }
9728     }
9729 
startCleaningPackages()9730     void startCleaningPackages() {
9731         // reader
9732         synchronized (mPackages) {
9733             if (!isExternalMediaAvailable()) {
9734                 return;
9735             }
9736             if (mSettings.mPackagesToBeCleaned.isEmpty()) {
9737                 return;
9738             }
9739         }
9740         Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
9741         intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
9742         IActivityManager am = ActivityManagerNative.getDefault();
9743         if (am != null) {
9744             try {
9745                 am.startService(null, intent, null, mContext.getOpPackageName(),
9746                         UserHandle.USER_OWNER);
9747             } catch (RemoteException e) {
9748             }
9749         }
9750     }
9751 
9752     @Override
installPackage(String originPath, IPackageInstallObserver2 observer, int installFlags, String installerPackageName, VerificationParams verificationParams, String packageAbiOverride)9753     public void installPackage(String originPath, IPackageInstallObserver2 observer,
9754             int installFlags, String installerPackageName, VerificationParams verificationParams,
9755             String packageAbiOverride) {
9756         installPackageAsUser(originPath, observer, installFlags, installerPackageName,
9757                 verificationParams, packageAbiOverride, UserHandle.getCallingUserId());
9758     }
9759 
9760     @Override
installPackageAsUser(String originPath, IPackageInstallObserver2 observer, int installFlags, String installerPackageName, VerificationParams verificationParams, String packageAbiOverride, int userId)9761     public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
9762             int installFlags, String installerPackageName, VerificationParams verificationParams,
9763             String packageAbiOverride, int userId) {
9764         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
9765 
9766         final int callingUid = Binder.getCallingUid();
9767         enforceCrossUserPermission(callingUid, userId, true, true, "installPackageAsUser");
9768 
9769         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
9770             try {
9771                 if (observer != null) {
9772                     observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
9773                 }
9774             } catch (RemoteException re) {
9775             }
9776             return;
9777         }
9778 
9779         if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
9780             installFlags |= PackageManager.INSTALL_FROM_ADB;
9781 
9782         } else {
9783             // Caller holds INSTALL_PACKAGES permission, so we're less strict
9784             // about installerPackageName.
9785 
9786             installFlags &= ~PackageManager.INSTALL_FROM_ADB;
9787             installFlags &= ~PackageManager.INSTALL_ALL_USERS;
9788         }
9789 
9790         UserHandle user;
9791         if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
9792             user = UserHandle.ALL;
9793         } else {
9794             user = new UserHandle(userId);
9795         }
9796 
9797         // Only system components can circumvent runtime permissions when installing.
9798         if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
9799                 && mContext.checkCallingOrSelfPermission(Manifest.permission
9800                 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
9801             throw new SecurityException("You need the "
9802                     + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
9803                     + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
9804         }
9805 
9806         verificationParams.setInstallerUid(callingUid);
9807 
9808         final File originFile = new File(originPath);
9809         final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
9810 
9811         final Message msg = mHandler.obtainMessage(INIT_COPY);
9812         msg.obj = new InstallParams(origin, null, observer, installFlags, installerPackageName,
9813                 null, verificationParams, user, packageAbiOverride, null);
9814         mHandler.sendMessage(msg);
9815     }
9816 
installStage(String packageName, File stagedDir, String stagedCid, IPackageInstallObserver2 observer, PackageInstaller.SessionParams params, String installerPackageName, int installerUid, UserHandle user)9817     void installStage(String packageName, File stagedDir, String stagedCid,
9818             IPackageInstallObserver2 observer, PackageInstaller.SessionParams params,
9819             String installerPackageName, int installerUid, UserHandle user) {
9820         final VerificationParams verifParams = new VerificationParams(null, params.originatingUri,
9821                 params.referrerUri, installerUid, null);
9822         verifParams.setInstallerUid(installerUid);
9823 
9824         final OriginInfo origin;
9825         if (stagedDir != null) {
9826             origin = OriginInfo.fromStagedFile(stagedDir);
9827         } else {
9828             origin = OriginInfo.fromStagedContainer(stagedCid);
9829         }
9830 
9831         final Message msg = mHandler.obtainMessage(INIT_COPY);
9832         msg.obj = new InstallParams(origin, null, observer, params.installFlags,
9833                 installerPackageName, params.volumeUuid, verifParams, user, params.abiOverride,
9834                 params.grantedRuntimePermissions);
9835         mHandler.sendMessage(msg);
9836     }
9837 
sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId)9838     private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId) {
9839         Bundle extras = new Bundle(1);
9840         extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId));
9841 
9842         sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
9843                 packageName, extras, null, null, new int[] {userId});
9844         try {
9845             IActivityManager am = ActivityManagerNative.getDefault();
9846             final boolean isSystem =
9847                     isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
9848             if (isSystem && am.isUserRunning(userId, false)) {
9849                 // The just-installed/enabled app is bundled on the system, so presumed
9850                 // to be able to run automatically without needing an explicit launch.
9851                 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
9852                 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED)
9853                         .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
9854                         .setPackage(packageName);
9855                 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
9856                         android.app.AppOpsManager.OP_NONE, null, false, false, userId);
9857             }
9858         } catch (RemoteException e) {
9859             // shouldn't happen
9860             Slog.w(TAG, "Unable to bootstrap installed package", e);
9861         }
9862     }
9863 
9864     @Override
setApplicationHiddenSettingAsUser(String packageName, boolean hidden, int userId)9865     public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
9866             int userId) {
9867         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
9868         PackageSetting pkgSetting;
9869         final int uid = Binder.getCallingUid();
9870         enforceCrossUserPermission(uid, userId, true, true,
9871                 "setApplicationHiddenSetting for user " + userId);
9872 
9873         if (hidden && isPackageDeviceAdmin(packageName, userId)) {
9874             Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
9875             return false;
9876         }
9877 
9878         long callingId = Binder.clearCallingIdentity();
9879         try {
9880             boolean sendAdded = false;
9881             boolean sendRemoved = false;
9882             // writer
9883             synchronized (mPackages) {
9884                 pkgSetting = mSettings.mPackages.get(packageName);
9885                 if (pkgSetting == null) {
9886                     return false;
9887                 }
9888                 if (pkgSetting.getHidden(userId) != hidden) {
9889                     pkgSetting.setHidden(hidden, userId);
9890                     mSettings.writePackageRestrictionsLPr(userId);
9891                     if (hidden) {
9892                         sendRemoved = true;
9893                     } else {
9894                         sendAdded = true;
9895                     }
9896                 }
9897             }
9898             if (sendAdded) {
9899                 sendPackageAddedForUser(packageName, pkgSetting, userId);
9900                 return true;
9901             }
9902             if (sendRemoved) {
9903                 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
9904                         "hiding pkg");
9905                 sendApplicationHiddenForUser(packageName, pkgSetting, userId);
9906                 return true;
9907             }
9908         } finally {
9909             Binder.restoreCallingIdentity(callingId);
9910         }
9911         return false;
9912     }
9913 
sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, int userId)9914     private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
9915             int userId) {
9916         final PackageRemovedInfo info = new PackageRemovedInfo();
9917         info.removedPackage = packageName;
9918         info.removedUsers = new int[] {userId};
9919         info.uid = UserHandle.getUid(userId, pkgSetting.appId);
9920         info.sendBroadcast(false, false, false);
9921     }
9922 
9923     /**
9924      * Returns true if application is not found or there was an error. Otherwise it returns
9925      * the hidden state of the package for the given user.
9926      */
9927     @Override
getApplicationHiddenSettingAsUser(String packageName, int userId)9928     public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
9929         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
9930         enforceCrossUserPermission(Binder.getCallingUid(), userId, true,
9931                 false, "getApplicationHidden for user " + userId);
9932         PackageSetting pkgSetting;
9933         long callingId = Binder.clearCallingIdentity();
9934         try {
9935             // writer
9936             synchronized (mPackages) {
9937                 pkgSetting = mSettings.mPackages.get(packageName);
9938                 if (pkgSetting == null) {
9939                     return true;
9940                 }
9941                 return pkgSetting.getHidden(userId);
9942             }
9943         } finally {
9944             Binder.restoreCallingIdentity(callingId);
9945         }
9946     }
9947 
9948     /**
9949      * @hide
9950      */
9951     @Override
installExistingPackageAsUser(String packageName, int userId)9952     public int installExistingPackageAsUser(String packageName, int userId) {
9953         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
9954                 null);
9955         PackageSetting pkgSetting;
9956         final int uid = Binder.getCallingUid();
9957         enforceCrossUserPermission(uid, userId, true, true, "installExistingPackage for user "
9958                 + userId);
9959         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
9960             return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
9961         }
9962 
9963         long callingId = Binder.clearCallingIdentity();
9964         try {
9965             boolean sendAdded = false;
9966 
9967             // writer
9968             synchronized (mPackages) {
9969                 pkgSetting = mSettings.mPackages.get(packageName);
9970                 if (pkgSetting == null) {
9971                     return PackageManager.INSTALL_FAILED_INVALID_URI;
9972                 }
9973                 if (!pkgSetting.getInstalled(userId)) {
9974                     pkgSetting.setInstalled(true, userId);
9975                     pkgSetting.setHidden(false, userId);
9976                     mSettings.writePackageRestrictionsLPr(userId);
9977                     sendAdded = true;
9978                 }
9979             }
9980 
9981             if (sendAdded) {
9982                 sendPackageAddedForUser(packageName, pkgSetting, userId);
9983             }
9984         } finally {
9985             Binder.restoreCallingIdentity(callingId);
9986         }
9987 
9988         return PackageManager.INSTALL_SUCCEEDED;
9989     }
9990 
isUserRestricted(int userId, String restrictionKey)9991     boolean isUserRestricted(int userId, String restrictionKey) {
9992         Bundle restrictions = sUserManager.getUserRestrictions(userId);
9993         if (restrictions.getBoolean(restrictionKey, false)) {
9994             Log.w(TAG, "User is restricted: " + restrictionKey);
9995             return true;
9996         }
9997         return false;
9998     }
9999 
10000     @Override
verifyPendingInstall(int id, int verificationCode)10001     public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
10002         mContext.enforceCallingOrSelfPermission(
10003                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
10004                 "Only package verification agents can verify applications");
10005 
10006         final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
10007         final PackageVerificationResponse response = new PackageVerificationResponse(
10008                 verificationCode, Binder.getCallingUid());
10009         msg.arg1 = id;
10010         msg.obj = response;
10011         mHandler.sendMessage(msg);
10012     }
10013 
10014     @Override
extendVerificationTimeout(int id, int verificationCodeAtTimeout, long millisecondsToDelay)10015     public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
10016             long millisecondsToDelay) {
10017         mContext.enforceCallingOrSelfPermission(
10018                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
10019                 "Only package verification agents can extend verification timeouts");
10020 
10021         final PackageVerificationState state = mPendingVerification.get(id);
10022         final PackageVerificationResponse response = new PackageVerificationResponse(
10023                 verificationCodeAtTimeout, Binder.getCallingUid());
10024 
10025         if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
10026             millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
10027         }
10028         if (millisecondsToDelay < 0) {
10029             millisecondsToDelay = 0;
10030         }
10031         if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
10032                 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
10033             verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
10034         }
10035 
10036         if ((state != null) && !state.timeoutExtended()) {
10037             state.extendTimeout();
10038 
10039             final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
10040             msg.arg1 = id;
10041             msg.obj = response;
10042             mHandler.sendMessageDelayed(msg, millisecondsToDelay);
10043         }
10044     }
10045 
broadcastPackageVerified(int verificationId, Uri packageUri, int verificationCode, UserHandle user)10046     private void broadcastPackageVerified(int verificationId, Uri packageUri,
10047             int verificationCode, UserHandle user) {
10048         final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
10049         intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
10050         intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
10051         intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
10052         intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
10053 
10054         mContext.sendBroadcastAsUser(intent, user,
10055                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
10056     }
10057 
matchComponentForVerifier(String packageName, List<ResolveInfo> receivers)10058     private ComponentName matchComponentForVerifier(String packageName,
10059             List<ResolveInfo> receivers) {
10060         ActivityInfo targetReceiver = null;
10061 
10062         final int NR = receivers.size();
10063         for (int i = 0; i < NR; i++) {
10064             final ResolveInfo info = receivers.get(i);
10065             if (info.activityInfo == null) {
10066                 continue;
10067             }
10068 
10069             if (packageName.equals(info.activityInfo.packageName)) {
10070                 targetReceiver = info.activityInfo;
10071                 break;
10072             }
10073         }
10074 
10075         if (targetReceiver == null) {
10076             return null;
10077         }
10078 
10079         return new ComponentName(targetReceiver.packageName, targetReceiver.name);
10080     }
10081 
matchVerifiers(PackageInfoLite pkgInfo, List<ResolveInfo> receivers, final PackageVerificationState verificationState)10082     private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
10083             List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
10084         if (pkgInfo.verifiers.length == 0) {
10085             return null;
10086         }
10087 
10088         final int N = pkgInfo.verifiers.length;
10089         final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
10090         for (int i = 0; i < N; i++) {
10091             final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
10092 
10093             final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
10094                     receivers);
10095             if (comp == null) {
10096                 continue;
10097             }
10098 
10099             final int verifierUid = getUidForVerifier(verifierInfo);
10100             if (verifierUid == -1) {
10101                 continue;
10102             }
10103 
10104             if (DEBUG_VERIFY) {
10105                 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
10106                         + " with the correct signature");
10107             }
10108             sufficientVerifiers.add(comp);
10109             verificationState.addSufficientVerifier(verifierUid);
10110         }
10111 
10112         return sufficientVerifiers;
10113     }
10114 
getUidForVerifier(VerifierInfo verifierInfo)10115     private int getUidForVerifier(VerifierInfo verifierInfo) {
10116         synchronized (mPackages) {
10117             final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
10118             if (pkg == null) {
10119                 return -1;
10120             } else if (pkg.mSignatures.length != 1) {
10121                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
10122                         + " has more than one signature; ignoring");
10123                 return -1;
10124             }
10125 
10126             /*
10127              * If the public key of the package's signature does not match
10128              * our expected public key, then this is a different package and
10129              * we should skip.
10130              */
10131 
10132             final byte[] expectedPublicKey;
10133             try {
10134                 final Signature verifierSig = pkg.mSignatures[0];
10135                 final PublicKey publicKey = verifierSig.getPublicKey();
10136                 expectedPublicKey = publicKey.getEncoded();
10137             } catch (CertificateException e) {
10138                 return -1;
10139             }
10140 
10141             final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
10142 
10143             if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
10144                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
10145                         + " does not have the expected public key; ignoring");
10146                 return -1;
10147             }
10148 
10149             return pkg.applicationInfo.uid;
10150         }
10151     }
10152 
10153     @Override
finishPackageInstall(int token)10154     public void finishPackageInstall(int token) {
10155         enforceSystemOrRoot("Only the system is allowed to finish installs");
10156 
10157         if (DEBUG_INSTALL) {
10158             Slog.v(TAG, "BM finishing package install for " + token);
10159         }
10160 
10161         final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
10162         mHandler.sendMessage(msg);
10163     }
10164 
10165     /**
10166      * Get the verification agent timeout.
10167      *
10168      * @return verification timeout in milliseconds
10169      */
getVerificationTimeout()10170     private long getVerificationTimeout() {
10171         return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
10172                 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
10173                 DEFAULT_VERIFICATION_TIMEOUT);
10174     }
10175 
10176     /**
10177      * Get the default verification agent response code.
10178      *
10179      * @return default verification response code
10180      */
getDefaultVerificationResponse()10181     private int getDefaultVerificationResponse() {
10182         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
10183                 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
10184                 DEFAULT_VERIFICATION_RESPONSE);
10185     }
10186 
10187     /**
10188      * Check whether or not package verification has been enabled.
10189      *
10190      * @return true if verification should be performed
10191      */
isVerificationEnabled(int userId, int installFlags)10192     private boolean isVerificationEnabled(int userId, int installFlags) {
10193         if (!DEFAULT_VERIFY_ENABLE) {
10194             return false;
10195         }
10196 
10197         boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
10198 
10199         // Check if installing from ADB
10200         if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
10201             // Do not run verification in a test harness environment
10202             if (ActivityManager.isRunningInTestHarness()) {
10203                 return false;
10204             }
10205             if (ensureVerifyAppsEnabled) {
10206                 return true;
10207             }
10208             // Check if the developer does not want package verification for ADB installs
10209             if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
10210                     android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
10211                 return false;
10212             }
10213         }
10214 
10215         if (ensureVerifyAppsEnabled) {
10216             return true;
10217         }
10218 
10219         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
10220                 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
10221     }
10222 
10223     @Override
verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)10224     public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
10225             throws RemoteException {
10226         mContext.enforceCallingOrSelfPermission(
10227                 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
10228                 "Only intentfilter verification agents can verify applications");
10229 
10230         final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
10231         final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
10232                 Binder.getCallingUid(), verificationCode, failedDomains);
10233         msg.arg1 = id;
10234         msg.obj = response;
10235         mHandler.sendMessage(msg);
10236     }
10237 
10238     @Override
getIntentVerificationStatus(String packageName, int userId)10239     public int getIntentVerificationStatus(String packageName, int userId) {
10240         synchronized (mPackages) {
10241             return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
10242         }
10243     }
10244 
10245     @Override
updateIntentVerificationStatus(String packageName, int status, int userId)10246     public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
10247         mContext.enforceCallingOrSelfPermission(
10248                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
10249 
10250         boolean result = false;
10251         synchronized (mPackages) {
10252             result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
10253         }
10254         if (result) {
10255             scheduleWritePackageRestrictionsLocked(userId);
10256         }
10257         return result;
10258     }
10259 
10260     @Override
getIntentFilterVerifications(String packageName)10261     public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) {
10262         synchronized (mPackages) {
10263             return mSettings.getIntentFilterVerificationsLPr(packageName);
10264         }
10265     }
10266 
10267     @Override
getAllIntentFilters(String packageName)10268     public List<IntentFilter> getAllIntentFilters(String packageName) {
10269         if (TextUtils.isEmpty(packageName)) {
10270             return Collections.<IntentFilter>emptyList();
10271         }
10272         synchronized (mPackages) {
10273             PackageParser.Package pkg = mPackages.get(packageName);
10274             if (pkg == null || pkg.activities == null) {
10275                 return Collections.<IntentFilter>emptyList();
10276             }
10277             final int count = pkg.activities.size();
10278             ArrayList<IntentFilter> result = new ArrayList<>();
10279             for (int n=0; n<count; n++) {
10280                 PackageParser.Activity activity = pkg.activities.get(n);
10281                 if (activity.intents != null || activity.intents.size() > 0) {
10282                     result.addAll(activity.intents);
10283                 }
10284             }
10285             return result;
10286         }
10287     }
10288 
10289     @Override
setDefaultBrowserPackageName(String packageName, int userId)10290     public boolean setDefaultBrowserPackageName(String packageName, int userId) {
10291         mContext.enforceCallingOrSelfPermission(
10292                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
10293 
10294         synchronized (mPackages) {
10295             boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
10296             if (packageName != null) {
10297                 result |= updateIntentVerificationStatus(packageName,
10298                         PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS,
10299                         userId);
10300                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
10301                         packageName, userId);
10302             }
10303             return result;
10304         }
10305     }
10306 
10307     @Override
getDefaultBrowserPackageName(int userId)10308     public String getDefaultBrowserPackageName(int userId) {
10309         synchronized (mPackages) {
10310             return mSettings.getDefaultBrowserPackageNameLPw(userId);
10311         }
10312     }
10313 
10314     /**
10315      * Get the "allow unknown sources" setting.
10316      *
10317      * @return the current "allow unknown sources" setting
10318      */
getUnknownSourcesSettings()10319     private int getUnknownSourcesSettings() {
10320         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
10321                 android.provider.Settings.Global.INSTALL_NON_MARKET_APPS,
10322                 -1);
10323     }
10324 
10325     @Override
setInstallerPackageName(String targetPackage, String installerPackageName)10326     public void setInstallerPackageName(String targetPackage, String installerPackageName) {
10327         final int uid = Binder.getCallingUid();
10328         // writer
10329         synchronized (mPackages) {
10330             PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
10331             if (targetPackageSetting == null) {
10332                 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
10333             }
10334 
10335             PackageSetting installerPackageSetting;
10336             if (installerPackageName != null) {
10337                 installerPackageSetting = mSettings.mPackages.get(installerPackageName);
10338                 if (installerPackageSetting == null) {
10339                     throw new IllegalArgumentException("Unknown installer package: "
10340                             + installerPackageName);
10341                 }
10342             } else {
10343                 installerPackageSetting = null;
10344             }
10345 
10346             Signature[] callerSignature;
10347             Object obj = mSettings.getUserIdLPr(uid);
10348             if (obj != null) {
10349                 if (obj instanceof SharedUserSetting) {
10350                     callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
10351                 } else if (obj instanceof PackageSetting) {
10352                     callerSignature = ((PackageSetting)obj).signatures.mSignatures;
10353                 } else {
10354                     throw new SecurityException("Bad object " + obj + " for uid " + uid);
10355                 }
10356             } else {
10357                 throw new SecurityException("Unknown calling uid " + uid);
10358             }
10359 
10360             // Verify: can't set installerPackageName to a package that is
10361             // not signed with the same cert as the caller.
10362             if (installerPackageSetting != null) {
10363                 if (compareSignatures(callerSignature,
10364                         installerPackageSetting.signatures.mSignatures)
10365                         != PackageManager.SIGNATURE_MATCH) {
10366                     throw new SecurityException(
10367                             "Caller does not have same cert as new installer package "
10368                             + installerPackageName);
10369                 }
10370             }
10371 
10372             // Verify: if target already has an installer package, it must
10373             // be signed with the same cert as the caller.
10374             if (targetPackageSetting.installerPackageName != null) {
10375                 PackageSetting setting = mSettings.mPackages.get(
10376                         targetPackageSetting.installerPackageName);
10377                 // If the currently set package isn't valid, then it's always
10378                 // okay to change it.
10379                 if (setting != null) {
10380                     if (compareSignatures(callerSignature,
10381                             setting.signatures.mSignatures)
10382                             != PackageManager.SIGNATURE_MATCH) {
10383                         throw new SecurityException(
10384                                 "Caller does not have same cert as old installer package "
10385                                 + targetPackageSetting.installerPackageName);
10386                     }
10387                 }
10388             }
10389 
10390             // Okay!
10391             targetPackageSetting.installerPackageName = installerPackageName;
10392             scheduleWriteSettingsLocked();
10393         }
10394     }
10395 
processPendingInstall(final InstallArgs args, final int currentStatus)10396     private void processPendingInstall(final InstallArgs args, final int currentStatus) {
10397         // Queue up an async operation since the package installation may take a little while.
10398         mHandler.post(new Runnable() {
10399             public void run() {
10400                 mHandler.removeCallbacks(this);
10401                  // Result object to be returned
10402                 PackageInstalledInfo res = new PackageInstalledInfo();
10403                 res.returnCode = currentStatus;
10404                 res.uid = -1;
10405                 res.pkg = null;
10406                 res.removedInfo = new PackageRemovedInfo();
10407                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
10408                     args.doPreInstall(res.returnCode);
10409                     synchronized (mInstallLock) {
10410                         installPackageLI(args, res);
10411                     }
10412                     args.doPostInstall(res.returnCode, res.uid);
10413                 }
10414 
10415                 // A restore should be performed at this point if (a) the install
10416                 // succeeded, (b) the operation is not an update, and (c) the new
10417                 // package has not opted out of backup participation.
10418                 final boolean update = res.removedInfo.removedPackage != null;
10419                 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
10420                 boolean doRestore = !update
10421                         && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
10422 
10423                 // Set up the post-install work request bookkeeping.  This will be used
10424                 // and cleaned up by the post-install event handling regardless of whether
10425                 // there's a restore pass performed.  Token values are >= 1.
10426                 int token;
10427                 if (mNextInstallToken < 0) mNextInstallToken = 1;
10428                 token = mNextInstallToken++;
10429 
10430                 PostInstallData data = new PostInstallData(args, res);
10431                 mRunningInstalls.put(token, data);
10432                 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
10433 
10434                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
10435                     // Pass responsibility to the Backup Manager.  It will perform a
10436                     // restore if appropriate, then pass responsibility back to the
10437                     // Package Manager to run the post-install observer callbacks
10438                     // and broadcasts.
10439                     IBackupManager bm = IBackupManager.Stub.asInterface(
10440                             ServiceManager.getService(Context.BACKUP_SERVICE));
10441                     if (bm != null) {
10442                         if (DEBUG_INSTALL) Log.v(TAG, "token " + token
10443                                 + " to BM for possible restore");
10444                         try {
10445                             if (bm.isBackupServiceActive(UserHandle.USER_OWNER)) {
10446                                 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
10447                             } else {
10448                                 doRestore = false;
10449                             }
10450                         } catch (RemoteException e) {
10451                             // can't happen; the backup manager is local
10452                         } catch (Exception e) {
10453                             Slog.e(TAG, "Exception trying to enqueue restore", e);
10454                             doRestore = false;
10455                         }
10456                     } else {
10457                         Slog.e(TAG, "Backup Manager not found!");
10458                         doRestore = false;
10459                     }
10460                 }
10461 
10462                 if (!doRestore) {
10463                     // No restore possible, or the Backup Manager was mysteriously not
10464                     // available -- just fire the post-install work request directly.
10465                     if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
10466                     Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
10467                     mHandler.sendMessage(msg);
10468                 }
10469             }
10470         });
10471     }
10472 
10473     private abstract class HandlerParams {
10474         private static final int MAX_RETRIES = 4;
10475 
10476         /**
10477          * Number of times startCopy() has been attempted and had a non-fatal
10478          * error.
10479          */
10480         private int mRetries = 0;
10481 
10482         /** User handle for the user requesting the information or installation. */
10483         private final UserHandle mUser;
10484 
HandlerParams(UserHandle user)10485         HandlerParams(UserHandle user) {
10486             mUser = user;
10487         }
10488 
getUser()10489         UserHandle getUser() {
10490             return mUser;
10491         }
10492 
startCopy()10493         final boolean startCopy() {
10494             boolean res;
10495             try {
10496                 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
10497 
10498                 if (++mRetries > MAX_RETRIES) {
10499                     Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
10500                     mHandler.sendEmptyMessage(MCS_GIVE_UP);
10501                     handleServiceError();
10502                     return false;
10503                 } else {
10504                     handleStartCopy();
10505                     res = true;
10506                 }
10507             } catch (RemoteException e) {
10508                 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
10509                 mHandler.sendEmptyMessage(MCS_RECONNECT);
10510                 res = false;
10511             }
10512             handleReturnCode();
10513             return res;
10514         }
10515 
serviceError()10516         final void serviceError() {
10517             if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
10518             handleServiceError();
10519             handleReturnCode();
10520         }
10521 
handleStartCopy()10522         abstract void handleStartCopy() throws RemoteException;
handleServiceError()10523         abstract void handleServiceError();
handleReturnCode()10524         abstract void handleReturnCode();
10525     }
10526 
10527     class MeasureParams extends HandlerParams {
10528         private final PackageStats mStats;
10529         private boolean mSuccess;
10530 
10531         private final IPackageStatsObserver mObserver;
10532 
MeasureParams(PackageStats stats, IPackageStatsObserver observer)10533         public MeasureParams(PackageStats stats, IPackageStatsObserver observer) {
10534             super(new UserHandle(stats.userHandle));
10535             mObserver = observer;
10536             mStats = stats;
10537         }
10538 
10539         @Override
toString()10540         public String toString() {
10541             return "MeasureParams{"
10542                 + Integer.toHexString(System.identityHashCode(this))
10543                 + " " + mStats.packageName + "}";
10544         }
10545 
10546         @Override
handleStartCopy()10547         void handleStartCopy() throws RemoteException {
10548             synchronized (mInstallLock) {
10549                 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats);
10550             }
10551 
10552             if (mSuccess) {
10553                 final boolean mounted;
10554                 if (Environment.isExternalStorageEmulated()) {
10555                     mounted = true;
10556                 } else {
10557                     final String status = Environment.getExternalStorageState();
10558                     mounted = (Environment.MEDIA_MOUNTED.equals(status)
10559                             || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status));
10560                 }
10561 
10562                 if (mounted) {
10563                     final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle);
10564 
10565                     mStats.externalCacheSize = calculateDirectorySize(mContainerService,
10566                             userEnv.buildExternalStorageAppCacheDirs(mStats.packageName));
10567 
10568                     mStats.externalDataSize = calculateDirectorySize(mContainerService,
10569                             userEnv.buildExternalStorageAppDataDirs(mStats.packageName));
10570 
10571                     // Always subtract cache size, since it's a subdirectory
10572                     mStats.externalDataSize -= mStats.externalCacheSize;
10573 
10574                     mStats.externalMediaSize = calculateDirectorySize(mContainerService,
10575                             userEnv.buildExternalStorageAppMediaDirs(mStats.packageName));
10576 
10577                     mStats.externalObbSize = calculateDirectorySize(mContainerService,
10578                             userEnv.buildExternalStorageAppObbDirs(mStats.packageName));
10579                 }
10580             }
10581         }
10582 
10583         @Override
handleReturnCode()10584         void handleReturnCode() {
10585             if (mObserver != null) {
10586                 try {
10587                     mObserver.onGetStatsCompleted(mStats, mSuccess);
10588                 } catch (RemoteException e) {
10589                     Slog.i(TAG, "Observer no longer exists.");
10590                 }
10591             }
10592         }
10593 
10594         @Override
handleServiceError()10595         void handleServiceError() {
10596             Slog.e(TAG, "Could not measure application " + mStats.packageName
10597                             + " external storage");
10598         }
10599     }
10600 
calculateDirectorySize(IMediaContainerService mcs, File[] paths)10601     private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths)
10602             throws RemoteException {
10603         long result = 0;
10604         for (File path : paths) {
10605             result += mcs.calculateDirectorySize(path.getAbsolutePath());
10606         }
10607         return result;
10608     }
10609 
clearDirectory(IMediaContainerService mcs, File[] paths)10610     private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
10611         for (File path : paths) {
10612             try {
10613                 mcs.clearDirectory(path.getAbsolutePath());
10614             } catch (RemoteException e) {
10615             }
10616         }
10617     }
10618 
10619     static class OriginInfo {
10620         /**
10621          * Location where install is coming from, before it has been
10622          * copied/renamed into place. This could be a single monolithic APK
10623          * file, or a cluster directory. This location may be untrusted.
10624          */
10625         final File file;
10626         final String cid;
10627 
10628         /**
10629          * Flag indicating that {@link #file} or {@link #cid} has already been
10630          * staged, meaning downstream users don't need to defensively copy the
10631          * contents.
10632          */
10633         final boolean staged;
10634 
10635         /**
10636          * Flag indicating that {@link #file} or {@link #cid} is an already
10637          * installed app that is being moved.
10638          */
10639         final boolean existing;
10640 
10641         final String resolvedPath;
10642         final File resolvedFile;
10643 
fromNothing()10644         static OriginInfo fromNothing() {
10645             return new OriginInfo(null, null, false, false);
10646         }
10647 
fromUntrustedFile(File file)10648         static OriginInfo fromUntrustedFile(File file) {
10649             return new OriginInfo(file, null, false, false);
10650         }
10651 
fromExistingFile(File file)10652         static OriginInfo fromExistingFile(File file) {
10653             return new OriginInfo(file, null, false, true);
10654         }
10655 
fromStagedFile(File file)10656         static OriginInfo fromStagedFile(File file) {
10657             return new OriginInfo(file, null, true, false);
10658         }
10659 
fromStagedContainer(String cid)10660         static OriginInfo fromStagedContainer(String cid) {
10661             return new OriginInfo(null, cid, true, false);
10662         }
10663 
OriginInfo(File file, String cid, boolean staged, boolean existing)10664         private OriginInfo(File file, String cid, boolean staged, boolean existing) {
10665             this.file = file;
10666             this.cid = cid;
10667             this.staged = staged;
10668             this.existing = existing;
10669 
10670             if (cid != null) {
10671                 resolvedPath = PackageHelper.getSdDir(cid);
10672                 resolvedFile = new File(resolvedPath);
10673             } else if (file != null) {
10674                 resolvedPath = file.getAbsolutePath();
10675                 resolvedFile = file;
10676             } else {
10677                 resolvedPath = null;
10678                 resolvedFile = null;
10679             }
10680         }
10681     }
10682 
10683     class MoveInfo {
10684         final int moveId;
10685         final String fromUuid;
10686         final String toUuid;
10687         final String packageName;
10688         final String dataAppName;
10689         final int appId;
10690         final String seinfo;
10691 
MoveInfo(int moveId, String fromUuid, String toUuid, String packageName, String dataAppName, int appId, String seinfo)10692         public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
10693                 String dataAppName, int appId, String seinfo) {
10694             this.moveId = moveId;
10695             this.fromUuid = fromUuid;
10696             this.toUuid = toUuid;
10697             this.packageName = packageName;
10698             this.dataAppName = dataAppName;
10699             this.appId = appId;
10700             this.seinfo = seinfo;
10701         }
10702     }
10703 
10704     class InstallParams extends HandlerParams {
10705         final OriginInfo origin;
10706         final MoveInfo move;
10707         final IPackageInstallObserver2 observer;
10708         int installFlags;
10709         final String installerPackageName;
10710         final String volumeUuid;
10711         final VerificationParams verificationParams;
10712         private InstallArgs mArgs;
10713         private int mRet;
10714         final String packageAbiOverride;
10715         final String[] grantedRuntimePermissions;
10716 
10717 
InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, int installFlags, String installerPackageName, String volumeUuid, VerificationParams verificationParams, UserHandle user, String packageAbiOverride, String[] grantedPermissions)10718         InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
10719                 int installFlags, String installerPackageName, String volumeUuid,
10720                 VerificationParams verificationParams, UserHandle user, String packageAbiOverride,
10721                 String[] grantedPermissions) {
10722             super(user);
10723             this.origin = origin;
10724             this.move = move;
10725             this.observer = observer;
10726             this.installFlags = installFlags;
10727             this.installerPackageName = installerPackageName;
10728             this.volumeUuid = volumeUuid;
10729             this.verificationParams = verificationParams;
10730             this.packageAbiOverride = packageAbiOverride;
10731             this.grantedRuntimePermissions = grantedPermissions;
10732         }
10733 
10734         @Override
toString()10735         public String toString() {
10736             return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
10737                     + " file=" + origin.file + " cid=" + origin.cid + "}";
10738         }
10739 
getManifestDigest()10740         public ManifestDigest getManifestDigest() {
10741             if (verificationParams == null) {
10742                 return null;
10743             }
10744             return verificationParams.getManifestDigest();
10745         }
10746 
installLocationPolicy(PackageInfoLite pkgLite)10747         private int installLocationPolicy(PackageInfoLite pkgLite) {
10748             String packageName = pkgLite.packageName;
10749             int installLocation = pkgLite.installLocation;
10750             boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
10751             // reader
10752             synchronized (mPackages) {
10753                 PackageParser.Package pkg = mPackages.get(packageName);
10754                 if (pkg != null) {
10755                     if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
10756                         // Check for downgrading.
10757                         if ((installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0) {
10758                             try {
10759                                 checkDowngrade(pkg, pkgLite);
10760                             } catch (PackageManagerException e) {
10761                                 Slog.w(TAG, "Downgrade detected: " + e.getMessage());
10762                                 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
10763                             }
10764                         }
10765                         // Check for updated system application.
10766                         if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10767                             if (onSd) {
10768                                 Slog.w(TAG, "Cannot install update to system app on sdcard");
10769                                 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
10770                             }
10771                             return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
10772                         } else {
10773                             if (onSd) {
10774                                 // Install flag overrides everything.
10775                                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
10776                             }
10777                             // If current upgrade specifies particular preference
10778                             if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
10779                                 // Application explicitly specified internal.
10780                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
10781                             } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
10782                                 // App explictly prefers external. Let policy decide
10783                             } else {
10784                                 // Prefer previous location
10785                                 if (isExternal(pkg)) {
10786                                     return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
10787                                 }
10788                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
10789                             }
10790                         }
10791                     } else {
10792                         // Invalid install. Return error code
10793                         return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
10794                     }
10795                 }
10796             }
10797             // All the special cases have been taken care of.
10798             // Return result based on recommended install location.
10799             if (onSd) {
10800                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
10801             }
10802             return pkgLite.recommendedInstallLocation;
10803         }
10804 
10805         /*
10806          * Invoke remote method to get package information and install
10807          * location values. Override install location based on default
10808          * policy if needed and then create install arguments based
10809          * on the install location.
10810          */
handleStartCopy()10811         public void handleStartCopy() throws RemoteException {
10812             int ret = PackageManager.INSTALL_SUCCEEDED;
10813 
10814             // If we're already staged, we've firmly committed to an install location
10815             if (origin.staged) {
10816                 if (origin.file != null) {
10817                     installFlags |= PackageManager.INSTALL_INTERNAL;
10818                     installFlags &= ~PackageManager.INSTALL_EXTERNAL;
10819                 } else if (origin.cid != null) {
10820                     installFlags |= PackageManager.INSTALL_EXTERNAL;
10821                     installFlags &= ~PackageManager.INSTALL_INTERNAL;
10822                 } else {
10823                     throw new IllegalStateException("Invalid stage location");
10824                 }
10825             }
10826 
10827             final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
10828             final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
10829 
10830             PackageInfoLite pkgLite = null;
10831 
10832             if (onInt && onSd) {
10833                 // Check if both bits are set.
10834                 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
10835                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
10836             } else {
10837                 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
10838                         packageAbiOverride);
10839 
10840                 /*
10841                  * If we have too little free space, try to free cache
10842                  * before giving up.
10843                  */
10844                 if (!origin.staged && pkgLite.recommendedInstallLocation
10845                         == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
10846                     // TODO: focus freeing disk space on the target device
10847                     final StorageManager storage = StorageManager.from(mContext);
10848                     final long lowThreshold = storage.getStorageLowBytes(
10849                             Environment.getDataDirectory());
10850 
10851                     final long sizeBytes = mContainerService.calculateInstalledSize(
10852                             origin.resolvedPath, isForwardLocked(), packageAbiOverride);
10853 
10854                     if (mInstaller.freeCache(null, sizeBytes + lowThreshold) >= 0) {
10855                         pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
10856                                 installFlags, packageAbiOverride);
10857                     }
10858 
10859                     /*
10860                      * The cache free must have deleted the file we
10861                      * downloaded to install.
10862                      *
10863                      * TODO: fix the "freeCache" call to not delete
10864                      *       the file we care about.
10865                      */
10866                     if (pkgLite.recommendedInstallLocation
10867                             == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
10868                         pkgLite.recommendedInstallLocation
10869                             = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
10870                     }
10871                 }
10872             }
10873 
10874             if (ret == PackageManager.INSTALL_SUCCEEDED) {
10875                 int loc = pkgLite.recommendedInstallLocation;
10876                 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
10877                     ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
10878                 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
10879                     ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
10880                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
10881                     ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
10882                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
10883                     ret = PackageManager.INSTALL_FAILED_INVALID_APK;
10884                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
10885                     ret = PackageManager.INSTALL_FAILED_INVALID_URI;
10886                 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
10887                     ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
10888                 } else {
10889                     // Override with defaults if needed.
10890                     loc = installLocationPolicy(pkgLite);
10891                     if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
10892                         ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
10893                     } else if (!onSd && !onInt) {
10894                         // Override install location with flags
10895                         if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
10896                             // Set the flag to install on external media.
10897                             installFlags |= PackageManager.INSTALL_EXTERNAL;
10898                             installFlags &= ~PackageManager.INSTALL_INTERNAL;
10899                         } else {
10900                             // Make sure the flag for installing on external
10901                             // media is unset
10902                             installFlags |= PackageManager.INSTALL_INTERNAL;
10903                             installFlags &= ~PackageManager.INSTALL_EXTERNAL;
10904                         }
10905                     }
10906                 }
10907             }
10908 
10909             final InstallArgs args = createInstallArgs(this);
10910             mArgs = args;
10911 
10912             if (ret == PackageManager.INSTALL_SUCCEEDED) {
10913                  /*
10914                  * ADB installs appear as UserHandle.USER_ALL, and can only be performed by
10915                  * UserHandle.USER_OWNER, so use the package verifier for UserHandle.USER_OWNER.
10916                  */
10917                 int userIdentifier = getUser().getIdentifier();
10918                 if (userIdentifier == UserHandle.USER_ALL
10919                         && ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0)) {
10920                     userIdentifier = UserHandle.USER_OWNER;
10921                 }
10922 
10923                 /*
10924                  * Determine if we have any installed package verifiers. If we
10925                  * do, then we'll defer to them to verify the packages.
10926                  */
10927                 final int requiredUid = mRequiredVerifierPackage == null ? -1
10928                         : getPackageUid(mRequiredVerifierPackage, userIdentifier);
10929                 if (!origin.existing && requiredUid != -1
10930                         && isVerificationEnabled(userIdentifier, installFlags)) {
10931                     final Intent verification = new Intent(
10932                             Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
10933                     verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10934                     verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
10935                             PACKAGE_MIME_TYPE);
10936                     verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
10937 
10938                     final List<ResolveInfo> receivers = queryIntentReceivers(verification,
10939                             PACKAGE_MIME_TYPE, PackageManager.GET_DISABLED_COMPONENTS,
10940                             0 /* TODO: Which userId? */);
10941 
10942                     if (DEBUG_VERIFY) {
10943                         Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
10944                                 + verification.toString() + " with " + pkgLite.verifiers.length
10945                                 + " optional verifiers");
10946                     }
10947 
10948                     final int verificationId = mPendingVerificationToken++;
10949 
10950                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
10951 
10952                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
10953                             installerPackageName);
10954 
10955                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
10956                             installFlags);
10957 
10958                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
10959                             pkgLite.packageName);
10960 
10961                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
10962                             pkgLite.versionCode);
10963 
10964                     if (verificationParams != null) {
10965                         if (verificationParams.getVerificationURI() != null) {
10966                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI,
10967                                  verificationParams.getVerificationURI());
10968                         }
10969                         if (verificationParams.getOriginatingURI() != null) {
10970                             verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
10971                                   verificationParams.getOriginatingURI());
10972                         }
10973                         if (verificationParams.getReferrer() != null) {
10974                             verification.putExtra(Intent.EXTRA_REFERRER,
10975                                   verificationParams.getReferrer());
10976                         }
10977                         if (verificationParams.getOriginatingUid() >= 0) {
10978                             verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
10979                                   verificationParams.getOriginatingUid());
10980                         }
10981                         if (verificationParams.getInstallerUid() >= 0) {
10982                             verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
10983                                   verificationParams.getInstallerUid());
10984                         }
10985                     }
10986 
10987                     final PackageVerificationState verificationState = new PackageVerificationState(
10988                             requiredUid, args);
10989 
10990                     mPendingVerification.append(verificationId, verificationState);
10991 
10992                     final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
10993                             receivers, verificationState);
10994 
10995                     // Apps installed for "all" users use the device owner to verify the app
10996                     UserHandle verifierUser = getUser();
10997                     if (verifierUser == UserHandle.ALL) {
10998                         verifierUser = UserHandle.OWNER;
10999                     }
11000 
11001                     /*
11002                      * If any sufficient verifiers were listed in the package
11003                      * manifest, attempt to ask them.
11004                      */
11005                     if (sufficientVerifiers != null) {
11006                         final int N = sufficientVerifiers.size();
11007                         if (N == 0) {
11008                             Slog.i(TAG, "Additional verifiers required, but none installed.");
11009                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
11010                         } else {
11011                             for (int i = 0; i < N; i++) {
11012                                 final ComponentName verifierComponent = sufficientVerifiers.get(i);
11013 
11014                                 final Intent sufficientIntent = new Intent(verification);
11015                                 sufficientIntent.setComponent(verifierComponent);
11016                                 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
11017                             }
11018                         }
11019                     }
11020 
11021                     final ComponentName requiredVerifierComponent = matchComponentForVerifier(
11022                             mRequiredVerifierPackage, receivers);
11023                     if (ret == PackageManager.INSTALL_SUCCEEDED
11024                             && mRequiredVerifierPackage != null) {
11025                         /*
11026                          * Send the intent to the required verification agent,
11027                          * but only start the verification timeout after the
11028                          * target BroadcastReceivers have run.
11029                          */
11030                         verification.setComponent(requiredVerifierComponent);
11031                         mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
11032                                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
11033                                 new BroadcastReceiver() {
11034                                     @Override
11035                                     public void onReceive(Context context, Intent intent) {
11036                                         final Message msg = mHandler
11037                                                 .obtainMessage(CHECK_PENDING_VERIFICATION);
11038                                         msg.arg1 = verificationId;
11039                                         mHandler.sendMessageDelayed(msg, getVerificationTimeout());
11040                                     }
11041                                 }, null, 0, null, null);
11042 
11043                         /*
11044                          * We don't want the copy to proceed until verification
11045                          * succeeds, so null out this field.
11046                          */
11047                         mArgs = null;
11048                     }
11049                 } else {
11050                     /*
11051                      * No package verification is enabled, so immediately start
11052                      * the remote call to initiate copy using temporary file.
11053                      */
11054                     ret = args.copyApk(mContainerService, true);
11055                 }
11056             }
11057 
11058             mRet = ret;
11059         }
11060 
11061         @Override
handleReturnCode()11062         void handleReturnCode() {
11063             // If mArgs is null, then MCS couldn't be reached. When it
11064             // reconnects, it will try again to install. At that point, this
11065             // will succeed.
11066             if (mArgs != null) {
11067                 processPendingInstall(mArgs, mRet);
11068             }
11069         }
11070 
11071         @Override
handleServiceError()11072         void handleServiceError() {
11073             mArgs = createInstallArgs(this);
11074             mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
11075         }
11076 
isForwardLocked()11077         public boolean isForwardLocked() {
11078             return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
11079         }
11080     }
11081 
11082     /**
11083      * Used during creation of InstallArgs
11084      *
11085      * @param installFlags package installation flags
11086      * @return true if should be installed on external storage
11087      */
installOnExternalAsec(int installFlags)11088     private static boolean installOnExternalAsec(int installFlags) {
11089         if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
11090             return false;
11091         }
11092         if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
11093             return true;
11094         }
11095         return false;
11096     }
11097 
11098     /**
11099      * Used during creation of InstallArgs
11100      *
11101      * @param installFlags package installation flags
11102      * @return true if should be installed as forward locked
11103      */
installForwardLocked(int installFlags)11104     private static boolean installForwardLocked(int installFlags) {
11105         return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
11106     }
11107 
createInstallArgs(InstallParams params)11108     private InstallArgs createInstallArgs(InstallParams params) {
11109         if (params.move != null) {
11110             return new MoveInstallArgs(params);
11111         } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
11112             return new AsecInstallArgs(params);
11113         } else {
11114             return new FileInstallArgs(params);
11115         }
11116     }
11117 
11118     /**
11119      * Create args that describe an existing installed package. Typically used
11120      * when cleaning up old installs, or used as a move source.
11121      */
createInstallArgsForExisting(int installFlags, String codePath, String resourcePath, String[] instructionSets)11122     private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
11123             String resourcePath, String[] instructionSets) {
11124         final boolean isInAsec;
11125         if (installOnExternalAsec(installFlags)) {
11126             /* Apps on SD card are always in ASEC containers. */
11127             isInAsec = true;
11128         } else if (installForwardLocked(installFlags)
11129                 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
11130             /*
11131              * Forward-locked apps are only in ASEC containers if they're the
11132              * new style
11133              */
11134             isInAsec = true;
11135         } else {
11136             isInAsec = false;
11137         }
11138 
11139         if (isInAsec) {
11140             return new AsecInstallArgs(codePath, instructionSets,
11141                     installOnExternalAsec(installFlags), installForwardLocked(installFlags));
11142         } else {
11143             return new FileInstallArgs(codePath, resourcePath, instructionSets);
11144         }
11145     }
11146 
11147     static abstract class InstallArgs {
11148         /** @see InstallParams#origin */
11149         final OriginInfo origin;
11150         /** @see InstallParams#move */
11151         final MoveInfo move;
11152 
11153         final IPackageInstallObserver2 observer;
11154         // Always refers to PackageManager flags only
11155         final int installFlags;
11156         final String installerPackageName;
11157         final String volumeUuid;
11158         final ManifestDigest manifestDigest;
11159         final UserHandle user;
11160         final String abiOverride;
11161         final String[] installGrantPermissions;
11162 
11163         // The list of instruction sets supported by this app. This is currently
11164         // only used during the rmdex() phase to clean up resources. We can get rid of this
11165         // if we move dex files under the common app path.
11166         /* nullable */ String[] instructionSets;
11167 
InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, int installFlags, String installerPackageName, String volumeUuid, ManifestDigest manifestDigest, UserHandle user, String[] instructionSets, String abiOverride, String[] installGrantPermissions)11168         InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
11169                 int installFlags, String installerPackageName, String volumeUuid,
11170                 ManifestDigest manifestDigest, UserHandle user, String[] instructionSets,
11171                 String abiOverride, String[] installGrantPermissions) {
11172             this.origin = origin;
11173             this.move = move;
11174             this.installFlags = installFlags;
11175             this.observer = observer;
11176             this.installerPackageName = installerPackageName;
11177             this.volumeUuid = volumeUuid;
11178             this.manifestDigest = manifestDigest;
11179             this.user = user;
11180             this.instructionSets = instructionSets;
11181             this.abiOverride = abiOverride;
11182             this.installGrantPermissions = installGrantPermissions;
11183         }
11184 
copyApk(IMediaContainerService imcs, boolean temp)11185         abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
doPreInstall(int status)11186         abstract int doPreInstall(int status);
11187 
11188         /**
11189          * Rename package into final resting place. All paths on the given
11190          * scanned package should be updated to reflect the rename.
11191          */
doRename(int status, PackageParser.Package pkg, String oldCodePath)11192         abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
doPostInstall(int status, int uid)11193         abstract int doPostInstall(int status, int uid);
11194 
11195         /** @see PackageSettingBase#codePathString */
getCodePath()11196         abstract String getCodePath();
11197         /** @see PackageSettingBase#resourcePathString */
getResourcePath()11198         abstract String getResourcePath();
11199 
11200         // Need installer lock especially for dex file removal.
cleanUpResourcesLI()11201         abstract void cleanUpResourcesLI();
doPostDeleteLI(boolean delete)11202         abstract boolean doPostDeleteLI(boolean delete);
11203 
11204         /**
11205          * Called before the source arguments are copied. This is used mostly
11206          * for MoveParams when it needs to read the source file to put it in the
11207          * destination.
11208          */
doPreCopy()11209         int doPreCopy() {
11210             return PackageManager.INSTALL_SUCCEEDED;
11211         }
11212 
11213         /**
11214          * Called after the source arguments are copied. This is used mostly for
11215          * MoveParams when it needs to read the source file to put it in the
11216          * destination.
11217          */
doPostCopy(int uid)11218         int doPostCopy(int uid) {
11219             return PackageManager.INSTALL_SUCCEEDED;
11220         }
11221 
isFwdLocked()11222         protected boolean isFwdLocked() {
11223             return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
11224         }
11225 
isExternalAsec()11226         protected boolean isExternalAsec() {
11227             return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
11228         }
11229 
getUser()11230         UserHandle getUser() {
11231             return user;
11232         }
11233     }
11234 
removeDexFiles(List<String> allCodePaths, String[] instructionSets)11235     private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
11236         if (!allCodePaths.isEmpty()) {
11237             if (instructionSets == null) {
11238                 throw new IllegalStateException("instructionSet == null");
11239             }
11240             String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
11241             for (String codePath : allCodePaths) {
11242                 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
11243                     int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet);
11244                     if (retCode < 0) {
11245                         Slog.w(TAG, "Couldn't remove dex file for package: "
11246                                 + " at location " + codePath + ", retcode=" + retCode);
11247                         // we don't consider this to be a failure of the core package deletion
11248                     }
11249                 }
11250             }
11251         }
11252     }
11253 
11254     /**
11255      * Logic to handle installation of non-ASEC applications, including copying
11256      * and renaming logic.
11257      */
11258     class FileInstallArgs extends InstallArgs {
11259         private File codeFile;
11260         private File resourceFile;
11261 
11262         // Example topology:
11263         // /data/app/com.example/base.apk
11264         // /data/app/com.example/split_foo.apk
11265         // /data/app/com.example/lib/arm/libfoo.so
11266         // /data/app/com.example/lib/arm64/libfoo.so
11267         // /data/app/com.example/dalvik/arm/base.apk@classes.dex
11268 
11269         /** New install */
FileInstallArgs(InstallParams params)11270         FileInstallArgs(InstallParams params) {
11271             super(params.origin, params.move, params.observer, params.installFlags,
11272                     params.installerPackageName, params.volumeUuid, params.getManifestDigest(),
11273                     params.getUser(), null /* instruction sets */, params.packageAbiOverride,
11274                     params.grantedRuntimePermissions);
11275             if (isFwdLocked()) {
11276                 throw new IllegalArgumentException("Forward locking only supported in ASEC");
11277             }
11278         }
11279 
11280         /** Existing install */
FileInstallArgs(String codePath, String resourcePath, String[] instructionSets)11281         FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
11282             super(OriginInfo.fromNothing(), null, null, 0, null, null, null, null, instructionSets,
11283                     null, null);
11284             this.codeFile = (codePath != null) ? new File(codePath) : null;
11285             this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
11286         }
11287 
copyApk(IMediaContainerService imcs, boolean temp)11288         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
11289             if (origin.staged) {
11290                 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
11291                 codeFile = origin.file;
11292                 resourceFile = origin.file;
11293                 return PackageManager.INSTALL_SUCCEEDED;
11294             }
11295 
11296             try {
11297                 final File tempDir = mInstallerService.allocateStageDirLegacy(volumeUuid);
11298                 codeFile = tempDir;
11299                 resourceFile = tempDir;
11300             } catch (IOException e) {
11301                 Slog.w(TAG, "Failed to create copy file: " + e);
11302                 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
11303             }
11304 
11305             final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
11306                 @Override
11307                 public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
11308                     if (!FileUtils.isValidExtFilename(name)) {
11309                         throw new IllegalArgumentException("Invalid filename: " + name);
11310                     }
11311                     try {
11312                         final File file = new File(codeFile, name);
11313                         final FileDescriptor fd = Os.open(file.getAbsolutePath(),
11314                                 O_RDWR | O_CREAT, 0644);
11315                         Os.chmod(file.getAbsolutePath(), 0644);
11316                         return new ParcelFileDescriptor(fd);
11317                     } catch (ErrnoException e) {
11318                         throw new RemoteException("Failed to open: " + e.getMessage());
11319                     }
11320                 }
11321             };
11322 
11323             int ret = PackageManager.INSTALL_SUCCEEDED;
11324             ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
11325             if (ret != PackageManager.INSTALL_SUCCEEDED) {
11326                 Slog.e(TAG, "Failed to copy package");
11327                 return ret;
11328             }
11329 
11330             final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
11331             NativeLibraryHelper.Handle handle = null;
11332             try {
11333                 handle = NativeLibraryHelper.Handle.create(codeFile);
11334                 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
11335                         abiOverride);
11336             } catch (IOException e) {
11337                 Slog.e(TAG, "Copying native libraries failed", e);
11338                 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
11339             } finally {
11340                 IoUtils.closeQuietly(handle);
11341             }
11342 
11343             return ret;
11344         }
11345 
doPreInstall(int status)11346         int doPreInstall(int status) {
11347             if (status != PackageManager.INSTALL_SUCCEEDED) {
11348                 cleanUp();
11349             }
11350             return status;
11351         }
11352 
doRename(int status, PackageParser.Package pkg, String oldCodePath)11353         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
11354             if (status != PackageManager.INSTALL_SUCCEEDED) {
11355                 cleanUp();
11356                 return false;
11357             }
11358 
11359             final File targetDir = codeFile.getParentFile();
11360             final File beforeCodeFile = codeFile;
11361             final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
11362 
11363             if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
11364             try {
11365                 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
11366             } catch (ErrnoException e) {
11367                 Slog.w(TAG, "Failed to rename", e);
11368                 return false;
11369             }
11370 
11371             if (!SELinux.restoreconRecursive(afterCodeFile)) {
11372                 Slog.w(TAG, "Failed to restorecon");
11373                 return false;
11374             }
11375 
11376             // Reflect the rename internally
11377             codeFile = afterCodeFile;
11378             resourceFile = afterCodeFile;
11379 
11380             // Reflect the rename in scanned details
11381             pkg.codePath = afterCodeFile.getAbsolutePath();
11382             pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
11383                     pkg.baseCodePath);
11384             pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
11385                     pkg.splitCodePaths);
11386 
11387             // Reflect the rename in app info
11388             pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
11389             pkg.applicationInfo.setCodePath(pkg.codePath);
11390             pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
11391             pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
11392             pkg.applicationInfo.setResourcePath(pkg.codePath);
11393             pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
11394             pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
11395 
11396             return true;
11397         }
11398 
doPostInstall(int status, int uid)11399         int doPostInstall(int status, int uid) {
11400             if (status != PackageManager.INSTALL_SUCCEEDED) {
11401                 cleanUp();
11402             }
11403             return status;
11404         }
11405 
11406         @Override
getCodePath()11407         String getCodePath() {
11408             return (codeFile != null) ? codeFile.getAbsolutePath() : null;
11409         }
11410 
11411         @Override
getResourcePath()11412         String getResourcePath() {
11413             return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
11414         }
11415 
cleanUp()11416         private boolean cleanUp() {
11417             if (codeFile == null || !codeFile.exists()) {
11418                 return false;
11419             }
11420 
11421             if (codeFile.isDirectory()) {
11422                 mInstaller.rmPackageDir(codeFile.getAbsolutePath());
11423             } else {
11424                 codeFile.delete();
11425             }
11426 
11427             if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
11428                 resourceFile.delete();
11429             }
11430 
11431             return true;
11432         }
11433 
cleanUpResourcesLI()11434         void cleanUpResourcesLI() {
11435             // Try enumerating all code paths before deleting
11436             List<String> allCodePaths = Collections.EMPTY_LIST;
11437             if (codeFile != null && codeFile.exists()) {
11438                 try {
11439                     final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
11440                     allCodePaths = pkg.getAllCodePaths();
11441                 } catch (PackageParserException e) {
11442                     // Ignored; we tried our best
11443                 }
11444             }
11445 
11446             cleanUp();
11447             removeDexFiles(allCodePaths, instructionSets);
11448         }
11449 
doPostDeleteLI(boolean delete)11450         boolean doPostDeleteLI(boolean delete) {
11451             // XXX err, shouldn't we respect the delete flag?
11452             cleanUpResourcesLI();
11453             return true;
11454         }
11455     }
11456 
isAsecExternal(String cid)11457     private boolean isAsecExternal(String cid) {
11458         final String asecPath = PackageHelper.getSdFilesystem(cid);
11459         return !asecPath.startsWith(mAsecInternalPath);
11460     }
11461 
maybeThrowExceptionForMultiArchCopy(String message, int copyRet)11462     private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
11463             PackageManagerException {
11464         if (copyRet < 0) {
11465             if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
11466                     copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
11467                 throw new PackageManagerException(copyRet, message);
11468             }
11469         }
11470     }
11471 
11472     /**
11473      * Extract the MountService "container ID" from the full code path of an
11474      * .apk.
11475      */
cidFromCodePath(String fullCodePath)11476     static String cidFromCodePath(String fullCodePath) {
11477         int eidx = fullCodePath.lastIndexOf("/");
11478         String subStr1 = fullCodePath.substring(0, eidx);
11479         int sidx = subStr1.lastIndexOf("/");
11480         return subStr1.substring(sidx+1, eidx);
11481     }
11482 
11483     /**
11484      * Logic to handle installation of ASEC applications, including copying and
11485      * renaming logic.
11486      */
11487     class AsecInstallArgs extends InstallArgs {
11488         static final String RES_FILE_NAME = "pkg.apk";
11489         static final String PUBLIC_RES_FILE_NAME = "res.zip";
11490 
11491         String cid;
11492         String packagePath;
11493         String resourcePath;
11494 
11495         /** New install */
AsecInstallArgs(InstallParams params)11496         AsecInstallArgs(InstallParams params) {
11497             super(params.origin, params.move, params.observer, params.installFlags,
11498                     params.installerPackageName, params.volumeUuid, params.getManifestDigest(),
11499                     params.getUser(), null /* instruction sets */, params.packageAbiOverride,
11500                     params.grantedRuntimePermissions);
11501         }
11502 
11503         /** Existing install */
AsecInstallArgs(String fullCodePath, String[] instructionSets, boolean isExternal, boolean isForwardLocked)11504         AsecInstallArgs(String fullCodePath, String[] instructionSets,
11505                         boolean isExternal, boolean isForwardLocked) {
11506             super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
11507                     | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, null,
11508                     instructionSets, null, null);
11509             // Hackily pretend we're still looking at a full code path
11510             if (!fullCodePath.endsWith(RES_FILE_NAME)) {
11511                 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
11512             }
11513 
11514             // Extract cid from fullCodePath
11515             int eidx = fullCodePath.lastIndexOf("/");
11516             String subStr1 = fullCodePath.substring(0, eidx);
11517             int sidx = subStr1.lastIndexOf("/");
11518             cid = subStr1.substring(sidx+1, eidx);
11519             setMountPath(subStr1);
11520         }
11521 
AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked)11522         AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
11523             super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
11524                     | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, null,
11525                     instructionSets, null, null);
11526             this.cid = cid;
11527             setMountPath(PackageHelper.getSdDir(cid));
11528         }
11529 
createCopyFile()11530         void createCopyFile() {
11531             cid = mInstallerService.allocateExternalStageCidLegacy();
11532         }
11533 
copyApk(IMediaContainerService imcs, boolean temp)11534         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
11535             if (origin.staged) {
11536                 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy");
11537                 cid = origin.cid;
11538                 setMountPath(PackageHelper.getSdDir(cid));
11539                 return PackageManager.INSTALL_SUCCEEDED;
11540             }
11541 
11542             if (temp) {
11543                 createCopyFile();
11544             } else {
11545                 /*
11546                  * Pre-emptively destroy the container since it's destroyed if
11547                  * copying fails due to it existing anyway.
11548                  */
11549                 PackageHelper.destroySdDir(cid);
11550             }
11551 
11552             final String newMountPath = imcs.copyPackageToContainer(
11553                     origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
11554                     isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
11555 
11556             if (newMountPath != null) {
11557                 setMountPath(newMountPath);
11558                 return PackageManager.INSTALL_SUCCEEDED;
11559             } else {
11560                 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
11561             }
11562         }
11563 
11564         @Override
getCodePath()11565         String getCodePath() {
11566             return packagePath;
11567         }
11568 
11569         @Override
getResourcePath()11570         String getResourcePath() {
11571             return resourcePath;
11572         }
11573 
doPreInstall(int status)11574         int doPreInstall(int status) {
11575             if (status != PackageManager.INSTALL_SUCCEEDED) {
11576                 // Destroy container
11577                 PackageHelper.destroySdDir(cid);
11578             } else {
11579                 boolean mounted = PackageHelper.isContainerMounted(cid);
11580                 if (!mounted) {
11581                     String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
11582                             Process.SYSTEM_UID);
11583                     if (newMountPath != null) {
11584                         setMountPath(newMountPath);
11585                     } else {
11586                         return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
11587                     }
11588                 }
11589             }
11590             return status;
11591         }
11592 
doRename(int status, PackageParser.Package pkg, String oldCodePath)11593         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
11594             String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
11595             String newMountPath = null;
11596             if (PackageHelper.isContainerMounted(cid)) {
11597                 // Unmount the container
11598                 if (!PackageHelper.unMountSdDir(cid)) {
11599                     Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
11600                     return false;
11601                 }
11602             }
11603             if (!PackageHelper.renameSdDir(cid, newCacheId)) {
11604                 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
11605                         " which might be stale. Will try to clean up.");
11606                 // Clean up the stale container and proceed to recreate.
11607                 if (!PackageHelper.destroySdDir(newCacheId)) {
11608                     Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
11609                     return false;
11610                 }
11611                 // Successfully cleaned up stale container. Try to rename again.
11612                 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
11613                     Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
11614                             + " inspite of cleaning it up.");
11615                     return false;
11616                 }
11617             }
11618             if (!PackageHelper.isContainerMounted(newCacheId)) {
11619                 Slog.w(TAG, "Mounting container " + newCacheId);
11620                 newMountPath = PackageHelper.mountSdDir(newCacheId,
11621                         getEncryptKey(), Process.SYSTEM_UID);
11622             } else {
11623                 newMountPath = PackageHelper.getSdDir(newCacheId);
11624             }
11625             if (newMountPath == null) {
11626                 Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
11627                 return false;
11628             }
11629             Log.i(TAG, "Succesfully renamed " + cid +
11630                     " to " + newCacheId +
11631                     " at new path: " + newMountPath);
11632             cid = newCacheId;
11633 
11634             final File beforeCodeFile = new File(packagePath);
11635             setMountPath(newMountPath);
11636             final File afterCodeFile = new File(packagePath);
11637 
11638             // Reflect the rename in scanned details
11639             pkg.codePath = afterCodeFile.getAbsolutePath();
11640             pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
11641                     pkg.baseCodePath);
11642             pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
11643                     pkg.splitCodePaths);
11644 
11645             // Reflect the rename in app info
11646             pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
11647             pkg.applicationInfo.setCodePath(pkg.codePath);
11648             pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
11649             pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
11650             pkg.applicationInfo.setResourcePath(pkg.codePath);
11651             pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
11652             pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
11653 
11654             return true;
11655         }
11656 
setMountPath(String mountPath)11657         private void setMountPath(String mountPath) {
11658             final File mountFile = new File(mountPath);
11659 
11660             final File monolithicFile = new File(mountFile, RES_FILE_NAME);
11661             if (monolithicFile.exists()) {
11662                 packagePath = monolithicFile.getAbsolutePath();
11663                 if (isFwdLocked()) {
11664                     resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
11665                 } else {
11666                     resourcePath = packagePath;
11667                 }
11668             } else {
11669                 packagePath = mountFile.getAbsolutePath();
11670                 resourcePath = packagePath;
11671             }
11672         }
11673 
doPostInstall(int status, int uid)11674         int doPostInstall(int status, int uid) {
11675             if (status != PackageManager.INSTALL_SUCCEEDED) {
11676                 cleanUp();
11677             } else {
11678                 final int groupOwner;
11679                 final String protectedFile;
11680                 if (isFwdLocked()) {
11681                     groupOwner = UserHandle.getSharedAppGid(uid);
11682                     protectedFile = RES_FILE_NAME;
11683                 } else {
11684                     groupOwner = -1;
11685                     protectedFile = null;
11686                 }
11687 
11688                 if (uid < Process.FIRST_APPLICATION_UID
11689                         || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
11690                     Slog.e(TAG, "Failed to finalize " + cid);
11691                     PackageHelper.destroySdDir(cid);
11692                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
11693                 }
11694 
11695                 boolean mounted = PackageHelper.isContainerMounted(cid);
11696                 if (!mounted) {
11697                     PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
11698                 }
11699             }
11700             return status;
11701         }
11702 
cleanUp()11703         private void cleanUp() {
11704             if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
11705 
11706             // Destroy secure container
11707             PackageHelper.destroySdDir(cid);
11708         }
11709 
getAllCodePaths()11710         private List<String> getAllCodePaths() {
11711             final File codeFile = new File(getCodePath());
11712             if (codeFile != null && codeFile.exists()) {
11713                 try {
11714                     final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
11715                     return pkg.getAllCodePaths();
11716                 } catch (PackageParserException e) {
11717                     // Ignored; we tried our best
11718                 }
11719             }
11720             return Collections.EMPTY_LIST;
11721         }
11722 
cleanUpResourcesLI()11723         void cleanUpResourcesLI() {
11724             // Enumerate all code paths before deleting
11725             cleanUpResourcesLI(getAllCodePaths());
11726         }
11727 
cleanUpResourcesLI(List<String> allCodePaths)11728         private void cleanUpResourcesLI(List<String> allCodePaths) {
11729             cleanUp();
11730             removeDexFiles(allCodePaths, instructionSets);
11731         }
11732 
getPackageName()11733         String getPackageName() {
11734             return getAsecPackageName(cid);
11735         }
11736 
doPostDeleteLI(boolean delete)11737         boolean doPostDeleteLI(boolean delete) {
11738             if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
11739             final List<String> allCodePaths = getAllCodePaths();
11740             boolean mounted = PackageHelper.isContainerMounted(cid);
11741             if (mounted) {
11742                 // Unmount first
11743                 if (PackageHelper.unMountSdDir(cid)) {
11744                     mounted = false;
11745                 }
11746             }
11747             if (!mounted && delete) {
11748                 cleanUpResourcesLI(allCodePaths);
11749             }
11750             return !mounted;
11751         }
11752 
11753         @Override
doPreCopy()11754         int doPreCopy() {
11755             if (isFwdLocked()) {
11756                 if (!PackageHelper.fixSdPermissions(cid,
11757                         getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) {
11758                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
11759                 }
11760             }
11761 
11762             return PackageManager.INSTALL_SUCCEEDED;
11763         }
11764 
11765         @Override
doPostCopy(int uid)11766         int doPostCopy(int uid) {
11767             if (isFwdLocked()) {
11768                 if (uid < Process.FIRST_APPLICATION_UID
11769                         || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
11770                                 RES_FILE_NAME)) {
11771                     Slog.e(TAG, "Failed to finalize " + cid);
11772                     PackageHelper.destroySdDir(cid);
11773                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
11774                 }
11775             }
11776 
11777             return PackageManager.INSTALL_SUCCEEDED;
11778         }
11779     }
11780 
11781     /**
11782      * Logic to handle movement of existing installed applications.
11783      */
11784     class MoveInstallArgs extends InstallArgs {
11785         private File codeFile;
11786         private File resourceFile;
11787 
11788         /** New install */
MoveInstallArgs(InstallParams params)11789         MoveInstallArgs(InstallParams params) {
11790             super(params.origin, params.move, params.observer, params.installFlags,
11791                     params.installerPackageName, params.volumeUuid, params.getManifestDigest(),
11792                     params.getUser(), null /* instruction sets */, params.packageAbiOverride,
11793                     params.grantedRuntimePermissions);
11794         }
11795 
copyApk(IMediaContainerService imcs, boolean temp)11796         int copyApk(IMediaContainerService imcs, boolean temp) {
11797             if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
11798                     + move.fromUuid + " to " + move.toUuid);
11799             synchronized (mInstaller) {
11800                 if (mInstaller.copyCompleteApp(move.fromUuid, move.toUuid, move.packageName,
11801                         move.dataAppName, move.appId, move.seinfo) != 0) {
11802                     return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
11803                 }
11804             }
11805 
11806             codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
11807             resourceFile = codeFile;
11808             if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
11809 
11810             return PackageManager.INSTALL_SUCCEEDED;
11811         }
11812 
doPreInstall(int status)11813         int doPreInstall(int status) {
11814             if (status != PackageManager.INSTALL_SUCCEEDED) {
11815                 cleanUp(move.toUuid);
11816             }
11817             return status;
11818         }
11819 
doRename(int status, PackageParser.Package pkg, String oldCodePath)11820         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
11821             if (status != PackageManager.INSTALL_SUCCEEDED) {
11822                 cleanUp(move.toUuid);
11823                 return false;
11824             }
11825 
11826             // Reflect the move in app info
11827             pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
11828             pkg.applicationInfo.setCodePath(pkg.codePath);
11829             pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
11830             pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
11831             pkg.applicationInfo.setResourcePath(pkg.codePath);
11832             pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
11833             pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
11834 
11835             return true;
11836         }
11837 
doPostInstall(int status, int uid)11838         int doPostInstall(int status, int uid) {
11839             if (status == PackageManager.INSTALL_SUCCEEDED) {
11840                 cleanUp(move.fromUuid);
11841             } else {
11842                 cleanUp(move.toUuid);
11843             }
11844             return status;
11845         }
11846 
11847         @Override
getCodePath()11848         String getCodePath() {
11849             return (codeFile != null) ? codeFile.getAbsolutePath() : null;
11850         }
11851 
11852         @Override
getResourcePath()11853         String getResourcePath() {
11854             return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
11855         }
11856 
cleanUp(String volumeUuid)11857         private boolean cleanUp(String volumeUuid) {
11858             final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
11859                     move.dataAppName);
11860             Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
11861             synchronized (mInstallLock) {
11862                 // Clean up both app data and code
11863                 removeDataDirsLI(volumeUuid, move.packageName);
11864                 if (codeFile.isDirectory()) {
11865                     mInstaller.rmPackageDir(codeFile.getAbsolutePath());
11866                 } else {
11867                     codeFile.delete();
11868                 }
11869             }
11870             return true;
11871         }
11872 
cleanUpResourcesLI()11873         void cleanUpResourcesLI() {
11874             throw new UnsupportedOperationException();
11875         }
11876 
doPostDeleteLI(boolean delete)11877         boolean doPostDeleteLI(boolean delete) {
11878             throw new UnsupportedOperationException();
11879         }
11880     }
11881 
getAsecPackageName(String packageCid)11882     static String getAsecPackageName(String packageCid) {
11883         int idx = packageCid.lastIndexOf("-");
11884         if (idx == -1) {
11885             return packageCid;
11886         }
11887         return packageCid.substring(0, idx);
11888     }
11889 
11890     // Utility method used to create code paths based on package name and available index.
getNextCodePath(String oldCodePath, String prefix, String suffix)11891     private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
11892         String idxStr = "";
11893         int idx = 1;
11894         // Fall back to default value of idx=1 if prefix is not
11895         // part of oldCodePath
11896         if (oldCodePath != null) {
11897             String subStr = oldCodePath;
11898             // Drop the suffix right away
11899             if (suffix != null && subStr.endsWith(suffix)) {
11900                 subStr = subStr.substring(0, subStr.length() - suffix.length());
11901             }
11902             // If oldCodePath already contains prefix find out the
11903             // ending index to either increment or decrement.
11904             int sidx = subStr.lastIndexOf(prefix);
11905             if (sidx != -1) {
11906                 subStr = subStr.substring(sidx + prefix.length());
11907                 if (subStr != null) {
11908                     if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
11909                         subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
11910                     }
11911                     try {
11912                         idx = Integer.parseInt(subStr);
11913                         if (idx <= 1) {
11914                             idx++;
11915                         } else {
11916                             idx--;
11917                         }
11918                     } catch(NumberFormatException e) {
11919                     }
11920                 }
11921             }
11922         }
11923         idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
11924         return prefix + idxStr;
11925     }
11926 
getNextCodePath(File targetDir, String packageName)11927     private File getNextCodePath(File targetDir, String packageName) {
11928         int suffix = 1;
11929         File result;
11930         do {
11931             result = new File(targetDir, packageName + "-" + suffix);
11932             suffix++;
11933         } while (result.exists());
11934         return result;
11935     }
11936 
11937     // Utility method that returns the relative package path with respect
11938     // to the installation directory. Like say for /data/data/com.test-1.apk
11939     // string com.test-1 is returned.
deriveCodePathName(String codePath)11940     static String deriveCodePathName(String codePath) {
11941         if (codePath == null) {
11942             return null;
11943         }
11944         final File codeFile = new File(codePath);
11945         final String name = codeFile.getName();
11946         if (codeFile.isDirectory()) {
11947             return name;
11948         } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
11949             final int lastDot = name.lastIndexOf('.');
11950             return name.substring(0, lastDot);
11951         } else {
11952             Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
11953             return null;
11954         }
11955     }
11956 
11957     class PackageInstalledInfo {
11958         String name;
11959         int uid;
11960         // The set of users that originally had this package installed.
11961         int[] origUsers;
11962         // The set of users that now have this package installed.
11963         int[] newUsers;
11964         PackageParser.Package pkg;
11965         int returnCode;
11966         String returnMsg;
11967         PackageRemovedInfo removedInfo;
11968 
setError(int code, String msg)11969         public void setError(int code, String msg) {
11970             returnCode = code;
11971             returnMsg = msg;
11972             Slog.w(TAG, msg);
11973         }
11974 
setError(String msg, PackageParserException e)11975         public void setError(String msg, PackageParserException e) {
11976             returnCode = e.error;
11977             returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
11978             Slog.w(TAG, msg, e);
11979         }
11980 
setError(String msg, PackageManagerException e)11981         public void setError(String msg, PackageManagerException e) {
11982             returnCode = e.error;
11983             returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
11984             Slog.w(TAG, msg, e);
11985         }
11986 
11987         // In some error cases we want to convey more info back to the observer
11988         String origPackage;
11989         String origPermission;
11990     }
11991 
11992     /*
11993      * Install a non-existing package.
11994      */
installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, String installerPackageName, String volumeUuid, PackageInstalledInfo res)11995     private void installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags,
11996             UserHandle user, String installerPackageName, String volumeUuid,
11997             PackageInstalledInfo res) {
11998         // Remember this for later, in case we need to rollback this install
11999         String pkgName = pkg.packageName;
12000 
12001         if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
12002         final boolean dataDirExists = Environment
12003                 .getDataUserPackageDirectory(volumeUuid, UserHandle.USER_OWNER, pkgName).exists();
12004         synchronized(mPackages) {
12005             if (mSettings.mRenamedPackages.containsKey(pkgName)) {
12006                 // A package with the same name is already installed, though
12007                 // it has been renamed to an older name.  The package we
12008                 // are trying to install should be installed as an update to
12009                 // the existing one, but that has not been requested, so bail.
12010                 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
12011                         + " without first uninstalling package running as "
12012                         + mSettings.mRenamedPackages.get(pkgName));
12013                 return;
12014             }
12015             if (mPackages.containsKey(pkgName)) {
12016                 // Don't allow installation over an existing package with the same name.
12017                 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
12018                         + " without first uninstalling.");
12019                 return;
12020             }
12021         }
12022 
12023         try {
12024             PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanFlags,
12025                     System.currentTimeMillis(), user);
12026 
12027             updateSettingsLI(newPackage, installerPackageName, volumeUuid, null, null, res, user);
12028             // delete the partially installed application. the data directory will have to be
12029             // restored if it was already existing
12030             if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
12031                 // remove package from internal structures.  Note that we want deletePackageX to
12032                 // delete the package data and cache directories that it created in
12033                 // scanPackageLocked, unless those directories existed before we even tried to
12034                 // install.
12035                 deletePackageLI(pkgName, UserHandle.ALL, false, null, null,
12036                         dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0,
12037                                 res.removedInfo, true);
12038             }
12039 
12040         } catch (PackageManagerException e) {
12041             res.setError("Package couldn't be installed in " + pkg.codePath, e);
12042         }
12043     }
12044 
shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags)12045     private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
12046         // Can't rotate keys during boot or if sharedUser.
12047         if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
12048                 || !oldPs.keySetData.isUsingUpgradeKeySets()) {
12049             return false;
12050         }
12051         // app is using upgradeKeySets; make sure all are valid
12052         KeySetManagerService ksms = mSettings.mKeySetManagerService;
12053         long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
12054         for (int i = 0; i < upgradeKeySets.length; i++) {
12055             if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
12056                 Slog.wtf(TAG, "Package "
12057                          + (oldPs.name != null ? oldPs.name : "<null>")
12058                          + " contains upgrade-key-set reference to unknown key-set: "
12059                          + upgradeKeySets[i]
12060                          + " reverting to signatures check.");
12061                 return false;
12062             }
12063         }
12064         return true;
12065     }
12066 
checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg)12067     private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
12068         // Upgrade keysets are being used.  Determine if new package has a superset of the
12069         // required keys.
12070         long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
12071         KeySetManagerService ksms = mSettings.mKeySetManagerService;
12072         for (int i = 0; i < upgradeKeySets.length; i++) {
12073             Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
12074             if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
12075                 return true;
12076             }
12077         }
12078         return false;
12079     }
12080 
replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, String installerPackageName, String volumeUuid, PackageInstalledInfo res)12081     private void replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags,
12082             UserHandle user, String installerPackageName, String volumeUuid,
12083             PackageInstalledInfo res) {
12084         final PackageParser.Package oldPackage;
12085         final String pkgName = pkg.packageName;
12086         final int[] allUsers;
12087         final boolean[] perUserInstalled;
12088 
12089         // First find the old package info and check signatures
12090         synchronized(mPackages) {
12091             oldPackage = mPackages.get(pkgName);
12092             if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
12093             final PackageSetting ps = mSettings.mPackages.get(pkgName);
12094             if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
12095                 if(!checkUpgradeKeySetLP(ps, pkg)) {
12096                     res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
12097                             "New package not signed by keys specified by upgrade-keysets: "
12098                             + pkgName);
12099                     return;
12100                 }
12101             } else {
12102                 // default to original signature matching
12103                 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
12104                     != PackageManager.SIGNATURE_MATCH) {
12105                     res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
12106                             "New package has a different signature: " + pkgName);
12107                     return;
12108                 }
12109             }
12110 
12111             // In case of rollback, remember per-user/profile install state
12112             allUsers = sUserManager.getUserIds();
12113             perUserInstalled = new boolean[allUsers.length];
12114             for (int i = 0; i < allUsers.length; i++) {
12115                 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
12116             }
12117         }
12118 
12119         boolean sysPkg = (isSystemApp(oldPackage));
12120         if (sysPkg) {
12121             replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
12122                     user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res);
12123         } else {
12124             replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
12125                     user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res);
12126         }
12127     }
12128 
replaceNonSystemPackageLI(PackageParser.Package deletedPackage, PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, int[] allUsers, boolean[] perUserInstalled, String installerPackageName, String volumeUuid, PackageInstalledInfo res)12129     private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage,
12130             PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
12131             int[] allUsers, boolean[] perUserInstalled, String installerPackageName,
12132             String volumeUuid, PackageInstalledInfo res) {
12133         String pkgName = deletedPackage.packageName;
12134         boolean deletedPkg = true;
12135         boolean updatedSettings = false;
12136 
12137         if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
12138                 + deletedPackage);
12139         long origUpdateTime;
12140         if (pkg.mExtras != null) {
12141             origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime;
12142         } else {
12143             origUpdateTime = 0;
12144         }
12145 
12146         // First delete the existing package while retaining the data directory
12147         if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA,
12148                 res.removedInfo, true)) {
12149             // If the existing package wasn't successfully deleted
12150             res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
12151             deletedPkg = false;
12152         } else {
12153             // Successfully deleted the old package; proceed with replace.
12154 
12155             // If deleted package lived in a container, give users a chance to
12156             // relinquish resources before killing.
12157             if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
12158                 if (DEBUG_INSTALL) {
12159                     Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
12160                 }
12161                 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
12162                 final ArrayList<String> pkgList = new ArrayList<String>(1);
12163                 pkgList.add(deletedPackage.applicationInfo.packageName);
12164                 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
12165             }
12166 
12167             deleteCodeCacheDirsLI(pkg.volumeUuid, pkgName);
12168             try {
12169                 final PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags,
12170                         scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
12171                 updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers,
12172                         perUserInstalled, res, user);
12173                 updatedSettings = true;
12174             } catch (PackageManagerException e) {
12175                 res.setError("Package couldn't be installed in " + pkg.codePath, e);
12176             }
12177         }
12178 
12179         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
12180             // remove package from internal structures.  Note that we want deletePackageX to
12181             // delete the package data and cache directories that it created in
12182             // scanPackageLocked, unless those directories existed before we even tried to
12183             // install.
12184             if(updatedSettings) {
12185                 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
12186                 deletePackageLI(
12187                         pkgName, null, true, allUsers, perUserInstalled,
12188                         PackageManager.DELETE_KEEP_DATA,
12189                                 res.removedInfo, true);
12190             }
12191             // Since we failed to install the new package we need to restore the old
12192             // package that we deleted.
12193             if (deletedPkg) {
12194                 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
12195                 File restoreFile = new File(deletedPackage.codePath);
12196                 // Parse old package
12197                 boolean oldExternal = isExternal(deletedPackage);
12198                 int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
12199                         (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
12200                         (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
12201                 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
12202                 try {
12203                     scanPackageLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, null);
12204                 } catch (PackageManagerException e) {
12205                     Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
12206                             + e.getMessage());
12207                     return;
12208                 }
12209                 // Restore of old package succeeded. Update permissions.
12210                 // writer
12211                 synchronized (mPackages) {
12212                     updatePermissionsLPw(deletedPackage.packageName, deletedPackage,
12213                             UPDATE_PERMISSIONS_ALL);
12214                     // can downgrade to reader
12215                     mSettings.writeLPr();
12216                 }
12217                 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
12218             }
12219         }
12220     }
12221 
replaceSystemPackageLI(PackageParser.Package deletedPackage, PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, int[] allUsers, boolean[] perUserInstalled, String installerPackageName, String volumeUuid, PackageInstalledInfo res)12222     private void replaceSystemPackageLI(PackageParser.Package deletedPackage,
12223             PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
12224             int[] allUsers, boolean[] perUserInstalled, String installerPackageName,
12225             String volumeUuid, PackageInstalledInfo res) {
12226         if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
12227                 + ", old=" + deletedPackage);
12228         boolean disabledSystem = false;
12229         boolean updatedSettings = false;
12230         parseFlags |= PackageParser.PARSE_IS_SYSTEM;
12231         if ((deletedPackage.applicationInfo.privateFlags&ApplicationInfo.PRIVATE_FLAG_PRIVILEGED)
12232                 != 0) {
12233             parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
12234         }
12235         String packageName = deletedPackage.packageName;
12236         if (packageName == null) {
12237             res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
12238                     "Attempt to delete null packageName.");
12239             return;
12240         }
12241         PackageParser.Package oldPkg;
12242         PackageSetting oldPkgSetting;
12243         // reader
12244         synchronized (mPackages) {
12245             oldPkg = mPackages.get(packageName);
12246             oldPkgSetting = mSettings.mPackages.get(packageName);
12247             if((oldPkg == null) || (oldPkg.applicationInfo == null) ||
12248                     (oldPkgSetting == null)) {
12249                 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
12250                         "Couldn't find package:" + packageName + " information");
12251                 return;
12252             }
12253         }
12254 
12255         killApplication(packageName, oldPkg.applicationInfo.uid, "replace sys pkg");
12256 
12257         res.removedInfo.uid = oldPkg.applicationInfo.uid;
12258         res.removedInfo.removedPackage = packageName;
12259         // Remove existing system package
12260         removePackageLI(oldPkgSetting, true);
12261         // writer
12262         synchronized (mPackages) {
12263             disabledSystem = mSettings.disableSystemPackageLPw(packageName);
12264             if (!disabledSystem && deletedPackage != null) {
12265                 // We didn't need to disable the .apk as a current system package,
12266                 // which means we are replacing another update that is already
12267                 // installed.  We need to make sure to delete the older one's .apk.
12268                 res.removedInfo.args = createInstallArgsForExisting(0,
12269                         deletedPackage.applicationInfo.getCodePath(),
12270                         deletedPackage.applicationInfo.getResourcePath(),
12271                         getAppDexInstructionSets(deletedPackage.applicationInfo));
12272             } else {
12273                 res.removedInfo.args = null;
12274             }
12275         }
12276 
12277         // Successfully disabled the old package. Now proceed with re-installation
12278         deleteCodeCacheDirsLI(pkg.volumeUuid, packageName);
12279 
12280         res.returnCode = PackageManager.INSTALL_SUCCEEDED;
12281         pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
12282 
12283         PackageParser.Package newPackage = null;
12284         try {
12285             newPackage = scanPackageLI(pkg, parseFlags, scanFlags, 0, user);
12286             if (newPackage.mExtras != null) {
12287                 final PackageSetting newPkgSetting = (PackageSetting) newPackage.mExtras;
12288                 newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime;
12289                 newPkgSetting.lastUpdateTime = System.currentTimeMillis();
12290 
12291                 // is the update attempting to change shared user? that isn't going to work...
12292                 if (oldPkgSetting.sharedUser != newPkgSetting.sharedUser) {
12293                     res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
12294                             "Forbidding shared user change from " + oldPkgSetting.sharedUser
12295                             + " to " + newPkgSetting.sharedUser);
12296                     updatedSettings = true;
12297                 }
12298             }
12299 
12300             if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
12301                 updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers,
12302                         perUserInstalled, res, user);
12303                 updatedSettings = true;
12304             }
12305 
12306         } catch (PackageManagerException e) {
12307             res.setError("Package couldn't be installed in " + pkg.codePath, e);
12308         }
12309 
12310         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
12311             // Re installation failed. Restore old information
12312             // Remove new pkg information
12313             if (newPackage != null) {
12314                 removeInstalledPackageLI(newPackage, true);
12315             }
12316             // Add back the old system package
12317             try {
12318                 scanPackageLI(oldPkg, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
12319             } catch (PackageManagerException e) {
12320                 Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
12321             }
12322             // Restore the old system information in Settings
12323             synchronized (mPackages) {
12324                 if (disabledSystem) {
12325                     mSettings.enableSystemPackageLPw(packageName);
12326                 }
12327                 if (updatedSettings) {
12328                     mSettings.setInstallerPackageName(packageName,
12329                             oldPkgSetting.installerPackageName);
12330                 }
12331                 mSettings.writeLPr();
12332             }
12333         }
12334     }
12335 
revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds)12336     private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
12337         // Collect all used permissions in the UID
12338         ArraySet<String> usedPermissions = new ArraySet<>();
12339         final int packageCount = su.packages.size();
12340         for (int i = 0; i < packageCount; i++) {
12341             PackageSetting ps = su.packages.valueAt(i);
12342             if (ps.pkg == null) {
12343                 continue;
12344             }
12345             final int requestedPermCount = ps.pkg.requestedPermissions.size();
12346             for (int j = 0; j < requestedPermCount; j++) {
12347                 String permission = ps.pkg.requestedPermissions.get(j);
12348                 BasePermission bp = mSettings.mPermissions.get(permission);
12349                 if (bp != null) {
12350                     usedPermissions.add(permission);
12351                 }
12352             }
12353         }
12354 
12355         PermissionsState permissionsState = su.getPermissionsState();
12356         // Prune install permissions
12357         List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
12358         final int installPermCount = installPermStates.size();
12359         for (int i = installPermCount - 1; i >= 0;  i--) {
12360             PermissionState permissionState = installPermStates.get(i);
12361             if (!usedPermissions.contains(permissionState.getName())) {
12362                 BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
12363                 if (bp != null) {
12364                     permissionsState.revokeInstallPermission(bp);
12365                     permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
12366                             PackageManager.MASK_PERMISSION_FLAGS, 0);
12367                 }
12368             }
12369         }
12370 
12371         int[] runtimePermissionChangedUserIds = EmptyArray.INT;
12372 
12373         // Prune runtime permissions
12374         for (int userId : allUserIds) {
12375             List<PermissionState> runtimePermStates = permissionsState
12376                     .getRuntimePermissionStates(userId);
12377             final int runtimePermCount = runtimePermStates.size();
12378             for (int i = runtimePermCount - 1; i >= 0; i--) {
12379                 PermissionState permissionState = runtimePermStates.get(i);
12380                 if (!usedPermissions.contains(permissionState.getName())) {
12381                     BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
12382                     if (bp != null) {
12383                         permissionsState.revokeRuntimePermission(bp, userId);
12384                         permissionsState.updatePermissionFlags(bp, userId,
12385                                 PackageManager.MASK_PERMISSION_FLAGS, 0);
12386                         runtimePermissionChangedUserIds = ArrayUtils.appendInt(
12387                                 runtimePermissionChangedUserIds, userId);
12388                     }
12389                 }
12390             }
12391         }
12392 
12393         return runtimePermissionChangedUserIds;
12394     }
12395 
updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, String volumeUuid, int[] allUsers, boolean[] perUserInstalled, PackageInstalledInfo res, UserHandle user)12396     private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
12397             String volumeUuid, int[] allUsers, boolean[] perUserInstalled, PackageInstalledInfo res,
12398             UserHandle user) {
12399         String pkgName = newPackage.packageName;
12400         synchronized (mPackages) {
12401             //write settings. the installStatus will be incomplete at this stage.
12402             //note that the new package setting would have already been
12403             //added to mPackages. It hasn't been persisted yet.
12404             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
12405             mSettings.writeLPr();
12406         }
12407 
12408         if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
12409 
12410         synchronized (mPackages) {
12411             updatePermissionsLPw(newPackage.packageName, newPackage,
12412                     UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
12413                             ? UPDATE_PERMISSIONS_ALL : 0));
12414             // For system-bundled packages, we assume that installing an upgraded version
12415             // of the package implies that the user actually wants to run that new code,
12416             // so we enable the package.
12417             PackageSetting ps = mSettings.mPackages.get(pkgName);
12418             if (ps != null) {
12419                 if (isSystemApp(newPackage)) {
12420                     // NB: implicit assumption that system package upgrades apply to all users
12421                     if (DEBUG_INSTALL) {
12422                         Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
12423                     }
12424                     if (res.origUsers != null) {
12425                         for (int userHandle : res.origUsers) {
12426                             ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
12427                                     userHandle, installerPackageName);
12428                         }
12429                     }
12430                     // Also convey the prior install/uninstall state
12431                     if (allUsers != null && perUserInstalled != null) {
12432                         for (int i = 0; i < allUsers.length; i++) {
12433                             if (DEBUG_INSTALL) {
12434                                 Slog.d(TAG, "    user " + allUsers[i]
12435                                         + " => " + perUserInstalled[i]);
12436                             }
12437                             ps.setInstalled(perUserInstalled[i], allUsers[i]);
12438                         }
12439                         // these install state changes will be persisted in the
12440                         // upcoming call to mSettings.writeLPr().
12441                     }
12442                 }
12443                 // It's implied that when a user requests installation, they want the app to be
12444                 // installed and enabled.
12445                 int userId = user.getIdentifier();
12446                 if (userId != UserHandle.USER_ALL) {
12447                     ps.setInstalled(true, userId);
12448                     ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
12449                 }
12450             }
12451             res.name = pkgName;
12452             res.uid = newPackage.applicationInfo.uid;
12453             res.pkg = newPackage;
12454             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
12455             mSettings.setInstallerPackageName(pkgName, installerPackageName);
12456             res.returnCode = PackageManager.INSTALL_SUCCEEDED;
12457             //to update install status
12458             mSettings.writeLPr();
12459         }
12460     }
12461 
installPackageLI(InstallArgs args, PackageInstalledInfo res)12462     private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
12463         final int installFlags = args.installFlags;
12464         final String installerPackageName = args.installerPackageName;
12465         final String volumeUuid = args.volumeUuid;
12466         final File tmpPackageFile = new File(args.getCodePath());
12467         final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
12468         final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
12469                 || (args.volumeUuid != null));
12470         boolean replace = false;
12471         int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
12472         if (args.move != null) {
12473             // moving a complete application; perfom an initial scan on the new install location
12474             scanFlags |= SCAN_INITIAL;
12475         }
12476         // Result object to be returned
12477         res.returnCode = PackageManager.INSTALL_SUCCEEDED;
12478 
12479         if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
12480         // Retrieve PackageSettings and parse package
12481         final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
12482                 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
12483                 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
12484         PackageParser pp = new PackageParser();
12485         pp.setSeparateProcesses(mSeparateProcesses);
12486         pp.setDisplayMetrics(mMetrics);
12487 
12488         final PackageParser.Package pkg;
12489         try {
12490             pkg = pp.parsePackage(tmpPackageFile, parseFlags);
12491         } catch (PackageParserException e) {
12492             res.setError("Failed parse during installPackageLI", e);
12493             return;
12494         }
12495 
12496         // Mark that we have an install time CPU ABI override.
12497         pkg.cpuAbiOverride = args.abiOverride;
12498 
12499         String pkgName = res.name = pkg.packageName;
12500         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
12501             if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
12502                 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
12503                 return;
12504             }
12505         }
12506 
12507         try {
12508             pp.collectCertificates(pkg, parseFlags);
12509             pp.collectManifestDigest(pkg);
12510         } catch (PackageParserException e) {
12511             res.setError("Failed collect during installPackageLI", e);
12512             return;
12513         }
12514 
12515         /* If the installer passed in a manifest digest, compare it now. */
12516         if (args.manifestDigest != null) {
12517             if (DEBUG_INSTALL) {
12518                 final String parsedManifest = pkg.manifestDigest == null ? "null"
12519                         : pkg.manifestDigest.toString();
12520                 Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. "
12521                         + parsedManifest);
12522             }
12523 
12524             if (!args.manifestDigest.equals(pkg.manifestDigest)) {
12525                 res.setError(INSTALL_FAILED_PACKAGE_CHANGED, "Manifest digest changed");
12526                 return;
12527             }
12528         } else if (DEBUG_INSTALL) {
12529             final String parsedManifest = pkg.manifestDigest == null
12530                     ? "null" : pkg.manifestDigest.toString();
12531             Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest);
12532         }
12533 
12534         // Get rid of all references to package scan path via parser.
12535         pp = null;
12536         String oldCodePath = null;
12537         boolean systemApp = false;
12538         synchronized (mPackages) {
12539             // Check if installing already existing package
12540             if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
12541                 String oldName = mSettings.mRenamedPackages.get(pkgName);
12542                 if (pkg.mOriginalPackages != null
12543                         && pkg.mOriginalPackages.contains(oldName)
12544                         && mPackages.containsKey(oldName)) {
12545                     // This package is derived from an original package,
12546                     // and this device has been updating from that original
12547                     // name.  We must continue using the original name, so
12548                     // rename the new package here.
12549                     pkg.setPackageName(oldName);
12550                     pkgName = pkg.packageName;
12551                     replace = true;
12552                     if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
12553                             + oldName + " pkgName=" + pkgName);
12554                 } else if (mPackages.containsKey(pkgName)) {
12555                     // This package, under its official name, already exists
12556                     // on the device; we should replace it.
12557                     replace = true;
12558                     if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
12559                 }
12560 
12561                 // Prevent apps opting out from runtime permissions
12562                 if (replace) {
12563                     PackageParser.Package oldPackage = mPackages.get(pkgName);
12564                     final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
12565                     final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
12566                     if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
12567                             && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
12568                         res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
12569                                 "Package " + pkg.packageName + " new target SDK " + newTargetSdk
12570                                         + " doesn't support runtime permissions but the old"
12571                                         + " target SDK " + oldTargetSdk + " does.");
12572                         return;
12573                     }
12574                 }
12575             }
12576 
12577             PackageSetting ps = mSettings.mPackages.get(pkgName);
12578             if (ps != null) {
12579                 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
12580 
12581                 // Quick sanity check that we're signed correctly if updating;
12582                 // we'll check this again later when scanning, but we want to
12583                 // bail early here before tripping over redefined permissions.
12584                 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
12585                     if (!checkUpgradeKeySetLP(ps, pkg)) {
12586                         res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
12587                                 + pkg.packageName + " upgrade keys do not match the "
12588                                 + "previously installed version");
12589                         return;
12590                     }
12591                 } else {
12592                     try {
12593                         verifySignaturesLP(ps, pkg);
12594                     } catch (PackageManagerException e) {
12595                         res.setError(e.error, e.getMessage());
12596                         return;
12597                     }
12598                 }
12599 
12600                 oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
12601                 if (ps.pkg != null && ps.pkg.applicationInfo != null) {
12602                     systemApp = (ps.pkg.applicationInfo.flags &
12603                             ApplicationInfo.FLAG_SYSTEM) != 0;
12604                 }
12605                 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
12606             }
12607 
12608             // Check whether the newly-scanned package wants to define an already-defined perm
12609             int N = pkg.permissions.size();
12610             for (int i = N-1; i >= 0; i--) {
12611                 PackageParser.Permission perm = pkg.permissions.get(i);
12612                 BasePermission bp = mSettings.mPermissions.get(perm.info.name);
12613                 if (bp != null) {
12614                     // If the defining package is signed with our cert, it's okay.  This
12615                     // also includes the "updating the same package" case, of course.
12616                     // "updating same package" could also involve key-rotation.
12617                     final boolean sigsOk;
12618                     if (bp.sourcePackage.equals(pkg.packageName)
12619                             && (bp.packageSetting instanceof PackageSetting)
12620                             && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting,
12621                                     scanFlags))) {
12622                         sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
12623                     } else {
12624                         sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
12625                                 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
12626                     }
12627                     if (!sigsOk) {
12628                         // If the owning package is the system itself, we log but allow
12629                         // install to proceed; we fail the install on all other permission
12630                         // redefinitions.
12631                         if (!bp.sourcePackage.equals("android")) {
12632                             res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
12633                                     + pkg.packageName + " attempting to redeclare permission "
12634                                     + perm.info.name + " already owned by " + bp.sourcePackage);
12635                             res.origPermission = perm.info.name;
12636                             res.origPackage = bp.sourcePackage;
12637                             return;
12638                         } else {
12639                             Slog.w(TAG, "Package " + pkg.packageName
12640                                     + " attempting to redeclare system permission "
12641                                     + perm.info.name + "; ignoring new declaration");
12642                             pkg.permissions.remove(i);
12643                         }
12644                     }
12645                 }
12646             }
12647 
12648         }
12649 
12650         if (systemApp && onExternal) {
12651             // Disable updates to system apps on sdcard
12652             res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
12653                     "Cannot install updates to system apps on sdcard");
12654             return;
12655         }
12656 
12657         if (args.move != null) {
12658             // We did an in-place move, so dex is ready to roll
12659             scanFlags |= SCAN_NO_DEX;
12660             scanFlags |= SCAN_MOVE;
12661 
12662             synchronized (mPackages) {
12663                 final PackageSetting ps = mSettings.mPackages.get(pkgName);
12664                 if (ps == null) {
12665                     res.setError(INSTALL_FAILED_INTERNAL_ERROR,
12666                             "Missing settings for moved package " + pkgName);
12667                 }
12668 
12669                 // We moved the entire application as-is, so bring over the
12670                 // previously derived ABI information.
12671                 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
12672                 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
12673             }
12674 
12675         } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
12676             // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
12677             scanFlags |= SCAN_NO_DEX;
12678 
12679             try {
12680                 derivePackageAbi(pkg, new File(pkg.codePath), args.abiOverride,
12681                         true /* extract libs */);
12682             } catch (PackageManagerException pme) {
12683                 Slog.e(TAG, "Error deriving application ABI", pme);
12684                 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
12685                 return;
12686             }
12687 
12688             // Run dexopt before old package gets removed, to minimize time when app is unavailable
12689             int result = mPackageDexOptimizer
12690                     .performDexOpt(pkg, null /* instruction sets */, false /* forceDex */,
12691                             false /* defer */, false /* inclDependencies */,
12692                             true /* boot complete */);
12693             if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
12694                 res.setError(INSTALL_FAILED_DEXOPT, "Dexopt failed for " + pkg.codePath);
12695                 return;
12696             }
12697         }
12698 
12699         if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
12700             res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
12701             return;
12702         }
12703 
12704         startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
12705 
12706         if (replace) {
12707             replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
12708                     installerPackageName, volumeUuid, res);
12709         } else {
12710             installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
12711                     args.user, installerPackageName, volumeUuid, res);
12712         }
12713         synchronized (mPackages) {
12714             final PackageSetting ps = mSettings.mPackages.get(pkgName);
12715             if (ps != null) {
12716                 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
12717             }
12718         }
12719     }
12720 
startIntentFilterVerifications(int userId, boolean replacing, PackageParser.Package pkg)12721     private void startIntentFilterVerifications(int userId, boolean replacing,
12722             PackageParser.Package pkg) {
12723         if (mIntentFilterVerifierComponent == null) {
12724             Slog.w(TAG, "No IntentFilter verification will not be done as "
12725                     + "there is no IntentFilterVerifier available!");
12726             return;
12727         }
12728 
12729         final int verifierUid = getPackageUid(
12730                 mIntentFilterVerifierComponent.getPackageName(),
12731                 (userId == UserHandle.USER_ALL) ? UserHandle.USER_OWNER : userId);
12732 
12733         mHandler.removeMessages(START_INTENT_FILTER_VERIFICATIONS);
12734         final Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
12735         msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
12736         mHandler.sendMessage(msg);
12737     }
12738 
verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing, PackageParser.Package pkg)12739     private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
12740             PackageParser.Package pkg) {
12741         int size = pkg.activities.size();
12742         if (size == 0) {
12743             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
12744                     "No activity, so no need to verify any IntentFilter!");
12745             return;
12746         }
12747 
12748         final boolean hasDomainURLs = hasDomainURLs(pkg);
12749         if (!hasDomainURLs) {
12750             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
12751                     "No domain URLs, so no need to verify any IntentFilter!");
12752             return;
12753         }
12754 
12755         if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
12756                 + " if any IntentFilter from the " + size
12757                 + " Activities needs verification ...");
12758 
12759         int count = 0;
12760         final String packageName = pkg.packageName;
12761 
12762         synchronized (mPackages) {
12763             // If this is a new install and we see that we've already run verification for this
12764             // package, we have nothing to do: it means the state was restored from backup.
12765             if (!replacing) {
12766                 IntentFilterVerificationInfo ivi =
12767                         mSettings.getIntentFilterVerificationLPr(packageName);
12768                 if (ivi != null) {
12769                     if (DEBUG_DOMAIN_VERIFICATION) {
12770                         Slog.i(TAG, "Package " + packageName+ " already verified: status="
12771                                 + ivi.getStatusString());
12772                     }
12773                     return;
12774                 }
12775             }
12776 
12777             // If any filters need to be verified, then all need to be.
12778             boolean needToVerify = false;
12779             for (PackageParser.Activity a : pkg.activities) {
12780                 for (ActivityIntentInfo filter : a.intents) {
12781                     if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
12782                         if (DEBUG_DOMAIN_VERIFICATION) {
12783                             Slog.d(TAG, "Intent filter needs verification, so processing all filters");
12784                         }
12785                         needToVerify = true;
12786                         break;
12787                     }
12788                 }
12789             }
12790 
12791             if (needToVerify) {
12792                 final int verificationId = mIntentFilterVerificationToken++;
12793                 for (PackageParser.Activity a : pkg.activities) {
12794                     for (ActivityIntentInfo filter : a.intents) {
12795                         if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
12796                             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
12797                                     "Verification needed for IntentFilter:" + filter.toString());
12798                             mIntentFilterVerifier.addOneIntentFilterVerification(
12799                                     verifierUid, userId, verificationId, filter, packageName);
12800                             count++;
12801                         }
12802                     }
12803                 }
12804             }
12805         }
12806 
12807         if (count > 0) {
12808             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
12809                     + " IntentFilter verification" + (count > 1 ? "s" : "")
12810                     +  " for userId:" + userId);
12811             mIntentFilterVerifier.startVerifications(userId);
12812         } else {
12813             if (DEBUG_DOMAIN_VERIFICATION) {
12814                 Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
12815             }
12816         }
12817     }
12818 
needsNetworkVerificationLPr(ActivityIntentInfo filter)12819     private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
12820         final ComponentName cn  = filter.activity.getComponentName();
12821         final String packageName = cn.getPackageName();
12822 
12823         IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
12824                 packageName);
12825         if (ivi == null) {
12826             return true;
12827         }
12828         int status = ivi.getStatus();
12829         switch (status) {
12830             case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
12831             case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
12832                 return true;
12833 
12834             default:
12835                 // Nothing to do
12836                 return false;
12837         }
12838     }
12839 
isMultiArch(PackageSetting ps)12840     private static boolean isMultiArch(PackageSetting ps) {
12841         return (ps.pkgFlags & ApplicationInfo.FLAG_MULTIARCH) != 0;
12842     }
12843 
isMultiArch(ApplicationInfo info)12844     private static boolean isMultiArch(ApplicationInfo info) {
12845         return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
12846     }
12847 
isExternal(PackageParser.Package pkg)12848     private static boolean isExternal(PackageParser.Package pkg) {
12849         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
12850     }
12851 
isExternal(PackageSetting ps)12852     private static boolean isExternal(PackageSetting ps) {
12853         return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
12854     }
12855 
isExternal(ApplicationInfo info)12856     private static boolean isExternal(ApplicationInfo info) {
12857         return (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
12858     }
12859 
isSystemApp(PackageParser.Package pkg)12860     private static boolean isSystemApp(PackageParser.Package pkg) {
12861         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12862     }
12863 
isPrivilegedApp(PackageParser.Package pkg)12864     private static boolean isPrivilegedApp(PackageParser.Package pkg) {
12865         return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
12866     }
12867 
hasDomainURLs(PackageParser.Package pkg)12868     private static boolean hasDomainURLs(PackageParser.Package pkg) {
12869         return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
12870     }
12871 
isSystemApp(PackageSetting ps)12872     private static boolean isSystemApp(PackageSetting ps) {
12873         return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
12874     }
12875 
isUpdatedSystemApp(PackageSetting ps)12876     private static boolean isUpdatedSystemApp(PackageSetting ps) {
12877         return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
12878     }
12879 
packageFlagsToInstallFlags(PackageSetting ps)12880     private int packageFlagsToInstallFlags(PackageSetting ps) {
12881         int installFlags = 0;
12882         if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
12883             // This existing package was an external ASEC install when we have
12884             // the external flag without a UUID
12885             installFlags |= PackageManager.INSTALL_EXTERNAL;
12886         }
12887         if (ps.isForwardLocked()) {
12888             installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
12889         }
12890         return installFlags;
12891     }
12892 
getVolumeUuidForPackage(PackageParser.Package pkg)12893     private String getVolumeUuidForPackage(PackageParser.Package pkg) {
12894         if (isExternal(pkg)) {
12895             if (TextUtils.isEmpty(pkg.volumeUuid)) {
12896                 return StorageManager.UUID_PRIMARY_PHYSICAL;
12897             } else {
12898                 return pkg.volumeUuid;
12899             }
12900         } else {
12901             return StorageManager.UUID_PRIVATE_INTERNAL;
12902         }
12903     }
12904 
getSettingsVersionForPackage(PackageParser.Package pkg)12905     private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
12906         if (isExternal(pkg)) {
12907             if (TextUtils.isEmpty(pkg.volumeUuid)) {
12908                 return mSettings.getExternalVersion();
12909             } else {
12910                 return mSettings.findOrCreateVersion(pkg.volumeUuid);
12911             }
12912         } else {
12913             return mSettings.getInternalVersion();
12914         }
12915     }
12916 
deleteTempPackageFiles()12917     private void deleteTempPackageFiles() {
12918         final FilenameFilter filter = new FilenameFilter() {
12919             public boolean accept(File dir, String name) {
12920                 return name.startsWith("vmdl") && name.endsWith(".tmp");
12921             }
12922         };
12923         for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
12924             file.delete();
12925         }
12926     }
12927 
12928     @Override
deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId, int flags)12929     public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId,
12930             int flags) {
12931         deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId,
12932                 flags);
12933     }
12934 
12935     @Override
deletePackage(final String packageName, final IPackageDeleteObserver2 observer, final int userId, final int flags)12936     public void deletePackage(final String packageName,
12937             final IPackageDeleteObserver2 observer, final int userId, final int flags) {
12938         mContext.enforceCallingOrSelfPermission(
12939                 android.Manifest.permission.DELETE_PACKAGES, null);
12940         Preconditions.checkNotNull(packageName);
12941         Preconditions.checkNotNull(observer);
12942         final int uid = Binder.getCallingUid();
12943         if (UserHandle.getUserId(uid) != userId) {
12944             mContext.enforceCallingPermission(
12945                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12946                     "deletePackage for user " + userId);
12947         }
12948         if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
12949             try {
12950                 observer.onPackageDeleted(packageName,
12951                         PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
12952             } catch (RemoteException re) {
12953             }
12954             return;
12955         }
12956 
12957         boolean uninstallBlocked = false;
12958         if ((flags & PackageManager.DELETE_ALL_USERS) != 0) {
12959             int[] users = sUserManager.getUserIds();
12960             for (int i = 0; i < users.length; ++i) {
12961                 if (getBlockUninstallForUser(packageName, users[i])) {
12962                     uninstallBlocked = true;
12963                     break;
12964                 }
12965             }
12966         } else {
12967             uninstallBlocked = getBlockUninstallForUser(packageName, userId);
12968         }
12969         if (uninstallBlocked) {
12970             try {
12971                 observer.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_OWNER_BLOCKED,
12972                         null);
12973             } catch (RemoteException re) {
12974             }
12975             return;
12976         }
12977 
12978         if (DEBUG_REMOVE) {
12979             Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId);
12980         }
12981         // Queue up an async operation since the package deletion may take a little while.
12982         mHandler.post(new Runnable() {
12983             public void run() {
12984                 mHandler.removeCallbacks(this);
12985                 final int returnCode = deletePackageX(packageName, userId, flags);
12986                 if (observer != null) {
12987                     try {
12988                         observer.onPackageDeleted(packageName, returnCode, null);
12989                     } catch (RemoteException e) {
12990                         Log.i(TAG, "Observer no longer exists.");
12991                     } //end catch
12992                 } //end if
12993             } //end run
12994         });
12995     }
12996 
isPackageDeviceAdmin(String packageName, int userId)12997     private boolean isPackageDeviceAdmin(String packageName, int userId) {
12998         IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
12999                 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
13000         try {
13001             if (dpm != null) {
13002                 if (dpm.isDeviceOwner(packageName)) {
13003                     return true;
13004                 }
13005                 int[] users;
13006                 if (userId == UserHandle.USER_ALL) {
13007                     users = sUserManager.getUserIds();
13008                 } else {
13009                     users = new int[]{userId};
13010                 }
13011                 for (int i = 0; i < users.length; ++i) {
13012                     if (dpm.packageHasActiveAdmins(packageName, users[i])) {
13013                         return true;
13014                     }
13015                 }
13016             }
13017         } catch (RemoteException e) {
13018         }
13019         return false;
13020     }
13021 
13022     /**
13023      *  This method is an internal method that could be get invoked either
13024      *  to delete an installed package or to clean up a failed installation.
13025      *  After deleting an installed package, a broadcast is sent to notify any
13026      *  listeners that the package has been installed. For cleaning up a failed
13027      *  installation, the broadcast is not necessary since the package's
13028      *  installation wouldn't have sent the initial broadcast either
13029      *  The key steps in deleting a package are
13030      *  deleting the package information in internal structures like mPackages,
13031      *  deleting the packages base directories through installd
13032      *  updating mSettings to reflect current status
13033      *  persisting settings for later use
13034      *  sending a broadcast if necessary
13035      */
deletePackageX(String packageName, int userId, int flags)13036     private int deletePackageX(String packageName, int userId, int flags) {
13037         final PackageRemovedInfo info = new PackageRemovedInfo();
13038         final boolean res;
13039 
13040         final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0
13041                 ? UserHandle.ALL : new UserHandle(userId);
13042 
13043         if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) {
13044             Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
13045             return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
13046         }
13047 
13048         boolean removedForAllUsers = false;
13049         boolean systemUpdate = false;
13050 
13051         // for the uninstall-updates case and restricted profiles, remember the per-
13052         // userhandle installed state
13053         int[] allUsers;
13054         boolean[] perUserInstalled;
13055         synchronized (mPackages) {
13056             PackageSetting ps = mSettings.mPackages.get(packageName);
13057             allUsers = sUserManager.getUserIds();
13058             perUserInstalled = new boolean[allUsers.length];
13059             for (int i = 0; i < allUsers.length; i++) {
13060                 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
13061             }
13062         }
13063 
13064         synchronized (mInstallLock) {
13065             if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
13066             res = deletePackageLI(packageName, removeForUser,
13067                     true, allUsers, perUserInstalled,
13068                     flags | REMOVE_CHATTY, info, true);
13069             systemUpdate = info.isRemovedPackageSystemUpdate;
13070             if (res && !systemUpdate && mPackages.get(packageName) == null) {
13071                 removedForAllUsers = true;
13072             }
13073             if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate
13074                     + " removedForAllUsers=" + removedForAllUsers);
13075         }
13076 
13077         if (res) {
13078             info.sendBroadcast(true, systemUpdate, removedForAllUsers);
13079 
13080             // If the removed package was a system update, the old system package
13081             // was re-enabled; we need to broadcast this information
13082             if (systemUpdate) {
13083                 Bundle extras = new Bundle(1);
13084                 extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0
13085                         ? info.removedAppId : info.uid);
13086                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
13087 
13088                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
13089                         extras, null, null, null);
13090                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
13091                         extras, null, null, null);
13092                 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
13093                         null, packageName, null, null);
13094             }
13095         }
13096         // Force a gc here.
13097         Runtime.getRuntime().gc();
13098         // Delete the resources here after sending the broadcast to let
13099         // other processes clean up before deleting resources.
13100         if (info.args != null) {
13101             synchronized (mInstallLock) {
13102                 info.args.doPostDeleteLI(true);
13103             }
13104         }
13105 
13106         return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
13107     }
13108 
13109     class PackageRemovedInfo {
13110         String removedPackage;
13111         int uid = -1;
13112         int removedAppId = -1;
13113         int[] removedUsers = null;
13114         boolean isRemovedPackageSystemUpdate = false;
13115         // Clean up resources deleted packages.
13116         InstallArgs args = null;
13117 
sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers)13118         void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) {
13119             Bundle extras = new Bundle(1);
13120             extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
13121             extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove);
13122             if (replacing) {
13123                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
13124             }
13125             extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
13126             if (removedPackage != null) {
13127                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
13128                         extras, null, null, removedUsers);
13129                 if (fullRemove && !replacing) {
13130                     sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage,
13131                             extras, null, null, removedUsers);
13132                 }
13133             }
13134             if (removedAppId >= 0) {
13135                 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null,
13136                         removedUsers);
13137             }
13138         }
13139     }
13140 
13141     /*
13142      * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
13143      * flag is not set, the data directory is removed as well.
13144      * make sure this flag is set for partially installed apps. If not its meaningless to
13145      * delete a partially installed application.
13146      */
removePackageDataLI(PackageSetting ps, int[] allUserHandles, boolean[] perUserInstalled, PackageRemovedInfo outInfo, int flags, boolean writeSettings)13147     private void removePackageDataLI(PackageSetting ps,
13148             int[] allUserHandles, boolean[] perUserInstalled,
13149             PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
13150         String packageName = ps.name;
13151         if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
13152         removePackageLI(ps, (flags&REMOVE_CHATTY) != 0);
13153         // Retrieve object to delete permissions for shared user later on
13154         final PackageSetting deletedPs;
13155         // reader
13156         synchronized (mPackages) {
13157             deletedPs = mSettings.mPackages.get(packageName);
13158             if (outInfo != null) {
13159                 outInfo.removedPackage = packageName;
13160                 outInfo.removedUsers = deletedPs != null
13161                         ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
13162                         : null;
13163             }
13164         }
13165         if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
13166             removeDataDirsLI(ps.volumeUuid, packageName);
13167             schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
13168         }
13169         // writer
13170         synchronized (mPackages) {
13171             if (deletedPs != null) {
13172                 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
13173                     clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
13174                     clearDefaultBrowserIfNeeded(packageName);
13175                     if (outInfo != null) {
13176                         mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
13177                         outInfo.removedAppId = mSettings.removePackageLPw(packageName);
13178                     }
13179                     updatePermissionsLPw(deletedPs.name, null, 0);
13180                     if (deletedPs.sharedUser != null) {
13181                         // Remove permissions associated with package. Since runtime
13182                         // permissions are per user we have to kill the removed package
13183                         // or packages running under the shared user of the removed
13184                         // package if revoking the permissions requested only by the removed
13185                         // package is successful and this causes a change in gids.
13186                         for (int userId : UserManagerService.getInstance().getUserIds()) {
13187                             final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
13188                                     userId);
13189                             if (userIdToKill == UserHandle.USER_ALL
13190                                     || userIdToKill >= UserHandle.USER_OWNER) {
13191                                 // If gids changed for this user, kill all affected packages.
13192                                 mHandler.post(new Runnable() {
13193                                     @Override
13194                                     public void run() {
13195                                         // This has to happen with no lock held.
13196                                         killApplication(deletedPs.name, deletedPs.appId,
13197                                                 KILL_APP_REASON_GIDS_CHANGED);
13198                                     }
13199                                 });
13200                                 break;
13201                             }
13202                         }
13203                     }
13204                     clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
13205                 }
13206                 // make sure to preserve per-user disabled state if this removal was just
13207                 // a downgrade of a system app to the factory package
13208                 if (allUserHandles != null && perUserInstalled != null) {
13209                     if (DEBUG_REMOVE) {
13210                         Slog.d(TAG, "Propagating install state across downgrade");
13211                     }
13212                     for (int i = 0; i < allUserHandles.length; i++) {
13213                         if (DEBUG_REMOVE) {
13214                             Slog.d(TAG, "    user " + allUserHandles[i]
13215                                     + " => " + perUserInstalled[i]);
13216                         }
13217                         ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
13218                     }
13219                 }
13220             }
13221             // can downgrade to reader
13222             if (writeSettings) {
13223                 // Save settings now
13224                 mSettings.writeLPr();
13225             }
13226         }
13227         if (outInfo != null) {
13228             // A user ID was deleted here. Go through all users and remove it
13229             // from KeyStore.
13230             removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId);
13231         }
13232     }
13233 
locationIsPrivileged(File path)13234     static boolean locationIsPrivileged(File path) {
13235         try {
13236             final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
13237                     .getCanonicalPath();
13238             return path.getCanonicalPath().startsWith(privilegedAppDir);
13239         } catch (IOException e) {
13240             Slog.e(TAG, "Unable to access code path " + path);
13241         }
13242         return false;
13243     }
13244 
13245     /*
13246      * Tries to delete system package.
13247      */
deleteSystemPackageLI(PackageSetting newPs, int[] allUserHandles, boolean[] perUserInstalled, int flags, PackageRemovedInfo outInfo, boolean writeSettings)13248     private boolean deleteSystemPackageLI(PackageSetting newPs,
13249             int[] allUserHandles, boolean[] perUserInstalled,
13250             int flags, PackageRemovedInfo outInfo, boolean writeSettings) {
13251         final boolean applyUserRestrictions
13252                 = (allUserHandles != null) && (perUserInstalled != null);
13253         PackageSetting disabledPs = null;
13254         // Confirm if the system package has been updated
13255         // An updated system app can be deleted. This will also have to restore
13256         // the system pkg from system partition
13257         // reader
13258         synchronized (mPackages) {
13259             disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name);
13260         }
13261         if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs
13262                 + " disabledPs=" + disabledPs);
13263         if (disabledPs == null) {
13264             Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name);
13265             return false;
13266         } else if (DEBUG_REMOVE) {
13267             Slog.d(TAG, "Deleting system pkg from data partition");
13268         }
13269         if (DEBUG_REMOVE) {
13270             if (applyUserRestrictions) {
13271                 Slog.d(TAG, "Remembering install states:");
13272                 for (int i = 0; i < allUserHandles.length; i++) {
13273                     Slog.d(TAG, "   u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]);
13274                 }
13275             }
13276         }
13277         // Delete the updated package
13278         outInfo.isRemovedPackageSystemUpdate = true;
13279         if (disabledPs.versionCode < newPs.versionCode) {
13280             // Delete data for downgrades
13281             flags &= ~PackageManager.DELETE_KEEP_DATA;
13282         } else {
13283             // Preserve data by setting flag
13284             flags |= PackageManager.DELETE_KEEP_DATA;
13285         }
13286         boolean ret = deleteInstalledPackageLI(newPs, true, flags,
13287                 allUserHandles, perUserInstalled, outInfo, writeSettings);
13288         if (!ret) {
13289             return false;
13290         }
13291         // writer
13292         synchronized (mPackages) {
13293             // Reinstate the old system package
13294             mSettings.enableSystemPackageLPw(newPs.name);
13295             // Remove any native libraries from the upgraded package.
13296             NativeLibraryHelper.removeNativeBinariesLI(newPs.legacyNativeLibraryPathString);
13297         }
13298         // Install the system package
13299         if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
13300         int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM;
13301         if (locationIsPrivileged(disabledPs.codePath)) {
13302             parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
13303         }
13304 
13305         final PackageParser.Package newPkg;
13306         try {
13307             newPkg = scanPackageLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null);
13308         } catch (PackageManagerException e) {
13309             Slog.w(TAG, "Failed to restore system package:" + newPs.name + ": " + e.getMessage());
13310             return false;
13311         }
13312 
13313         // writer
13314         synchronized (mPackages) {
13315             PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
13316 
13317             // Propagate the permissions state as we do not want to drop on the floor
13318             // runtime permissions. The update permissions method below will take
13319             // care of removing obsolete permissions and grant install permissions.
13320             ps.getPermissionsState().copyFrom(newPs.getPermissionsState());
13321             updatePermissionsLPw(newPkg.packageName, newPkg,
13322                     UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
13323 
13324             if (applyUserRestrictions) {
13325                 if (DEBUG_REMOVE) {
13326                     Slog.d(TAG, "Propagating install state across reinstall");
13327                 }
13328                 for (int i = 0; i < allUserHandles.length; i++) {
13329                     if (DEBUG_REMOVE) {
13330                         Slog.d(TAG, "    user " + allUserHandles[i]
13331                                 + " => " + perUserInstalled[i]);
13332                     }
13333                     ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
13334 
13335                     mSettings.writeRuntimePermissionsForUserLPr(allUserHandles[i], false);
13336                 }
13337                 // Regardless of writeSettings we need to ensure that this restriction
13338                 // state propagation is persisted
13339                 mSettings.writeAllUsersPackageRestrictionsLPr();
13340             }
13341             // can downgrade to reader here
13342             if (writeSettings) {
13343                 mSettings.writeLPr();
13344             }
13345         }
13346         return true;
13347     }
13348 
deleteInstalledPackageLI(PackageSetting ps, boolean deleteCodeAndResources, int flags, int[] allUserHandles, boolean[] perUserInstalled, PackageRemovedInfo outInfo, boolean writeSettings)13349     private boolean deleteInstalledPackageLI(PackageSetting ps,
13350             boolean deleteCodeAndResources, int flags,
13351             int[] allUserHandles, boolean[] perUserInstalled,
13352             PackageRemovedInfo outInfo, boolean writeSettings) {
13353         if (outInfo != null) {
13354             outInfo.uid = ps.appId;
13355         }
13356 
13357         // Delete package data from internal structures and also remove data if flag is set
13358         removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings);
13359 
13360         // Delete application code and resources
13361         if (deleteCodeAndResources && (outInfo != null)) {
13362             outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
13363                     ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
13364             if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
13365         }
13366         return true;
13367     }
13368 
13369     @Override
setBlockUninstallForUser(String packageName, boolean blockUninstall, int userId)13370     public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
13371             int userId) {
13372         mContext.enforceCallingOrSelfPermission(
13373                 android.Manifest.permission.DELETE_PACKAGES, null);
13374         synchronized (mPackages) {
13375             PackageSetting ps = mSettings.mPackages.get(packageName);
13376             if (ps == null) {
13377                 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName);
13378                 return false;
13379             }
13380             if (!ps.getInstalled(userId)) {
13381                 // Can't block uninstall for an app that is not installed or enabled.
13382                 Log.i(TAG, "Package not installed in set block uninstall " + packageName);
13383                 return false;
13384             }
13385             ps.setBlockUninstall(blockUninstall, userId);
13386             mSettings.writePackageRestrictionsLPr(userId);
13387         }
13388         return true;
13389     }
13390 
13391     @Override
getBlockUninstallForUser(String packageName, int userId)13392     public boolean getBlockUninstallForUser(String packageName, int userId) {
13393         synchronized (mPackages) {
13394             PackageSetting ps = mSettings.mPackages.get(packageName);
13395             if (ps == null) {
13396                 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName);
13397                 return false;
13398             }
13399             return ps.getBlockUninstall(userId);
13400         }
13401     }
13402 
13403     /*
13404      * This method handles package deletion in general
13405      */
deletePackageLI(String packageName, UserHandle user, boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled, int flags, PackageRemovedInfo outInfo, boolean writeSettings)13406     private boolean deletePackageLI(String packageName, UserHandle user,
13407             boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled,
13408             int flags, PackageRemovedInfo outInfo,
13409             boolean writeSettings) {
13410         if (packageName == null) {
13411             Slog.w(TAG, "Attempt to delete null packageName.");
13412             return false;
13413         }
13414         if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
13415         PackageSetting ps;
13416         boolean dataOnly = false;
13417         int removeUser = -1;
13418         int appId = -1;
13419         synchronized (mPackages) {
13420             ps = mSettings.mPackages.get(packageName);
13421             if (ps == null) {
13422                 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
13423                 return false;
13424             }
13425             if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
13426                     && user.getIdentifier() != UserHandle.USER_ALL) {
13427                 // The caller is asking that the package only be deleted for a single
13428                 // user.  To do this, we just mark its uninstalled state and delete
13429                 // its data.  If this is a system app, we only allow this to happen if
13430                 // they have set the special DELETE_SYSTEM_APP which requests different
13431                 // semantics than normal for uninstalling system apps.
13432                 if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user");
13433                 final int userId = user.getIdentifier();
13434                 ps.setUserState(userId,
13435                         COMPONENT_ENABLED_STATE_DEFAULT,
13436                         false, //installed
13437                         true,  //stopped
13438                         true,  //notLaunched
13439                         false, //hidden
13440                         null, null, null,
13441                         false, // blockUninstall
13442                         ps.readUserState(userId).domainVerificationStatus, 0);
13443                 if (!isSystemApp(ps)) {
13444                     if (ps.isAnyInstalled(sUserManager.getUserIds())) {
13445                         // Other user still have this package installed, so all
13446                         // we need to do is clear this user's data and save that
13447                         // it is uninstalled.
13448                         if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
13449                         removeUser = user.getIdentifier();
13450                         appId = ps.appId;
13451                         scheduleWritePackageRestrictionsLocked(removeUser);
13452                     } else {
13453                         // We need to set it back to 'installed' so the uninstall
13454                         // broadcasts will be sent correctly.
13455                         if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
13456                         ps.setInstalled(true, user.getIdentifier());
13457                     }
13458                 } else {
13459                     // This is a system app, so we assume that the
13460                     // other users still have this package installed, so all
13461                     // we need to do is clear this user's data and save that
13462                     // it is uninstalled.
13463                     if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
13464                     removeUser = user.getIdentifier();
13465                     appId = ps.appId;
13466                     scheduleWritePackageRestrictionsLocked(removeUser);
13467                 }
13468             }
13469         }
13470 
13471         if (removeUser >= 0) {
13472             // From above, we determined that we are deleting this only
13473             // for a single user.  Continue the work here.
13474             if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser);
13475             if (outInfo != null) {
13476                 outInfo.removedPackage = packageName;
13477                 outInfo.removedAppId = appId;
13478                 outInfo.removedUsers = new int[] {removeUser};
13479             }
13480             mInstaller.clearUserData(ps.volumeUuid, packageName, removeUser);
13481             removeKeystoreDataIfNeeded(removeUser, appId);
13482             schedulePackageCleaning(packageName, removeUser, false);
13483             synchronized (mPackages) {
13484                 if (clearPackagePreferredActivitiesLPw(packageName, removeUser)) {
13485                     scheduleWritePackageRestrictionsLocked(removeUser);
13486                 }
13487                 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, removeUser);
13488             }
13489             return true;
13490         }
13491 
13492         if (dataOnly) {
13493             // Delete application data first
13494             if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only");
13495             removePackageDataLI(ps, null, null, outInfo, flags, writeSettings);
13496             return true;
13497         }
13498 
13499         boolean ret = false;
13500         if (isSystemApp(ps)) {
13501             if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package:" + ps.name);
13502             // When an updated system application is deleted we delete the existing resources as well and
13503             // fall back to existing code in system partition
13504             ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled,
13505                     flags, outInfo, writeSettings);
13506         } else {
13507             if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package:" + ps.name);
13508             // Kill application pre-emptively especially for apps on sd.
13509             killApplication(packageName, ps.appId, "uninstall pkg");
13510             ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags,
13511                     allUserHandles, perUserInstalled,
13512                     outInfo, writeSettings);
13513         }
13514 
13515         return ret;
13516     }
13517 
13518     private final class ClearStorageConnection implements ServiceConnection {
13519         IMediaContainerService mContainerService;
13520 
13521         @Override
onServiceConnected(ComponentName name, IBinder service)13522         public void onServiceConnected(ComponentName name, IBinder service) {
13523             synchronized (this) {
13524                 mContainerService = IMediaContainerService.Stub.asInterface(service);
13525                 notifyAll();
13526             }
13527         }
13528 
13529         @Override
onServiceDisconnected(ComponentName name)13530         public void onServiceDisconnected(ComponentName name) {
13531         }
13532     }
13533 
clearExternalStorageDataSync(String packageName, int userId, boolean allData)13534     private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
13535         final boolean mounted;
13536         if (Environment.isExternalStorageEmulated()) {
13537             mounted = true;
13538         } else {
13539             final String status = Environment.getExternalStorageState();
13540 
13541             mounted = status.equals(Environment.MEDIA_MOUNTED)
13542                     || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
13543         }
13544 
13545         if (!mounted) {
13546             return;
13547         }
13548 
13549         final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
13550         int[] users;
13551         if (userId == UserHandle.USER_ALL) {
13552             users = sUserManager.getUserIds();
13553         } else {
13554             users = new int[] { userId };
13555         }
13556         final ClearStorageConnection conn = new ClearStorageConnection();
13557         if (mContext.bindServiceAsUser(
13558                 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
13559             try {
13560                 for (int curUser : users) {
13561                     long timeout = SystemClock.uptimeMillis() + 5000;
13562                     synchronized (conn) {
13563                         long now = SystemClock.uptimeMillis();
13564                         while (conn.mContainerService == null && now < timeout) {
13565                             try {
13566                                 conn.wait(timeout - now);
13567                             } catch (InterruptedException e) {
13568                             }
13569                         }
13570                     }
13571                     if (conn.mContainerService == null) {
13572                         return;
13573                     }
13574 
13575                     final UserEnvironment userEnv = new UserEnvironment(curUser);
13576                     clearDirectory(conn.mContainerService,
13577                             userEnv.buildExternalStorageAppCacheDirs(packageName));
13578                     if (allData) {
13579                         clearDirectory(conn.mContainerService,
13580                                 userEnv.buildExternalStorageAppDataDirs(packageName));
13581                         clearDirectory(conn.mContainerService,
13582                                 userEnv.buildExternalStorageAppMediaDirs(packageName));
13583                     }
13584                 }
13585             } finally {
13586                 mContext.unbindService(conn);
13587             }
13588         }
13589     }
13590 
13591     @Override
clearApplicationUserData(final String packageName, final IPackageDataObserver observer, final int userId)13592     public void clearApplicationUserData(final String packageName,
13593             final IPackageDataObserver observer, final int userId) {
13594         mContext.enforceCallingOrSelfPermission(
13595                 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
13596         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "clear application data");
13597         // Queue up an async operation since the package deletion may take a little while.
13598         mHandler.post(new Runnable() {
13599             public void run() {
13600                 mHandler.removeCallbacks(this);
13601                 final boolean succeeded;
13602                 synchronized (mInstallLock) {
13603                     succeeded = clearApplicationUserDataLI(packageName, userId);
13604                 }
13605                 clearExternalStorageDataSync(packageName, userId, true);
13606                 if (succeeded) {
13607                     // invoke DeviceStorageMonitor's update method to clear any notifications
13608                     DeviceStorageMonitorInternal
13609                             dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
13610                     if (dsm != null) {
13611                         dsm.checkMemory();
13612                     }
13613                 }
13614                 if(observer != null) {
13615                     try {
13616                         observer.onRemoveCompleted(packageName, succeeded);
13617                     } catch (RemoteException e) {
13618                         Log.i(TAG, "Observer no longer exists.");
13619                     }
13620                 } //end if observer
13621             } //end run
13622         });
13623     }
13624 
clearApplicationUserDataLI(String packageName, int userId)13625     private boolean clearApplicationUserDataLI(String packageName, int userId) {
13626         if (packageName == null) {
13627             Slog.w(TAG, "Attempt to delete null packageName.");
13628             return false;
13629         }
13630 
13631         // Try finding details about the requested package
13632         PackageParser.Package pkg;
13633         synchronized (mPackages) {
13634             pkg = mPackages.get(packageName);
13635             if (pkg == null) {
13636                 final PackageSetting ps = mSettings.mPackages.get(packageName);
13637                 if (ps != null) {
13638                     pkg = ps.pkg;
13639                 }
13640             }
13641 
13642             if (pkg == null) {
13643                 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
13644                 return false;
13645             }
13646 
13647             PackageSetting ps = (PackageSetting) pkg.mExtras;
13648             resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
13649         }
13650 
13651         // Always delete data directories for package, even if we found no other
13652         // record of app. This helps users recover from UID mismatches without
13653         // resorting to a full data wipe.
13654         int retCode = mInstaller.clearUserData(pkg.volumeUuid, packageName, userId);
13655         if (retCode < 0) {
13656             Slog.w(TAG, "Couldn't remove cache files for package: " + packageName);
13657             return false;
13658         }
13659 
13660         final int appId = pkg.applicationInfo.uid;
13661         removeKeystoreDataIfNeeded(userId, appId);
13662 
13663         // Create a native library symlink only if we have native libraries
13664         // and if the native libraries are 32 bit libraries. We do not provide
13665         // this symlink for 64 bit libraries.
13666         if (pkg.applicationInfo.primaryCpuAbi != null &&
13667                 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
13668             final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
13669             if (mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName,
13670                     nativeLibPath, userId) < 0) {
13671                 Slog.w(TAG, "Failed linking native library dir");
13672                 return false;
13673             }
13674         }
13675 
13676         return true;
13677     }
13678 
13679     /**
13680      * Reverts user permission state changes (permissions and flags) in
13681      * all packages for a given user.
13682      *
13683      * @param userId The device user for which to do a reset.
13684      */
resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId)13685     private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
13686         final int packageCount = mPackages.size();
13687         for (int i = 0; i < packageCount; i++) {
13688             PackageParser.Package pkg = mPackages.valueAt(i);
13689             PackageSetting ps = (PackageSetting) pkg.mExtras;
13690             resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
13691         }
13692     }
13693 
13694     /**
13695      * Reverts user permission state changes (permissions and flags).
13696      *
13697      * @param ps The package for which to reset.
13698      * @param userId The device user for which to do a reset.
13699      */
resetUserChangesToRuntimePermissionsAndFlagsLPw( final PackageSetting ps, final int userId)13700     private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
13701             final PackageSetting ps, final int userId) {
13702         if (ps.pkg == null) {
13703             return;
13704         }
13705 
13706         final int userSettableFlags = FLAG_PERMISSION_USER_SET
13707                 | FLAG_PERMISSION_USER_FIXED
13708                 | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
13709 
13710         final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
13711                 | FLAG_PERMISSION_POLICY_FIXED;
13712 
13713         boolean writeInstallPermissions = false;
13714         boolean writeRuntimePermissions = false;
13715 
13716         final int permissionCount = ps.pkg.requestedPermissions.size();
13717         for (int i = 0; i < permissionCount; i++) {
13718             String permission = ps.pkg.requestedPermissions.get(i);
13719 
13720             BasePermission bp = mSettings.mPermissions.get(permission);
13721             if (bp == null) {
13722                 continue;
13723             }
13724 
13725             // If shared user we just reset the state to which only this app contributed.
13726             if (ps.sharedUser != null) {
13727                 boolean used = false;
13728                 final int packageCount = ps.sharedUser.packages.size();
13729                 for (int j = 0; j < packageCount; j++) {
13730                     PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
13731                     if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
13732                             && pkg.pkg.requestedPermissions.contains(permission)) {
13733                         used = true;
13734                         break;
13735                     }
13736                 }
13737                 if (used) {
13738                     continue;
13739                 }
13740             }
13741 
13742             PermissionsState permissionsState = ps.getPermissionsState();
13743 
13744             final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
13745 
13746             // Always clear the user settable flags.
13747             final boolean hasInstallState = permissionsState.getInstallPermissionState(
13748                     bp.name) != null;
13749             if (permissionsState.updatePermissionFlags(bp, userId, userSettableFlags, 0)) {
13750                 if (hasInstallState) {
13751                     writeInstallPermissions = true;
13752                 } else {
13753                     writeRuntimePermissions = true;
13754                 }
13755             }
13756 
13757             // Below is only runtime permission handling.
13758             if (!bp.isRuntime()) {
13759                 continue;
13760             }
13761 
13762             // Never clobber system or policy.
13763             if ((oldFlags & policyOrSystemFlags) != 0) {
13764                 continue;
13765             }
13766 
13767             // If this permission was granted by default, make sure it is.
13768             if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
13769                 if (permissionsState.grantRuntimePermission(bp, userId)
13770                         != PERMISSION_OPERATION_FAILURE) {
13771                     writeRuntimePermissions = true;
13772                 }
13773             } else {
13774                 // Otherwise, reset the permission.
13775                 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
13776                 switch (revokeResult) {
13777                     case PERMISSION_OPERATION_SUCCESS: {
13778                         writeRuntimePermissions = true;
13779                     } break;
13780 
13781                     case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
13782                         writeRuntimePermissions = true;
13783                         final int appId = ps.appId;
13784                         mHandler.post(new Runnable() {
13785                             @Override
13786                             public void run() {
13787                                 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
13788                             }
13789                         });
13790                     } break;
13791                 }
13792             }
13793         }
13794 
13795         // Synchronously write as we are taking permissions away.
13796         if (writeRuntimePermissions) {
13797             mSettings.writeRuntimePermissionsForUserLPr(userId, true);
13798         }
13799 
13800         // Synchronously write as we are taking permissions away.
13801         if (writeInstallPermissions) {
13802             mSettings.writeLPr();
13803         }
13804     }
13805 
13806     /**
13807      * Remove entries from the keystore daemon. Will only remove it if the
13808      * {@code appId} is valid.
13809      */
removeKeystoreDataIfNeeded(int userId, int appId)13810     private static void removeKeystoreDataIfNeeded(int userId, int appId) {
13811         if (appId < 0) {
13812             return;
13813         }
13814 
13815         final KeyStore keyStore = KeyStore.getInstance();
13816         if (keyStore != null) {
13817             if (userId == UserHandle.USER_ALL) {
13818                 for (final int individual : sUserManager.getUserIds()) {
13819                     keyStore.clearUid(UserHandle.getUid(individual, appId));
13820                 }
13821             } else {
13822                 keyStore.clearUid(UserHandle.getUid(userId, appId));
13823             }
13824         } else {
13825             Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
13826         }
13827     }
13828 
13829     @Override
deleteApplicationCacheFiles(final String packageName, final IPackageDataObserver observer)13830     public void deleteApplicationCacheFiles(final String packageName,
13831             final IPackageDataObserver observer) {
13832         mContext.enforceCallingOrSelfPermission(
13833                 android.Manifest.permission.DELETE_CACHE_FILES, null);
13834         // Queue up an async operation since the package deletion may take a little while.
13835         final int userId = UserHandle.getCallingUserId();
13836         mHandler.post(new Runnable() {
13837             public void run() {
13838                 mHandler.removeCallbacks(this);
13839                 final boolean succeded;
13840                 synchronized (mInstallLock) {
13841                     succeded = deleteApplicationCacheFilesLI(packageName, userId);
13842                 }
13843                 clearExternalStorageDataSync(packageName, userId, false);
13844                 if (observer != null) {
13845                     try {
13846                         observer.onRemoveCompleted(packageName, succeded);
13847                     } catch (RemoteException e) {
13848                         Log.i(TAG, "Observer no longer exists.");
13849                     }
13850                 } //end if observer
13851             } //end run
13852         });
13853     }
13854 
deleteApplicationCacheFilesLI(String packageName, int userId)13855     private boolean deleteApplicationCacheFilesLI(String packageName, int userId) {
13856         if (packageName == null) {
13857             Slog.w(TAG, "Attempt to delete null packageName.");
13858             return false;
13859         }
13860         PackageParser.Package p;
13861         synchronized (mPackages) {
13862             p = mPackages.get(packageName);
13863         }
13864         if (p == null) {
13865             Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
13866             return false;
13867         }
13868         final ApplicationInfo applicationInfo = p.applicationInfo;
13869         if (applicationInfo == null) {
13870             Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
13871             return false;
13872         }
13873         int retCode = mInstaller.deleteCacheFiles(p.volumeUuid, packageName, userId);
13874         if (retCode < 0) {
13875             Slog.w(TAG, "Couldn't remove cache files for package: "
13876                        + packageName + " u" + userId);
13877             return false;
13878         }
13879         return true;
13880     }
13881 
13882     @Override
getPackageSizeInfo(final String packageName, int userHandle, final IPackageStatsObserver observer)13883     public void getPackageSizeInfo(final String packageName, int userHandle,
13884             final IPackageStatsObserver observer) {
13885         mContext.enforceCallingOrSelfPermission(
13886                 android.Manifest.permission.GET_PACKAGE_SIZE, null);
13887         if (packageName == null) {
13888             throw new IllegalArgumentException("Attempt to get size of null packageName");
13889         }
13890 
13891         PackageStats stats = new PackageStats(packageName, userHandle);
13892 
13893         /*
13894          * Queue up an async operation since the package measurement may take a
13895          * little while.
13896          */
13897         Message msg = mHandler.obtainMessage(INIT_COPY);
13898         msg.obj = new MeasureParams(stats, observer);
13899         mHandler.sendMessage(msg);
13900     }
13901 
getPackageSizeInfoLI(String packageName, int userHandle, PackageStats pStats)13902     private boolean getPackageSizeInfoLI(String packageName, int userHandle,
13903             PackageStats pStats) {
13904         if (packageName == null) {
13905             Slog.w(TAG, "Attempt to get size of null packageName.");
13906             return false;
13907         }
13908         PackageParser.Package p;
13909         boolean dataOnly = false;
13910         String libDirRoot = null;
13911         String asecPath = null;
13912         PackageSetting ps = null;
13913         synchronized (mPackages) {
13914             p = mPackages.get(packageName);
13915             ps = mSettings.mPackages.get(packageName);
13916             if(p == null) {
13917                 dataOnly = true;
13918                 if((ps == null) || (ps.pkg == null)) {
13919                     Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
13920                     return false;
13921                 }
13922                 p = ps.pkg;
13923             }
13924             if (ps != null) {
13925                 libDirRoot = ps.legacyNativeLibraryPathString;
13926             }
13927             if (p != null && (p.isForwardLocked() || p.applicationInfo.isExternalAsec())) {
13928                 final long token = Binder.clearCallingIdentity();
13929                 try {
13930                     String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath());
13931                     if (secureContainerId != null) {
13932                         asecPath = PackageHelper.getSdFilesystem(secureContainerId);
13933                     }
13934                 } finally {
13935                     Binder.restoreCallingIdentity(token);
13936                 }
13937             }
13938         }
13939         String publicSrcDir = null;
13940         if(!dataOnly) {
13941             final ApplicationInfo applicationInfo = p.applicationInfo;
13942             if (applicationInfo == null) {
13943                 Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
13944                 return false;
13945             }
13946             if (p.isForwardLocked()) {
13947                 publicSrcDir = applicationInfo.getBaseResourcePath();
13948             }
13949         }
13950         // TODO: extend to measure size of split APKs
13951         // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree,
13952         // not just the first level.
13953         // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not
13954         // just the primary.
13955         String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps));
13956 
13957         String apkPath;
13958         File packageDir = new File(p.codePath);
13959 
13960         if (packageDir.isDirectory() && p.canHaveOatDir()) {
13961             apkPath = packageDir.getAbsolutePath();
13962             // If libDirRoot is inside a package dir, set it to null to avoid it being counted twice
13963             if (libDirRoot != null && libDirRoot.startsWith(apkPath)) {
13964                 libDirRoot = null;
13965             }
13966         } else {
13967             apkPath = p.baseCodePath;
13968         }
13969 
13970         int res = mInstaller.getSizeInfo(p.volumeUuid, packageName, userHandle, apkPath,
13971                 libDirRoot, publicSrcDir, asecPath, dexCodeInstructionSets, pStats);
13972         if (res < 0) {
13973             return false;
13974         }
13975 
13976         // Fix-up for forward-locked applications in ASEC containers.
13977         if (!isExternal(p)) {
13978             pStats.codeSize += pStats.externalCodeSize;
13979             pStats.externalCodeSize = 0L;
13980         }
13981 
13982         return true;
13983     }
13984 
13985 
13986     @Override
addPackageToPreferred(String packageName)13987     public void addPackageToPreferred(String packageName) {
13988         Slog.w(TAG, "addPackageToPreferred: this is now a no-op");
13989     }
13990 
13991     @Override
removePackageFromPreferred(String packageName)13992     public void removePackageFromPreferred(String packageName) {
13993         Slog.w(TAG, "removePackageFromPreferred: this is now a no-op");
13994     }
13995 
13996     @Override
getPreferredPackages(int flags)13997     public List<PackageInfo> getPreferredPackages(int flags) {
13998         return new ArrayList<PackageInfo>();
13999     }
14000 
getUidTargetSdkVersionLockedLPr(int uid)14001     private int getUidTargetSdkVersionLockedLPr(int uid) {
14002         Object obj = mSettings.getUserIdLPr(uid);
14003         if (obj instanceof SharedUserSetting) {
14004             final SharedUserSetting sus = (SharedUserSetting) obj;
14005             int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
14006             final Iterator<PackageSetting> it = sus.packages.iterator();
14007             while (it.hasNext()) {
14008                 final PackageSetting ps = it.next();
14009                 if (ps.pkg != null) {
14010                     int v = ps.pkg.applicationInfo.targetSdkVersion;
14011                     if (v < vers) vers = v;
14012                 }
14013             }
14014             return vers;
14015         } else if (obj instanceof PackageSetting) {
14016             final PackageSetting ps = (PackageSetting) obj;
14017             if (ps.pkg != null) {
14018                 return ps.pkg.applicationInfo.targetSdkVersion;
14019             }
14020         }
14021         return Build.VERSION_CODES.CUR_DEVELOPMENT;
14022     }
14023 
14024     @Override
addPreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, int userId)14025     public void addPreferredActivity(IntentFilter filter, int match,
14026             ComponentName[] set, ComponentName activity, int userId) {
14027         addPreferredActivityInternal(filter, match, set, activity, true, userId,
14028                 "Adding preferred");
14029     }
14030 
addPreferredActivityInternal(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, boolean always, int userId, String opname)14031     private void addPreferredActivityInternal(IntentFilter filter, int match,
14032             ComponentName[] set, ComponentName activity, boolean always, int userId,
14033             String opname) {
14034         // writer
14035         int callingUid = Binder.getCallingUid();
14036         enforceCrossUserPermission(callingUid, userId, true, false, "add preferred activity");
14037         if (filter.countActions() == 0) {
14038             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
14039             return;
14040         }
14041         synchronized (mPackages) {
14042             if (mContext.checkCallingOrSelfPermission(
14043                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
14044                     != PackageManager.PERMISSION_GRANTED) {
14045                 if (getUidTargetSdkVersionLockedLPr(callingUid)
14046                         < Build.VERSION_CODES.FROYO) {
14047                     Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
14048                             + callingUid);
14049                     return;
14050                 }
14051                 mContext.enforceCallingOrSelfPermission(
14052                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14053             }
14054 
14055             PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
14056             Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
14057                     + userId + ":");
14058             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
14059             pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
14060             scheduleWritePackageRestrictionsLocked(userId);
14061         }
14062     }
14063 
14064     @Override
replacePreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, int userId)14065     public void replacePreferredActivity(IntentFilter filter, int match,
14066             ComponentName[] set, ComponentName activity, int userId) {
14067         if (filter.countActions() != 1) {
14068             throw new IllegalArgumentException(
14069                     "replacePreferredActivity expects filter to have only 1 action.");
14070         }
14071         if (filter.countDataAuthorities() != 0
14072                 || filter.countDataPaths() != 0
14073                 || filter.countDataSchemes() > 1
14074                 || filter.countDataTypes() != 0) {
14075             throw new IllegalArgumentException(
14076                     "replacePreferredActivity expects filter to have no data authorities, " +
14077                     "paths, or types; and at most one scheme.");
14078         }
14079 
14080         final int callingUid = Binder.getCallingUid();
14081         enforceCrossUserPermission(callingUid, userId, true, false, "replace preferred activity");
14082         synchronized (mPackages) {
14083             if (mContext.checkCallingOrSelfPermission(
14084                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
14085                     != PackageManager.PERMISSION_GRANTED) {
14086                 if (getUidTargetSdkVersionLockedLPr(callingUid)
14087                         < Build.VERSION_CODES.FROYO) {
14088                     Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
14089                             + Binder.getCallingUid());
14090                     return;
14091                 }
14092                 mContext.enforceCallingOrSelfPermission(
14093                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14094             }
14095 
14096             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
14097             if (pir != null) {
14098                 // Get all of the existing entries that exactly match this filter.
14099                 ArrayList<PreferredActivity> existing = pir.findFilters(filter);
14100                 if (existing != null && existing.size() == 1) {
14101                     PreferredActivity cur = existing.get(0);
14102                     if (DEBUG_PREFERRED) {
14103                         Slog.i(TAG, "Checking replace of preferred:");
14104                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
14105                         if (!cur.mPref.mAlways) {
14106                             Slog.i(TAG, "  -- CUR; not mAlways!");
14107                         } else {
14108                             Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
14109                             Slog.i(TAG, "  -- CUR: mSet="
14110                                     + Arrays.toString(cur.mPref.mSetComponents));
14111                             Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
14112                             Slog.i(TAG, "  -- NEW: mMatch="
14113                                     + (match&IntentFilter.MATCH_CATEGORY_MASK));
14114                             Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
14115                             Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
14116                         }
14117                     }
14118                     if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
14119                             && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
14120                             && cur.mPref.sameSet(set)) {
14121                         // Setting the preferred activity to what it happens to be already
14122                         if (DEBUG_PREFERRED) {
14123                             Slog.i(TAG, "Replacing with same preferred activity "
14124                                     + cur.mPref.mShortComponent + " for user "
14125                                     + userId + ":");
14126                             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
14127                         }
14128                         return;
14129                     }
14130                 }
14131 
14132                 if (existing != null) {
14133                     if (DEBUG_PREFERRED) {
14134                         Slog.i(TAG, existing.size() + " existing preferred matches for:");
14135                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
14136                     }
14137                     for (int i = 0; i < existing.size(); i++) {
14138                         PreferredActivity pa = existing.get(i);
14139                         if (DEBUG_PREFERRED) {
14140                             Slog.i(TAG, "Removing existing preferred activity "
14141                                     + pa.mPref.mComponent + ":");
14142                             pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
14143                         }
14144                         pir.removeFilter(pa);
14145                     }
14146                 }
14147             }
14148             addPreferredActivityInternal(filter, match, set, activity, true, userId,
14149                     "Replacing preferred");
14150         }
14151     }
14152 
14153     @Override
clearPackagePreferredActivities(String packageName)14154     public void clearPackagePreferredActivities(String packageName) {
14155         final int uid = Binder.getCallingUid();
14156         // writer
14157         synchronized (mPackages) {
14158             PackageParser.Package pkg = mPackages.get(packageName);
14159             if (pkg == null || pkg.applicationInfo.uid != uid) {
14160                 if (mContext.checkCallingOrSelfPermission(
14161                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
14162                         != PackageManager.PERMISSION_GRANTED) {
14163                     if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
14164                             < Build.VERSION_CODES.FROYO) {
14165                         Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
14166                                 + Binder.getCallingUid());
14167                         return;
14168                     }
14169                     mContext.enforceCallingOrSelfPermission(
14170                             android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14171                 }
14172             }
14173 
14174             int user = UserHandle.getCallingUserId();
14175             if (clearPackagePreferredActivitiesLPw(packageName, user)) {
14176                 scheduleWritePackageRestrictionsLocked(user);
14177             }
14178         }
14179     }
14180 
14181     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
clearPackagePreferredActivitiesLPw(String packageName, int userId)14182     boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
14183         ArrayList<PreferredActivity> removed = null;
14184         boolean changed = false;
14185         for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
14186             final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
14187             PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
14188             if (userId != UserHandle.USER_ALL && userId != thisUserId) {
14189                 continue;
14190             }
14191             Iterator<PreferredActivity> it = pir.filterIterator();
14192             while (it.hasNext()) {
14193                 PreferredActivity pa = it.next();
14194                 // Mark entry for removal only if it matches the package name
14195                 // and the entry is of type "always".
14196                 if (packageName == null ||
14197                         (pa.mPref.mComponent.getPackageName().equals(packageName)
14198                                 && pa.mPref.mAlways)) {
14199                     if (removed == null) {
14200                         removed = new ArrayList<PreferredActivity>();
14201                     }
14202                     removed.add(pa);
14203                 }
14204             }
14205             if (removed != null) {
14206                 for (int j=0; j<removed.size(); j++) {
14207                     PreferredActivity pa = removed.get(j);
14208                     pir.removeFilter(pa);
14209                 }
14210                 changed = true;
14211             }
14212         }
14213         return changed;
14214     }
14215 
14216     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
clearIntentFilterVerificationsLPw(int userId)14217     private void clearIntentFilterVerificationsLPw(int userId) {
14218         final int packageCount = mPackages.size();
14219         for (int i = 0; i < packageCount; i++) {
14220             PackageParser.Package pkg = mPackages.valueAt(i);
14221             clearIntentFilterVerificationsLPw(pkg.packageName, userId);
14222         }
14223     }
14224 
14225     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
clearIntentFilterVerificationsLPw(String packageName, int userId)14226     void clearIntentFilterVerificationsLPw(String packageName, int userId) {
14227         if (userId == UserHandle.USER_ALL) {
14228             if (mSettings.removeIntentFilterVerificationLPw(packageName,
14229                     sUserManager.getUserIds())) {
14230                 for (int oneUserId : sUserManager.getUserIds()) {
14231                     scheduleWritePackageRestrictionsLocked(oneUserId);
14232                 }
14233             }
14234         } else {
14235             if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
14236                 scheduleWritePackageRestrictionsLocked(userId);
14237             }
14238         }
14239     }
14240 
clearDefaultBrowserIfNeeded(String packageName)14241     void clearDefaultBrowserIfNeeded(String packageName) {
14242         for (int oneUserId : sUserManager.getUserIds()) {
14243             String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId);
14244             if (TextUtils.isEmpty(defaultBrowserPackageName)) continue;
14245             if (packageName.equals(defaultBrowserPackageName)) {
14246                 setDefaultBrowserPackageName(null, oneUserId);
14247             }
14248         }
14249     }
14250 
14251     @Override
resetApplicationPreferences(int userId)14252     public void resetApplicationPreferences(int userId) {
14253         mContext.enforceCallingOrSelfPermission(
14254                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14255         // writer
14256         synchronized (mPackages) {
14257             final long identity = Binder.clearCallingIdentity();
14258             try {
14259                 clearPackagePreferredActivitiesLPw(null, userId);
14260                 mSettings.applyDefaultPreferredAppsLPw(this, userId);
14261                 // TODO: We have to reset the default SMS and Phone. This requires
14262                 // significant refactoring to keep all default apps in the package
14263                 // manager (cleaner but more work) or have the services provide
14264                 // callbacks to the package manager to request a default app reset.
14265                 applyFactoryDefaultBrowserLPw(userId);
14266                 clearIntentFilterVerificationsLPw(userId);
14267                 primeDomainVerificationsLPw(userId);
14268                 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
14269                 scheduleWritePackageRestrictionsLocked(userId);
14270             } finally {
14271                 Binder.restoreCallingIdentity(identity);
14272             }
14273         }
14274     }
14275 
14276     @Override
getPreferredActivities(List<IntentFilter> outFilters, List<ComponentName> outActivities, String packageName)14277     public int getPreferredActivities(List<IntentFilter> outFilters,
14278             List<ComponentName> outActivities, String packageName) {
14279 
14280         int num = 0;
14281         final int userId = UserHandle.getCallingUserId();
14282         // reader
14283         synchronized (mPackages) {
14284             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
14285             if (pir != null) {
14286                 final Iterator<PreferredActivity> it = pir.filterIterator();
14287                 while (it.hasNext()) {
14288                     final PreferredActivity pa = it.next();
14289                     if (packageName == null
14290                             || (pa.mPref.mComponent.getPackageName().equals(packageName)
14291                                     && pa.mPref.mAlways)) {
14292                         if (outFilters != null) {
14293                             outFilters.add(new IntentFilter(pa));
14294                         }
14295                         if (outActivities != null) {
14296                             outActivities.add(pa.mPref.mComponent);
14297                         }
14298                     }
14299                 }
14300             }
14301         }
14302 
14303         return num;
14304     }
14305 
14306     @Override
addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, int userId)14307     public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
14308             int userId) {
14309         int callingUid = Binder.getCallingUid();
14310         if (callingUid != Process.SYSTEM_UID) {
14311             throw new SecurityException(
14312                     "addPersistentPreferredActivity can only be run by the system");
14313         }
14314         if (filter.countActions() == 0) {
14315             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
14316             return;
14317         }
14318         synchronized (mPackages) {
14319             Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
14320                     " :");
14321             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
14322             mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
14323                     new PersistentPreferredActivity(filter, activity));
14324             scheduleWritePackageRestrictionsLocked(userId);
14325         }
14326     }
14327 
14328     @Override
clearPackagePersistentPreferredActivities(String packageName, int userId)14329     public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
14330         int callingUid = Binder.getCallingUid();
14331         if (callingUid != Process.SYSTEM_UID) {
14332             throw new SecurityException(
14333                     "clearPackagePersistentPreferredActivities can only be run by the system");
14334         }
14335         ArrayList<PersistentPreferredActivity> removed = null;
14336         boolean changed = false;
14337         synchronized (mPackages) {
14338             for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
14339                 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
14340                 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
14341                         .valueAt(i);
14342                 if (userId != thisUserId) {
14343                     continue;
14344                 }
14345                 Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
14346                 while (it.hasNext()) {
14347                     PersistentPreferredActivity ppa = it.next();
14348                     // Mark entry for removal only if it matches the package name.
14349                     if (ppa.mComponent.getPackageName().equals(packageName)) {
14350                         if (removed == null) {
14351                             removed = new ArrayList<PersistentPreferredActivity>();
14352                         }
14353                         removed.add(ppa);
14354                     }
14355                 }
14356                 if (removed != null) {
14357                     for (int j=0; j<removed.size(); j++) {
14358                         PersistentPreferredActivity ppa = removed.get(j);
14359                         ppir.removeFilter(ppa);
14360                     }
14361                     changed = true;
14362                 }
14363             }
14364 
14365             if (changed) {
14366                 scheduleWritePackageRestrictionsLocked(userId);
14367             }
14368         }
14369     }
14370 
14371     /**
14372      * Common machinery for picking apart a restored XML blob and passing
14373      * it to a caller-supplied functor to be applied to the running system.
14374      */
restoreFromXml(XmlPullParser parser, int userId, String expectedStartTag, BlobXmlRestorer functor)14375     private void restoreFromXml(XmlPullParser parser, int userId,
14376             String expectedStartTag, BlobXmlRestorer functor)
14377             throws IOException, XmlPullParserException {
14378         int type;
14379         while ((type = parser.next()) != XmlPullParser.START_TAG
14380                 && type != XmlPullParser.END_DOCUMENT) {
14381         }
14382         if (type != XmlPullParser.START_TAG) {
14383             // oops didn't find a start tag?!
14384             if (DEBUG_BACKUP) {
14385                 Slog.e(TAG, "Didn't find start tag during restore");
14386             }
14387             return;
14388         }
14389 
14390         // this is supposed to be TAG_PREFERRED_BACKUP
14391         if (!expectedStartTag.equals(parser.getName())) {
14392             if (DEBUG_BACKUP) {
14393                 Slog.e(TAG, "Found unexpected tag " + parser.getName());
14394             }
14395             return;
14396         }
14397 
14398         // skip interfering stuff, then we're aligned with the backing implementation
14399         while ((type = parser.next()) == XmlPullParser.TEXT) { }
14400         functor.apply(parser, userId);
14401     }
14402 
14403     private interface BlobXmlRestorer {
apply(XmlPullParser parser, int userId)14404         public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
14405     }
14406 
14407     /**
14408      * Non-Binder method, support for the backup/restore mechanism: write the
14409      * full set of preferred activities in its canonical XML format.  Returns the
14410      * XML output as a byte array, or null if there is none.
14411      */
14412     @Override
getPreferredActivityBackup(int userId)14413     public byte[] getPreferredActivityBackup(int userId) {
14414         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14415             throw new SecurityException("Only the system may call getPreferredActivityBackup()");
14416         }
14417 
14418         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
14419         try {
14420             final XmlSerializer serializer = new FastXmlSerializer();
14421             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
14422             serializer.startDocument(null, true);
14423             serializer.startTag(null, TAG_PREFERRED_BACKUP);
14424 
14425             synchronized (mPackages) {
14426                 mSettings.writePreferredActivitiesLPr(serializer, userId, true);
14427             }
14428 
14429             serializer.endTag(null, TAG_PREFERRED_BACKUP);
14430             serializer.endDocument();
14431             serializer.flush();
14432         } catch (Exception e) {
14433             if (DEBUG_BACKUP) {
14434                 Slog.e(TAG, "Unable to write preferred activities for backup", e);
14435             }
14436             return null;
14437         }
14438 
14439         return dataStream.toByteArray();
14440     }
14441 
14442     @Override
restorePreferredActivities(byte[] backup, int userId)14443     public void restorePreferredActivities(byte[] backup, int userId) {
14444         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14445             throw new SecurityException("Only the system may call restorePreferredActivities()");
14446         }
14447 
14448         try {
14449             final XmlPullParser parser = Xml.newPullParser();
14450             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
14451             restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
14452                     new BlobXmlRestorer() {
14453                         @Override
14454                         public void apply(XmlPullParser parser, int userId)
14455                                 throws XmlPullParserException, IOException {
14456                             synchronized (mPackages) {
14457                                 mSettings.readPreferredActivitiesLPw(parser, userId);
14458                             }
14459                         }
14460                     } );
14461         } catch (Exception e) {
14462             if (DEBUG_BACKUP) {
14463                 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
14464             }
14465         }
14466     }
14467 
14468     /**
14469      * Non-Binder method, support for the backup/restore mechanism: write the
14470      * default browser (etc) settings in its canonical XML format.  Returns the default
14471      * browser XML representation as a byte array, or null if there is none.
14472      */
14473     @Override
getDefaultAppsBackup(int userId)14474     public byte[] getDefaultAppsBackup(int userId) {
14475         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14476             throw new SecurityException("Only the system may call getDefaultAppsBackup()");
14477         }
14478 
14479         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
14480         try {
14481             final XmlSerializer serializer = new FastXmlSerializer();
14482             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
14483             serializer.startDocument(null, true);
14484             serializer.startTag(null, TAG_DEFAULT_APPS);
14485 
14486             synchronized (mPackages) {
14487                 mSettings.writeDefaultAppsLPr(serializer, userId);
14488             }
14489 
14490             serializer.endTag(null, TAG_DEFAULT_APPS);
14491             serializer.endDocument();
14492             serializer.flush();
14493         } catch (Exception e) {
14494             if (DEBUG_BACKUP) {
14495                 Slog.e(TAG, "Unable to write default apps for backup", e);
14496             }
14497             return null;
14498         }
14499 
14500         return dataStream.toByteArray();
14501     }
14502 
14503     @Override
restoreDefaultApps(byte[] backup, int userId)14504     public void restoreDefaultApps(byte[] backup, int userId) {
14505         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14506             throw new SecurityException("Only the system may call restoreDefaultApps()");
14507         }
14508 
14509         try {
14510             final XmlPullParser parser = Xml.newPullParser();
14511             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
14512             restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
14513                     new BlobXmlRestorer() {
14514                         @Override
14515                         public void apply(XmlPullParser parser, int userId)
14516                                 throws XmlPullParserException, IOException {
14517                             synchronized (mPackages) {
14518                                 mSettings.readDefaultAppsLPw(parser, userId);
14519                             }
14520                         }
14521                     } );
14522         } catch (Exception e) {
14523             if (DEBUG_BACKUP) {
14524                 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
14525             }
14526         }
14527     }
14528 
14529     @Override
getIntentFilterVerificationBackup(int userId)14530     public byte[] getIntentFilterVerificationBackup(int userId) {
14531         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14532             throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
14533         }
14534 
14535         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
14536         try {
14537             final XmlSerializer serializer = new FastXmlSerializer();
14538             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
14539             serializer.startDocument(null, true);
14540             serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
14541 
14542             synchronized (mPackages) {
14543                 mSettings.writeAllDomainVerificationsLPr(serializer, userId);
14544             }
14545 
14546             serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
14547             serializer.endDocument();
14548             serializer.flush();
14549         } catch (Exception e) {
14550             if (DEBUG_BACKUP) {
14551                 Slog.e(TAG, "Unable to write default apps for backup", e);
14552             }
14553             return null;
14554         }
14555 
14556         return dataStream.toByteArray();
14557     }
14558 
14559     @Override
restoreIntentFilterVerification(byte[] backup, int userId)14560     public void restoreIntentFilterVerification(byte[] backup, int userId) {
14561         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14562             throw new SecurityException("Only the system may call restorePreferredActivities()");
14563         }
14564 
14565         try {
14566             final XmlPullParser parser = Xml.newPullParser();
14567             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
14568             restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
14569                     new BlobXmlRestorer() {
14570                         @Override
14571                         public void apply(XmlPullParser parser, int userId)
14572                                 throws XmlPullParserException, IOException {
14573                             synchronized (mPackages) {
14574                                 mSettings.readAllDomainVerificationsLPr(parser, userId);
14575                                 mSettings.writeLPr();
14576                             }
14577                         }
14578                     } );
14579         } catch (Exception e) {
14580             if (DEBUG_BACKUP) {
14581                 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
14582             }
14583         }
14584     }
14585 
14586     @Override
addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, int sourceUserId, int targetUserId, int flags)14587     public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
14588             int sourceUserId, int targetUserId, int flags) {
14589         mContext.enforceCallingOrSelfPermission(
14590                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
14591         int callingUid = Binder.getCallingUid();
14592         enforceOwnerRights(ownerPackage, callingUid);
14593         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
14594         if (intentFilter.countActions() == 0) {
14595             Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
14596             return;
14597         }
14598         synchronized (mPackages) {
14599             CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
14600                     ownerPackage, targetUserId, flags);
14601             CrossProfileIntentResolver resolver =
14602                     mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
14603             ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
14604             // We have all those whose filter is equal. Now checking if the rest is equal as well.
14605             if (existing != null) {
14606                 int size = existing.size();
14607                 for (int i = 0; i < size; i++) {
14608                     if (newFilter.equalsIgnoreFilter(existing.get(i))) {
14609                         return;
14610                     }
14611                 }
14612             }
14613             resolver.addFilter(newFilter);
14614             scheduleWritePackageRestrictionsLocked(sourceUserId);
14615         }
14616     }
14617 
14618     @Override
clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage)14619     public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
14620         mContext.enforceCallingOrSelfPermission(
14621                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
14622         int callingUid = Binder.getCallingUid();
14623         enforceOwnerRights(ownerPackage, callingUid);
14624         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
14625         synchronized (mPackages) {
14626             CrossProfileIntentResolver resolver =
14627                     mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
14628             ArraySet<CrossProfileIntentFilter> set =
14629                     new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
14630             for (CrossProfileIntentFilter filter : set) {
14631                 if (filter.getOwnerPackage().equals(ownerPackage)) {
14632                     resolver.removeFilter(filter);
14633                 }
14634             }
14635             scheduleWritePackageRestrictionsLocked(sourceUserId);
14636         }
14637     }
14638 
14639     // Enforcing that callingUid is owning pkg on userId
enforceOwnerRights(String pkg, int callingUid)14640     private void enforceOwnerRights(String pkg, int callingUid) {
14641         // The system owns everything.
14642         if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
14643             return;
14644         }
14645         int callingUserId = UserHandle.getUserId(callingUid);
14646         PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
14647         if (pi == null) {
14648             throw new IllegalArgumentException("Unknown package " + pkg + " on user "
14649                     + callingUserId);
14650         }
14651         if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
14652             throw new SecurityException("Calling uid " + callingUid
14653                     + " does not own package " + pkg);
14654         }
14655     }
14656 
14657     @Override
getHomeActivities(List<ResolveInfo> allHomeCandidates)14658     public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
14659         Intent intent = new Intent(Intent.ACTION_MAIN);
14660         intent.addCategory(Intent.CATEGORY_HOME);
14661 
14662         final int callingUserId = UserHandle.getCallingUserId();
14663         List<ResolveInfo> list = queryIntentActivities(intent, null,
14664                 PackageManager.GET_META_DATA, callingUserId);
14665         ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
14666                 true, false, false, callingUserId);
14667 
14668         allHomeCandidates.clear();
14669         if (list != null) {
14670             for (ResolveInfo ri : list) {
14671                 allHomeCandidates.add(ri);
14672             }
14673         }
14674         return (preferred == null || preferred.activityInfo == null)
14675                 ? null
14676                 : new ComponentName(preferred.activityInfo.packageName,
14677                         preferred.activityInfo.name);
14678     }
14679 
14680     @Override
setApplicationEnabledSetting(String appPackageName, int newState, int flags, int userId, String callingPackage)14681     public void setApplicationEnabledSetting(String appPackageName,
14682             int newState, int flags, int userId, String callingPackage) {
14683         if (!sUserManager.exists(userId)) return;
14684         if (callingPackage == null) {
14685             callingPackage = Integer.toString(Binder.getCallingUid());
14686         }
14687         setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
14688     }
14689 
14690     @Override
setComponentEnabledSetting(ComponentName componentName, int newState, int flags, int userId)14691     public void setComponentEnabledSetting(ComponentName componentName,
14692             int newState, int flags, int userId) {
14693         if (!sUserManager.exists(userId)) return;
14694         setEnabledSetting(componentName.getPackageName(),
14695                 componentName.getClassName(), newState, flags, userId, null);
14696     }
14697 
setEnabledSetting(final String packageName, String className, int newState, final int flags, int userId, String callingPackage)14698     private void setEnabledSetting(final String packageName, String className, int newState,
14699             final int flags, int userId, String callingPackage) {
14700         if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
14701               || newState == COMPONENT_ENABLED_STATE_ENABLED
14702               || newState == COMPONENT_ENABLED_STATE_DISABLED
14703               || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
14704               || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
14705             throw new IllegalArgumentException("Invalid new component state: "
14706                     + newState);
14707         }
14708         PackageSetting pkgSetting;
14709         final int uid = Binder.getCallingUid();
14710         final int permission = mContext.checkCallingOrSelfPermission(
14711                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
14712         enforceCrossUserPermission(uid, userId, false, true, "set enabled");
14713         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
14714         boolean sendNow = false;
14715         boolean isApp = (className == null);
14716         String componentName = isApp ? packageName : className;
14717         int packageUid = -1;
14718         ArrayList<String> components;
14719 
14720         // writer
14721         synchronized (mPackages) {
14722             pkgSetting = mSettings.mPackages.get(packageName);
14723             if (pkgSetting == null) {
14724                 if (className == null) {
14725                     throw new IllegalArgumentException(
14726                             "Unknown package: " + packageName);
14727                 }
14728                 throw new IllegalArgumentException(
14729                         "Unknown component: " + packageName
14730                         + "/" + className);
14731             }
14732             // Allow root and verify that userId is not being specified by a different user
14733             if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) {
14734                 throw new SecurityException(
14735                         "Permission Denial: attempt to change component state from pid="
14736                         + Binder.getCallingPid()
14737                         + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
14738             }
14739             if (className == null) {
14740                 // We're dealing with an application/package level state change
14741                 if (pkgSetting.getEnabled(userId) == newState) {
14742                     // Nothing to do
14743                     return;
14744                 }
14745                 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
14746                     || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
14747                     // Don't care about who enables an app.
14748                     callingPackage = null;
14749                 }
14750                 pkgSetting.setEnabled(newState, userId, callingPackage);
14751                 // pkgSetting.pkg.mSetEnabled = newState;
14752             } else {
14753                 // We're dealing with a component level state change
14754                 // First, verify that this is a valid class name.
14755                 PackageParser.Package pkg = pkgSetting.pkg;
14756                 if (pkg == null || !pkg.hasComponentClassName(className)) {
14757                     if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) {
14758                         throw new IllegalArgumentException("Component class " + className
14759                                 + " does not exist in " + packageName);
14760                     } else {
14761                         Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
14762                                 + className + " does not exist in " + packageName);
14763                     }
14764                 }
14765                 switch (newState) {
14766                 case COMPONENT_ENABLED_STATE_ENABLED:
14767                     if (!pkgSetting.enableComponentLPw(className, userId)) {
14768                         return;
14769                     }
14770                     break;
14771                 case COMPONENT_ENABLED_STATE_DISABLED:
14772                     if (!pkgSetting.disableComponentLPw(className, userId)) {
14773                         return;
14774                     }
14775                     break;
14776                 case COMPONENT_ENABLED_STATE_DEFAULT:
14777                     if (!pkgSetting.restoreComponentLPw(className, userId)) {
14778                         return;
14779                     }
14780                     break;
14781                 default:
14782                     Slog.e(TAG, "Invalid new component state: " + newState);
14783                     return;
14784                 }
14785             }
14786             scheduleWritePackageRestrictionsLocked(userId);
14787             components = mPendingBroadcasts.get(userId, packageName);
14788             final boolean newPackage = components == null;
14789             if (newPackage) {
14790                 components = new ArrayList<String>();
14791             }
14792             if (!components.contains(componentName)) {
14793                 components.add(componentName);
14794             }
14795             if ((flags&PackageManager.DONT_KILL_APP) == 0) {
14796                 sendNow = true;
14797                 // Purge entry from pending broadcast list if another one exists already
14798                 // since we are sending one right away.
14799                 mPendingBroadcasts.remove(userId, packageName);
14800             } else {
14801                 if (newPackage) {
14802                     mPendingBroadcasts.put(userId, packageName, components);
14803                 }
14804                 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
14805                     // Schedule a message
14806                     mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
14807                 }
14808             }
14809         }
14810 
14811         long callingId = Binder.clearCallingIdentity();
14812         try {
14813             if (sendNow) {
14814                 packageUid = UserHandle.getUid(userId, pkgSetting.appId);
14815                 sendPackageChangedBroadcast(packageName,
14816                         (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
14817             }
14818         } finally {
14819             Binder.restoreCallingIdentity(callingId);
14820         }
14821     }
14822 
sendPackageChangedBroadcast(String packageName, boolean killFlag, ArrayList<String> componentNames, int packageUid)14823     private void sendPackageChangedBroadcast(String packageName,
14824             boolean killFlag, ArrayList<String> componentNames, int packageUid) {
14825         if (DEBUG_INSTALL)
14826             Log.v(TAG, "Sending package changed: package=" + packageName + " components="
14827                     + componentNames);
14828         Bundle extras = new Bundle(4);
14829         extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
14830         String nameList[] = new String[componentNames.size()];
14831         componentNames.toArray(nameList);
14832         extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
14833         extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
14834         extras.putInt(Intent.EXTRA_UID, packageUid);
14835         sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, null, null,
14836                 new int[] {UserHandle.getUserId(packageUid)});
14837     }
14838 
14839     @Override
setPackageStoppedState(String packageName, boolean stopped, int userId)14840     public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
14841         if (!sUserManager.exists(userId)) return;
14842         final int uid = Binder.getCallingUid();
14843         final int permission = mContext.checkCallingOrSelfPermission(
14844                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
14845         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
14846         enforceCrossUserPermission(uid, userId, true, true, "stop package");
14847         // writer
14848         synchronized (mPackages) {
14849             if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
14850                     allowedByPermission, uid, userId)) {
14851                 scheduleWritePackageRestrictionsLocked(userId);
14852             }
14853         }
14854     }
14855 
14856     @Override
getInstallerPackageName(String packageName)14857     public String getInstallerPackageName(String packageName) {
14858         // reader
14859         synchronized (mPackages) {
14860             return mSettings.getInstallerPackageNameLPr(packageName);
14861         }
14862     }
14863 
14864     @Override
getApplicationEnabledSetting(String packageName, int userId)14865     public int getApplicationEnabledSetting(String packageName, int userId) {
14866         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
14867         int uid = Binder.getCallingUid();
14868         enforceCrossUserPermission(uid, userId, false, false, "get enabled");
14869         // reader
14870         synchronized (mPackages) {
14871             return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
14872         }
14873     }
14874 
14875     @Override
getComponentEnabledSetting(ComponentName componentName, int userId)14876     public int getComponentEnabledSetting(ComponentName componentName, int userId) {
14877         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
14878         int uid = Binder.getCallingUid();
14879         enforceCrossUserPermission(uid, userId, false, false, "get component enabled");
14880         // reader
14881         synchronized (mPackages) {
14882             return mSettings.getComponentEnabledSettingLPr(componentName, userId);
14883         }
14884     }
14885 
14886     @Override
enterSafeMode()14887     public void enterSafeMode() {
14888         enforceSystemOrRoot("Only the system can request entering safe mode");
14889 
14890         if (!mSystemReady) {
14891             mSafeMode = true;
14892         }
14893     }
14894 
14895     @Override
systemReady()14896     public void systemReady() {
14897         mSystemReady = true;
14898 
14899         // Read the compatibilty setting when the system is ready.
14900         boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
14901                 mContext.getContentResolver(),
14902                 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
14903         PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
14904         if (DEBUG_SETTINGS) {
14905             Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
14906         }
14907 
14908         int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
14909 
14910         synchronized (mPackages) {
14911             // Verify that all of the preferred activity components actually
14912             // exist.  It is possible for applications to be updated and at
14913             // that point remove a previously declared activity component that
14914             // had been set as a preferred activity.  We try to clean this up
14915             // the next time we encounter that preferred activity, but it is
14916             // possible for the user flow to never be able to return to that
14917             // situation so here we do a sanity check to make sure we haven't
14918             // left any junk around.
14919             ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
14920             for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
14921                 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
14922                 removed.clear();
14923                 for (PreferredActivity pa : pir.filterSet()) {
14924                     if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
14925                         removed.add(pa);
14926                     }
14927                 }
14928                 if (removed.size() > 0) {
14929                     for (int r=0; r<removed.size(); r++) {
14930                         PreferredActivity pa = removed.get(r);
14931                         Slog.w(TAG, "Removing dangling preferred activity: "
14932                                 + pa.mPref.mComponent);
14933                         pir.removeFilter(pa);
14934                     }
14935                     mSettings.writePackageRestrictionsLPr(
14936                             mSettings.mPreferredActivities.keyAt(i));
14937                 }
14938             }
14939 
14940             for (int userId : UserManagerService.getInstance().getUserIds()) {
14941                 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
14942                     grantPermissionsUserIds = ArrayUtils.appendInt(
14943                             grantPermissionsUserIds, userId);
14944                 }
14945             }
14946         }
14947         sUserManager.systemReady();
14948 
14949         // If we upgraded grant all default permissions before kicking off.
14950         for (int userId : grantPermissionsUserIds) {
14951             mDefaultPermissionPolicy.grantDefaultPermissions(userId);
14952         }
14953 
14954         // Kick off any messages waiting for system ready
14955         if (mPostSystemReadyMessages != null) {
14956             for (Message msg : mPostSystemReadyMessages) {
14957                 msg.sendToTarget();
14958             }
14959             mPostSystemReadyMessages = null;
14960         }
14961 
14962         // Watch for external volumes that come and go over time
14963         final StorageManager storage = mContext.getSystemService(StorageManager.class);
14964         storage.registerListener(mStorageListener);
14965 
14966         mInstallerService.systemReady();
14967         mPackageDexOptimizer.systemReady();
14968 
14969         MountServiceInternal mountServiceInternal = LocalServices.getService(
14970                 MountServiceInternal.class);
14971         mountServiceInternal.addExternalStoragePolicy(
14972                 new MountServiceInternal.ExternalStorageMountPolicy() {
14973             @Override
14974             public int getMountMode(int uid, String packageName) {
14975                 if (Process.isIsolated(uid)) {
14976                     return Zygote.MOUNT_EXTERNAL_NONE;
14977                 }
14978                 if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
14979                     return Zygote.MOUNT_EXTERNAL_DEFAULT;
14980                 }
14981                 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
14982                     return Zygote.MOUNT_EXTERNAL_DEFAULT;
14983                 }
14984                 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
14985                     return Zygote.MOUNT_EXTERNAL_READ;
14986                 }
14987                 return Zygote.MOUNT_EXTERNAL_WRITE;
14988             }
14989 
14990             @Override
14991             public boolean hasExternalStorage(int uid, String packageName) {
14992                 return true;
14993             }
14994         });
14995     }
14996 
14997     @Override
isSafeMode()14998     public boolean isSafeMode() {
14999         return mSafeMode;
15000     }
15001 
15002     @Override
hasSystemUidErrors()15003     public boolean hasSystemUidErrors() {
15004         return mHasSystemUidErrors;
15005     }
15006 
arrayToString(int[] array)15007     static String arrayToString(int[] array) {
15008         StringBuffer buf = new StringBuffer(128);
15009         buf.append('[');
15010         if (array != null) {
15011             for (int i=0; i<array.length; i++) {
15012                 if (i > 0) buf.append(", ");
15013                 buf.append(array[i]);
15014             }
15015         }
15016         buf.append(']');
15017         return buf.toString();
15018     }
15019 
15020     static class DumpState {
15021         public static final int DUMP_LIBS = 1 << 0;
15022         public static final int DUMP_FEATURES = 1 << 1;
15023         public static final int DUMP_RESOLVERS = 1 << 2;
15024         public static final int DUMP_PERMISSIONS = 1 << 3;
15025         public static final int DUMP_PACKAGES = 1 << 4;
15026         public static final int DUMP_SHARED_USERS = 1 << 5;
15027         public static final int DUMP_MESSAGES = 1 << 6;
15028         public static final int DUMP_PROVIDERS = 1 << 7;
15029         public static final int DUMP_VERIFIERS = 1 << 8;
15030         public static final int DUMP_PREFERRED = 1 << 9;
15031         public static final int DUMP_PREFERRED_XML = 1 << 10;
15032         public static final int DUMP_KEYSETS = 1 << 11;
15033         public static final int DUMP_VERSION = 1 << 12;
15034         public static final int DUMP_INSTALLS = 1 << 13;
15035         public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 14;
15036         public static final int DUMP_DOMAIN_PREFERRED = 1 << 15;
15037 
15038         public static final int OPTION_SHOW_FILTERS = 1 << 0;
15039 
15040         private int mTypes;
15041 
15042         private int mOptions;
15043 
15044         private boolean mTitlePrinted;
15045 
15046         private SharedUserSetting mSharedUser;
15047 
isDumping(int type)15048         public boolean isDumping(int type) {
15049             if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
15050                 return true;
15051             }
15052 
15053             return (mTypes & type) != 0;
15054         }
15055 
setDump(int type)15056         public void setDump(int type) {
15057             mTypes |= type;
15058         }
15059 
isOptionEnabled(int option)15060         public boolean isOptionEnabled(int option) {
15061             return (mOptions & option) != 0;
15062         }
15063 
setOptionEnabled(int option)15064         public void setOptionEnabled(int option) {
15065             mOptions |= option;
15066         }
15067 
onTitlePrinted()15068         public boolean onTitlePrinted() {
15069             final boolean printed = mTitlePrinted;
15070             mTitlePrinted = true;
15071             return printed;
15072         }
15073 
getTitlePrinted()15074         public boolean getTitlePrinted() {
15075             return mTitlePrinted;
15076         }
15077 
setTitlePrinted(boolean enabled)15078         public void setTitlePrinted(boolean enabled) {
15079             mTitlePrinted = enabled;
15080         }
15081 
getSharedUser()15082         public SharedUserSetting getSharedUser() {
15083             return mSharedUser;
15084         }
15085 
setSharedUser(SharedUserSetting user)15086         public void setSharedUser(SharedUserSetting user) {
15087             mSharedUser = user;
15088         }
15089     }
15090 
15091     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)15092     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15093         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
15094                 != PackageManager.PERMISSION_GRANTED) {
15095             pw.println("Permission Denial: can't dump ActivityManager from from pid="
15096                     + Binder.getCallingPid()
15097                     + ", uid=" + Binder.getCallingUid()
15098                     + " without permission "
15099                     + android.Manifest.permission.DUMP);
15100             return;
15101         }
15102 
15103         DumpState dumpState = new DumpState();
15104         boolean fullPreferred = false;
15105         boolean checkin = false;
15106 
15107         String packageName = null;
15108         ArraySet<String> permissionNames = null;
15109 
15110         int opti = 0;
15111         while (opti < args.length) {
15112             String opt = args[opti];
15113             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15114                 break;
15115             }
15116             opti++;
15117 
15118             if ("-a".equals(opt)) {
15119                 // Right now we only know how to print all.
15120             } else if ("-h".equals(opt)) {
15121                 pw.println("Package manager dump options:");
15122                 pw.println("  [-h] [-f] [--checkin] [cmd] ...");
15123                 pw.println("    --checkin: dump for a checkin");
15124                 pw.println("    -f: print details of intent filters");
15125                 pw.println("    -h: print this help");
15126                 pw.println("  cmd may be one of:");
15127                 pw.println("    l[ibraries]: list known shared libraries");
15128                 pw.println("    f[ibraries]: list device features");
15129                 pw.println("    k[eysets]: print known keysets");
15130                 pw.println("    r[esolvers]: dump intent resolvers");
15131                 pw.println("    perm[issions]: dump permissions");
15132                 pw.println("    permission [name ...]: dump declaration and use of given permission");
15133                 pw.println("    pref[erred]: print preferred package settings");
15134                 pw.println("    preferred-xml [--full]: print preferred package settings as xml");
15135                 pw.println("    prov[iders]: dump content providers");
15136                 pw.println("    p[ackages]: dump installed packages");
15137                 pw.println("    s[hared-users]: dump shared user IDs");
15138                 pw.println("    m[essages]: print collected runtime messages");
15139                 pw.println("    v[erifiers]: print package verifier info");
15140                 pw.println("    d[omain-preferred-apps]: print domains preferred apps");
15141                 pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
15142                 pw.println("    version: print database version info");
15143                 pw.println("    write: write current settings now");
15144                 pw.println("    installs: details about install sessions");
15145                 pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
15146                 pw.println("    <package.name>: info about given package");
15147                 return;
15148             } else if ("--checkin".equals(opt)) {
15149                 checkin = true;
15150             } else if ("-f".equals(opt)) {
15151                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
15152             } else {
15153                 pw.println("Unknown argument: " + opt + "; use -h for help");
15154             }
15155         }
15156 
15157         // Is the caller requesting to dump a particular piece of data?
15158         if (opti < args.length) {
15159             String cmd = args[opti];
15160             opti++;
15161             // Is this a package name?
15162             if ("android".equals(cmd) || cmd.contains(".")) {
15163                 packageName = cmd;
15164                 // When dumping a single package, we always dump all of its
15165                 // filter information since the amount of data will be reasonable.
15166                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
15167             } else if ("check-permission".equals(cmd)) {
15168                 if (opti >= args.length) {
15169                     pw.println("Error: check-permission missing permission argument");
15170                     return;
15171                 }
15172                 String perm = args[opti];
15173                 opti++;
15174                 if (opti >= args.length) {
15175                     pw.println("Error: check-permission missing package argument");
15176                     return;
15177                 }
15178                 String pkg = args[opti];
15179                 opti++;
15180                 int user = UserHandle.getUserId(Binder.getCallingUid());
15181                 if (opti < args.length) {
15182                     try {
15183                         user = Integer.parseInt(args[opti]);
15184                     } catch (NumberFormatException e) {
15185                         pw.println("Error: check-permission user argument is not a number: "
15186                                 + args[opti]);
15187                         return;
15188                     }
15189                 }
15190                 pw.println(checkPermission(perm, pkg, user));
15191                 return;
15192             } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
15193                 dumpState.setDump(DumpState.DUMP_LIBS);
15194             } else if ("f".equals(cmd) || "features".equals(cmd)) {
15195                 dumpState.setDump(DumpState.DUMP_FEATURES);
15196             } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
15197                 dumpState.setDump(DumpState.DUMP_RESOLVERS);
15198             } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
15199                 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
15200             } else if ("permission".equals(cmd)) {
15201                 if (opti >= args.length) {
15202                     pw.println("Error: permission requires permission name");
15203                     return;
15204                 }
15205                 permissionNames = new ArraySet<>();
15206                 while (opti < args.length) {
15207                     permissionNames.add(args[opti]);
15208                     opti++;
15209                 }
15210                 dumpState.setDump(DumpState.DUMP_PERMISSIONS
15211                         | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
15212             } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
15213                 dumpState.setDump(DumpState.DUMP_PREFERRED);
15214             } else if ("preferred-xml".equals(cmd)) {
15215                 dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
15216                 if (opti < args.length && "--full".equals(args[opti])) {
15217                     fullPreferred = true;
15218                     opti++;
15219                 }
15220             } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
15221                 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
15222             } else if ("p".equals(cmd) || "packages".equals(cmd)) {
15223                 dumpState.setDump(DumpState.DUMP_PACKAGES);
15224             } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
15225                 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
15226             } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
15227                 dumpState.setDump(DumpState.DUMP_PROVIDERS);
15228             } else if ("m".equals(cmd) || "messages".equals(cmd)) {
15229                 dumpState.setDump(DumpState.DUMP_MESSAGES);
15230             } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
15231                 dumpState.setDump(DumpState.DUMP_VERIFIERS);
15232             } else if ("i".equals(cmd) || "ifv".equals(cmd)
15233                     || "intent-filter-verifiers".equals(cmd)) {
15234                 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
15235             } else if ("version".equals(cmd)) {
15236                 dumpState.setDump(DumpState.DUMP_VERSION);
15237             } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
15238                 dumpState.setDump(DumpState.DUMP_KEYSETS);
15239             } else if ("installs".equals(cmd)) {
15240                 dumpState.setDump(DumpState.DUMP_INSTALLS);
15241             } else if ("write".equals(cmd)) {
15242                 synchronized (mPackages) {
15243                     mSettings.writeLPr();
15244                     pw.println("Settings written.");
15245                     return;
15246                 }
15247             }
15248         }
15249 
15250         if (checkin) {
15251             pw.println("vers,1");
15252         }
15253 
15254         // reader
15255         synchronized (mPackages) {
15256             if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
15257                 if (!checkin) {
15258                     if (dumpState.onTitlePrinted())
15259                         pw.println();
15260                     pw.println("Database versions:");
15261                     mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
15262                 }
15263             }
15264 
15265             if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
15266                 if (!checkin) {
15267                     if (dumpState.onTitlePrinted())
15268                         pw.println();
15269                     pw.println("Verifiers:");
15270                     pw.print("  Required: ");
15271                     pw.print(mRequiredVerifierPackage);
15272                     pw.print(" (uid=");
15273                     pw.print(getPackageUid(mRequiredVerifierPackage, 0));
15274                     pw.println(")");
15275                 } else if (mRequiredVerifierPackage != null) {
15276                     pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
15277                     pw.print(","); pw.println(getPackageUid(mRequiredVerifierPackage, 0));
15278                 }
15279             }
15280 
15281             if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
15282                     packageName == null) {
15283                 if (mIntentFilterVerifierComponent != null) {
15284                     String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
15285                     if (!checkin) {
15286                         if (dumpState.onTitlePrinted())
15287                             pw.println();
15288                         pw.println("Intent Filter Verifier:");
15289                         pw.print("  Using: ");
15290                         pw.print(verifierPackageName);
15291                         pw.print(" (uid=");
15292                         pw.print(getPackageUid(verifierPackageName, 0));
15293                         pw.println(")");
15294                     } else if (verifierPackageName != null) {
15295                         pw.print("ifv,"); pw.print(verifierPackageName);
15296                         pw.print(","); pw.println(getPackageUid(verifierPackageName, 0));
15297                     }
15298                 } else {
15299                     pw.println();
15300                     pw.println("No Intent Filter Verifier available!");
15301                 }
15302             }
15303 
15304             if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
15305                 boolean printedHeader = false;
15306                 final Iterator<String> it = mSharedLibraries.keySet().iterator();
15307                 while (it.hasNext()) {
15308                     String name = it.next();
15309                     SharedLibraryEntry ent = mSharedLibraries.get(name);
15310                     if (!checkin) {
15311                         if (!printedHeader) {
15312                             if (dumpState.onTitlePrinted())
15313                                 pw.println();
15314                             pw.println("Libraries:");
15315                             printedHeader = true;
15316                         }
15317                         pw.print("  ");
15318                     } else {
15319                         pw.print("lib,");
15320                     }
15321                     pw.print(name);
15322                     if (!checkin) {
15323                         pw.print(" -> ");
15324                     }
15325                     if (ent.path != null) {
15326                         if (!checkin) {
15327                             pw.print("(jar) ");
15328                             pw.print(ent.path);
15329                         } else {
15330                             pw.print(",jar,");
15331                             pw.print(ent.path);
15332                         }
15333                     } else {
15334                         if (!checkin) {
15335                             pw.print("(apk) ");
15336                             pw.print(ent.apk);
15337                         } else {
15338                             pw.print(",apk,");
15339                             pw.print(ent.apk);
15340                         }
15341                     }
15342                     pw.println();
15343                 }
15344             }
15345 
15346             if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
15347                 if (dumpState.onTitlePrinted())
15348                     pw.println();
15349                 if (!checkin) {
15350                     pw.println("Features:");
15351                 }
15352                 Iterator<String> it = mAvailableFeatures.keySet().iterator();
15353                 while (it.hasNext()) {
15354                     String name = it.next();
15355                     if (!checkin) {
15356                         pw.print("  ");
15357                     } else {
15358                         pw.print("feat,");
15359                     }
15360                     pw.println(name);
15361                 }
15362             }
15363 
15364             if (!checkin && dumpState.isDumping(DumpState.DUMP_RESOLVERS)) {
15365                 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
15366                         : "Activity Resolver Table:", "  ", packageName,
15367                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
15368                     dumpState.setTitlePrinted(true);
15369                 }
15370                 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
15371                         : "Receiver Resolver Table:", "  ", packageName,
15372                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
15373                     dumpState.setTitlePrinted(true);
15374                 }
15375                 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
15376                         : "Service Resolver Table:", "  ", packageName,
15377                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
15378                     dumpState.setTitlePrinted(true);
15379                 }
15380                 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
15381                         : "Provider Resolver Table:", "  ", packageName,
15382                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
15383                     dumpState.setTitlePrinted(true);
15384                 }
15385             }
15386 
15387             if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
15388                 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
15389                     PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
15390                     int user = mSettings.mPreferredActivities.keyAt(i);
15391                     if (pir.dump(pw,
15392                             dumpState.getTitlePrinted()
15393                                 ? "\nPreferred Activities User " + user + ":"
15394                                 : "Preferred Activities User " + user + ":", "  ",
15395                             packageName, true, false)) {
15396                         dumpState.setTitlePrinted(true);
15397                     }
15398                 }
15399             }
15400 
15401             if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
15402                 pw.flush();
15403                 FileOutputStream fout = new FileOutputStream(fd);
15404                 BufferedOutputStream str = new BufferedOutputStream(fout);
15405                 XmlSerializer serializer = new FastXmlSerializer();
15406                 try {
15407                     serializer.setOutput(str, StandardCharsets.UTF_8.name());
15408                     serializer.startDocument(null, true);
15409                     serializer.setFeature(
15410                             "http://xmlpull.org/v1/doc/features.html#indent-output", true);
15411                     mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
15412                     serializer.endDocument();
15413                     serializer.flush();
15414                 } catch (IllegalArgumentException e) {
15415                     pw.println("Failed writing: " + e);
15416                 } catch (IllegalStateException e) {
15417                     pw.println("Failed writing: " + e);
15418                 } catch (IOException e) {
15419                     pw.println("Failed writing: " + e);
15420                 }
15421             }
15422 
15423             if (!checkin
15424                     && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
15425                     && packageName == null) {
15426                 pw.println();
15427                 int count = mSettings.mPackages.size();
15428                 if (count == 0) {
15429                     pw.println("No applications!");
15430                     pw.println();
15431                 } else {
15432                     final String prefix = "  ";
15433                     Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
15434                     if (allPackageSettings.size() == 0) {
15435                         pw.println("No domain preferred apps!");
15436                         pw.println();
15437                     } else {
15438                         pw.println("App verification status:");
15439                         pw.println();
15440                         count = 0;
15441                         for (PackageSetting ps : allPackageSettings) {
15442                             IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
15443                             if (ivi == null || ivi.getPackageName() == null) continue;
15444                             pw.println(prefix + "Package: " + ivi.getPackageName());
15445                             pw.println(prefix + "Domains: " + ivi.getDomainsString());
15446                             pw.println(prefix + "Status:  " + ivi.getStatusString());
15447                             pw.println();
15448                             count++;
15449                         }
15450                         if (count == 0) {
15451                             pw.println(prefix + "No app verification established.");
15452                             pw.println();
15453                         }
15454                         for (int userId : sUserManager.getUserIds()) {
15455                             pw.println("App linkages for user " + userId + ":");
15456                             pw.println();
15457                             count = 0;
15458                             for (PackageSetting ps : allPackageSettings) {
15459                                 final long status = ps.getDomainVerificationStatusForUser(userId);
15460                                 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
15461                                     continue;
15462                                 }
15463                                 pw.println(prefix + "Package: " + ps.name);
15464                                 pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
15465                                 String statusStr = IntentFilterVerificationInfo.
15466                                         getStatusStringFromValue(status);
15467                                 pw.println(prefix + "Status:  " + statusStr);
15468                                 pw.println();
15469                                 count++;
15470                             }
15471                             if (count == 0) {
15472                                 pw.println(prefix + "No configured app linkages.");
15473                                 pw.println();
15474                             }
15475                         }
15476                     }
15477                 }
15478             }
15479 
15480             if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
15481                 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
15482                 if (packageName == null && permissionNames == null) {
15483                     for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
15484                         if (iperm == 0) {
15485                             if (dumpState.onTitlePrinted())
15486                                 pw.println();
15487                             pw.println("AppOp Permissions:");
15488                         }
15489                         pw.print("  AppOp Permission ");
15490                         pw.print(mAppOpPermissionPackages.keyAt(iperm));
15491                         pw.println(":");
15492                         ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
15493                         for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
15494                             pw.print("    "); pw.println(pkgs.valueAt(ipkg));
15495                         }
15496                     }
15497                 }
15498             }
15499 
15500             if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
15501                 boolean printedSomething = false;
15502                 for (PackageParser.Provider p : mProviders.mProviders.values()) {
15503                     if (packageName != null && !packageName.equals(p.info.packageName)) {
15504                         continue;
15505                     }
15506                     if (!printedSomething) {
15507                         if (dumpState.onTitlePrinted())
15508                             pw.println();
15509                         pw.println("Registered ContentProviders:");
15510                         printedSomething = true;
15511                     }
15512                     pw.print("  "); p.printComponentShortName(pw); pw.println(":");
15513                     pw.print("    "); pw.println(p.toString());
15514                 }
15515                 printedSomething = false;
15516                 for (Map.Entry<String, PackageParser.Provider> entry :
15517                         mProvidersByAuthority.entrySet()) {
15518                     PackageParser.Provider p = entry.getValue();
15519                     if (packageName != null && !packageName.equals(p.info.packageName)) {
15520                         continue;
15521                     }
15522                     if (!printedSomething) {
15523                         if (dumpState.onTitlePrinted())
15524                             pw.println();
15525                         pw.println("ContentProvider Authorities:");
15526                         printedSomething = true;
15527                     }
15528                     pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
15529                     pw.print("    "); pw.println(p.toString());
15530                     if (p.info != null && p.info.applicationInfo != null) {
15531                         final String appInfo = p.info.applicationInfo.toString();
15532                         pw.print("      applicationInfo="); pw.println(appInfo);
15533                     }
15534                 }
15535             }
15536 
15537             if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
15538                 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
15539             }
15540 
15541             if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
15542                 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
15543             }
15544 
15545             if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
15546                 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
15547             }
15548 
15549             if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
15550                 // XXX should handle packageName != null by dumping only install data that
15551                 // the given package is involved with.
15552                 if (dumpState.onTitlePrinted()) pw.println();
15553                 mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
15554             }
15555 
15556             if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
15557                 if (dumpState.onTitlePrinted()) pw.println();
15558                 mSettings.dumpReadMessagesLPr(pw, dumpState);
15559 
15560                 pw.println();
15561                 pw.println("Package warning messages:");
15562                 BufferedReader in = null;
15563                 String line = null;
15564                 try {
15565                     in = new BufferedReader(new FileReader(getSettingsProblemFile()));
15566                     while ((line = in.readLine()) != null) {
15567                         if (line.contains("ignored: updated version")) continue;
15568                         pw.println(line);
15569                     }
15570                 } catch (IOException ignored) {
15571                 } finally {
15572                     IoUtils.closeQuietly(in);
15573                 }
15574             }
15575 
15576             if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
15577                 BufferedReader in = null;
15578                 String line = null;
15579                 try {
15580                     in = new BufferedReader(new FileReader(getSettingsProblemFile()));
15581                     while ((line = in.readLine()) != null) {
15582                         if (line.contains("ignored: updated version")) continue;
15583                         pw.print("msg,");
15584                         pw.println(line);
15585                     }
15586                 } catch (IOException ignored) {
15587                 } finally {
15588                     IoUtils.closeQuietly(in);
15589                 }
15590             }
15591         }
15592     }
15593 
dumpDomainString(String packageName)15594     private String dumpDomainString(String packageName) {
15595         List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName);
15596         List<IntentFilter> filters = getAllIntentFilters(packageName);
15597 
15598         ArraySet<String> result = new ArraySet<>();
15599         if (iviList.size() > 0) {
15600             for (IntentFilterVerificationInfo ivi : iviList) {
15601                 for (String host : ivi.getDomains()) {
15602                     result.add(host);
15603                 }
15604             }
15605         }
15606         if (filters != null && filters.size() > 0) {
15607             for (IntentFilter filter : filters) {
15608                 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
15609                         && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
15610                                 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
15611                     result.addAll(filter.getHostsList());
15612                 }
15613             }
15614         }
15615 
15616         StringBuilder sb = new StringBuilder(result.size() * 16);
15617         for (String domain : result) {
15618             if (sb.length() > 0) sb.append(" ");
15619             sb.append(domain);
15620         }
15621         return sb.toString();
15622     }
15623 
15624     // ------- apps on sdcard specific code -------
15625     static final boolean DEBUG_SD_INSTALL = false;
15626 
15627     private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
15628 
15629     private static final String SD_ENCRYPTION_ALGORITHM = "AES";
15630 
15631     private boolean mMediaMounted = false;
15632 
getEncryptKey()15633     static String getEncryptKey() {
15634         try {
15635             String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
15636                     SD_ENCRYPTION_KEYSTORE_NAME);
15637             if (sdEncKey == null) {
15638                 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
15639                         SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
15640                 if (sdEncKey == null) {
15641                     Slog.e(TAG, "Failed to create encryption keys");
15642                     return null;
15643                 }
15644             }
15645             return sdEncKey;
15646         } catch (NoSuchAlgorithmException nsae) {
15647             Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
15648             return null;
15649         } catch (IOException ioe) {
15650             Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
15651             return null;
15652         }
15653     }
15654 
15655     /*
15656      * Update media status on PackageManager.
15657      */
15658     @Override
updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus)15659     public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
15660         int callingUid = Binder.getCallingUid();
15661         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15662             throw new SecurityException("Media status can only be updated by the system");
15663         }
15664         // reader; this apparently protects mMediaMounted, but should probably
15665         // be a different lock in that case.
15666         synchronized (mPackages) {
15667             Log.i(TAG, "Updating external media status from "
15668                     + (mMediaMounted ? "mounted" : "unmounted") + " to "
15669                     + (mediaStatus ? "mounted" : "unmounted"));
15670             if (DEBUG_SD_INSTALL)
15671                 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
15672                         + ", mMediaMounted=" + mMediaMounted);
15673             if (mediaStatus == mMediaMounted) {
15674                 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
15675                         : 0, -1);
15676                 mHandler.sendMessage(msg);
15677                 return;
15678             }
15679             mMediaMounted = mediaStatus;
15680         }
15681         // Queue up an async operation since the package installation may take a
15682         // little while.
15683         mHandler.post(new Runnable() {
15684             public void run() {
15685                 updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
15686             }
15687         });
15688     }
15689 
15690     /**
15691      * Called by MountService when the initial ASECs to scan are available.
15692      * Should block until all the ASEC containers are finished being scanned.
15693      */
scanAvailableAsecs()15694     public void scanAvailableAsecs() {
15695         updateExternalMediaStatusInner(true, false, false);
15696         if (mShouldRestoreconData) {
15697             SELinuxMMAC.setRestoreconDone();
15698             mShouldRestoreconData = false;
15699         }
15700     }
15701 
15702     /*
15703      * Collect information of applications on external media, map them against
15704      * existing containers and update information based on current mount status.
15705      * Please note that we always have to report status if reportStatus has been
15706      * set to true especially when unloading packages.
15707      */
updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, boolean externalStorage)15708     private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
15709             boolean externalStorage) {
15710         ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
15711         int[] uidArr = EmptyArray.INT;
15712 
15713         final String[] list = PackageHelper.getSecureContainerList();
15714         if (ArrayUtils.isEmpty(list)) {
15715             Log.i(TAG, "No secure containers found");
15716         } else {
15717             // Process list of secure containers and categorize them
15718             // as active or stale based on their package internal state.
15719 
15720             // reader
15721             synchronized (mPackages) {
15722                 for (String cid : list) {
15723                     // Leave stages untouched for now; installer service owns them
15724                     if (PackageInstallerService.isStageName(cid)) continue;
15725 
15726                     if (DEBUG_SD_INSTALL)
15727                         Log.i(TAG, "Processing container " + cid);
15728                     String pkgName = getAsecPackageName(cid);
15729                     if (pkgName == null) {
15730                         Slog.i(TAG, "Found stale container " + cid + " with no package name");
15731                         continue;
15732                     }
15733                     if (DEBUG_SD_INSTALL)
15734                         Log.i(TAG, "Looking for pkg : " + pkgName);
15735 
15736                     final PackageSetting ps = mSettings.mPackages.get(pkgName);
15737                     if (ps == null) {
15738                         Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
15739                         continue;
15740                     }
15741 
15742                     /*
15743                      * Skip packages that are not external if we're unmounting
15744                      * external storage.
15745                      */
15746                     if (externalStorage && !isMounted && !isExternal(ps)) {
15747                         continue;
15748                     }
15749 
15750                     final AsecInstallArgs args = new AsecInstallArgs(cid,
15751                             getAppDexInstructionSets(ps), ps.isForwardLocked());
15752                     // The package status is changed only if the code path
15753                     // matches between settings and the container id.
15754                     if (ps.codePathString != null
15755                             && ps.codePathString.startsWith(args.getCodePath())) {
15756                         if (DEBUG_SD_INSTALL) {
15757                             Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
15758                                     + " at code path: " + ps.codePathString);
15759                         }
15760 
15761                         // We do have a valid package installed on sdcard
15762                         processCids.put(args, ps.codePathString);
15763                         final int uid = ps.appId;
15764                         if (uid != -1) {
15765                             uidArr = ArrayUtils.appendInt(uidArr, uid);
15766                         }
15767                     } else {
15768                         Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
15769                                 + ps.codePathString);
15770                     }
15771                 }
15772             }
15773 
15774             Arrays.sort(uidArr);
15775         }
15776 
15777         // Process packages with valid entries.
15778         if (isMounted) {
15779             if (DEBUG_SD_INSTALL)
15780                 Log.i(TAG, "Loading packages");
15781             loadMediaPackages(processCids, uidArr, externalStorage);
15782             startCleaningPackages();
15783             mInstallerService.onSecureContainersAvailable();
15784         } else {
15785             if (DEBUG_SD_INSTALL)
15786                 Log.i(TAG, "Unloading packages");
15787             unloadMediaPackages(processCids, uidArr, reportStatus);
15788         }
15789     }
15790 
sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver)15791     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
15792             ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
15793         final int size = infos.size();
15794         final String[] packageNames = new String[size];
15795         final int[] packageUids = new int[size];
15796         for (int i = 0; i < size; i++) {
15797             final ApplicationInfo info = infos.get(i);
15798             packageNames[i] = info.packageName;
15799             packageUids[i] = info.uid;
15800         }
15801         sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
15802                 finishedReceiver);
15803     }
15804 
sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver)15805     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
15806             ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
15807         sendResourcesChangedBroadcast(mediaStatus, replacing,
15808                 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
15809     }
15810 
sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver)15811     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
15812             String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
15813         int size = pkgList.length;
15814         if (size > 0) {
15815             // Send broadcasts here
15816             Bundle extras = new Bundle();
15817             extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
15818             if (uidArr != null) {
15819                 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
15820             }
15821             if (replacing) {
15822                 extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
15823             }
15824             String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
15825                     : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
15826             sendPackageBroadcast(action, null, extras, null, finishedReceiver, null);
15827         }
15828     }
15829 
15830    /*
15831      * Look at potentially valid container ids from processCids If package
15832      * information doesn't match the one on record or package scanning fails,
15833      * the cid is added to list of removeCids. We currently don't delete stale
15834      * containers.
15835      */
loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr, boolean externalStorage)15836     private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr,
15837             boolean externalStorage) {
15838         ArrayList<String> pkgList = new ArrayList<String>();
15839         Set<AsecInstallArgs> keys = processCids.keySet();
15840 
15841         for (AsecInstallArgs args : keys) {
15842             String codePath = processCids.get(args);
15843             if (DEBUG_SD_INSTALL)
15844                 Log.i(TAG, "Loading container : " + args.cid);
15845             int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15846             try {
15847                 // Make sure there are no container errors first.
15848                 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
15849                     Slog.e(TAG, "Failed to mount cid : " + args.cid
15850                             + " when installing from sdcard");
15851                     continue;
15852                 }
15853                 // Check code path here.
15854                 if (codePath == null || !codePath.startsWith(args.getCodePath())) {
15855                     Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
15856                             + " does not match one in settings " + codePath);
15857                     continue;
15858                 }
15859                 // Parse package
15860                 int parseFlags = mDefParseFlags;
15861                 if (args.isExternalAsec()) {
15862                     parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
15863                 }
15864                 if (args.isFwdLocked()) {
15865                     parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
15866                 }
15867 
15868                 synchronized (mInstallLock) {
15869                     PackageParser.Package pkg = null;
15870                     try {
15871                         pkg = scanPackageLI(new File(codePath), parseFlags, 0, 0, null);
15872                     } catch (PackageManagerException e) {
15873                         Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
15874                     }
15875                     // Scan the package
15876                     if (pkg != null) {
15877                         /*
15878                          * TODO why is the lock being held? doPostInstall is
15879                          * called in other places without the lock. This needs
15880                          * to be straightened out.
15881                          */
15882                         // writer
15883                         synchronized (mPackages) {
15884                             retCode = PackageManager.INSTALL_SUCCEEDED;
15885                             pkgList.add(pkg.packageName);
15886                             // Post process args
15887                             args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
15888                                     pkg.applicationInfo.uid);
15889                         }
15890                     } else {
15891                         Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
15892                     }
15893                 }
15894 
15895             } finally {
15896                 if (retCode != PackageManager.INSTALL_SUCCEEDED) {
15897                     Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
15898                 }
15899             }
15900         }
15901         // writer
15902         synchronized (mPackages) {
15903             // If the platform SDK has changed since the last time we booted,
15904             // we need to re-grant app permission to catch any new ones that
15905             // appear. This is really a hack, and means that apps can in some
15906             // cases get permissions that the user didn't initially explicitly
15907             // allow... it would be nice to have some better way to handle
15908             // this situation.
15909             final VersionInfo ver = externalStorage ? mSettings.getExternalVersion()
15910                     : mSettings.getInternalVersion();
15911             final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL
15912                     : StorageManager.UUID_PRIVATE_INTERNAL;
15913 
15914             int updateFlags = UPDATE_PERMISSIONS_ALL;
15915             if (ver.sdkVersion != mSdkVersion) {
15916                 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
15917                         + mSdkVersion + "; regranting permissions for external");
15918                 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
15919             }
15920             updatePermissionsLPw(null, null, volumeUuid, updateFlags);
15921 
15922             // Yay, everything is now upgraded
15923             ver.forceCurrent();
15924 
15925             // can downgrade to reader
15926             // Persist settings
15927             mSettings.writeLPr();
15928         }
15929         // Send a broadcast to let everyone know we are done processing
15930         if (pkgList.size() > 0) {
15931             sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
15932         }
15933     }
15934 
15935    /*
15936      * Utility method to unload a list of specified containers
15937      */
unloadAllContainers(Set<AsecInstallArgs> cidArgs)15938     private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
15939         // Just unmount all valid containers.
15940         for (AsecInstallArgs arg : cidArgs) {
15941             synchronized (mInstallLock) {
15942                 arg.doPostDeleteLI(false);
15943            }
15944        }
15945    }
15946 
15947     /*
15948      * Unload packages mounted on external media. This involves deleting package
15949      * data from internal structures, sending broadcasts about diabled packages,
15950      * gc'ing to free up references, unmounting all secure containers
15951      * corresponding to packages on external media, and posting a
15952      * UPDATED_MEDIA_STATUS message if status has been requested. Please note
15953      * that we always have to post this message if status has been requested no
15954      * matter what.
15955      */
unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], final boolean reportStatus)15956     private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
15957             final boolean reportStatus) {
15958         if (DEBUG_SD_INSTALL)
15959             Log.i(TAG, "unloading media packages");
15960         ArrayList<String> pkgList = new ArrayList<String>();
15961         ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
15962         final Set<AsecInstallArgs> keys = processCids.keySet();
15963         for (AsecInstallArgs args : keys) {
15964             String pkgName = args.getPackageName();
15965             if (DEBUG_SD_INSTALL)
15966                 Log.i(TAG, "Trying to unload pkg : " + pkgName);
15967             // Delete package internally
15968             PackageRemovedInfo outInfo = new PackageRemovedInfo();
15969             synchronized (mInstallLock) {
15970                 boolean res = deletePackageLI(pkgName, null, false, null, null,
15971                         PackageManager.DELETE_KEEP_DATA, outInfo, false);
15972                 if (res) {
15973                     pkgList.add(pkgName);
15974                 } else {
15975                     Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
15976                     failedList.add(args);
15977                 }
15978             }
15979         }
15980 
15981         // reader
15982         synchronized (mPackages) {
15983             // We didn't update the settings after removing each package;
15984             // write them now for all packages.
15985             mSettings.writeLPr();
15986         }
15987 
15988         // We have to absolutely send UPDATED_MEDIA_STATUS only
15989         // after confirming that all the receivers processed the ordered
15990         // broadcast when packages get disabled, force a gc to clean things up.
15991         // and unload all the containers.
15992         if (pkgList.size() > 0) {
15993             sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
15994                     new IIntentReceiver.Stub() {
15995                 public void performReceive(Intent intent, int resultCode, String data,
15996                         Bundle extras, boolean ordered, boolean sticky,
15997                         int sendingUser) throws RemoteException {
15998                     Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
15999                             reportStatus ? 1 : 0, 1, keys);
16000                     mHandler.sendMessage(msg);
16001                 }
16002             });
16003         } else {
16004             Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
16005                     keys);
16006             mHandler.sendMessage(msg);
16007         }
16008     }
16009 
loadPrivatePackages(final VolumeInfo vol)16010     private void loadPrivatePackages(final VolumeInfo vol) {
16011         mHandler.post(new Runnable() {
16012             @Override
16013             public void run() {
16014                 loadPrivatePackagesInner(vol);
16015             }
16016         });
16017     }
16018 
loadPrivatePackagesInner(VolumeInfo vol)16019     private void loadPrivatePackagesInner(VolumeInfo vol) {
16020         final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
16021         final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
16022 
16023         final VersionInfo ver;
16024         final List<PackageSetting> packages;
16025         synchronized (mPackages) {
16026             ver = mSettings.findOrCreateVersion(vol.fsUuid);
16027             packages = mSettings.getVolumePackagesLPr(vol.fsUuid);
16028         }
16029 
16030         for (PackageSetting ps : packages) {
16031             synchronized (mInstallLock) {
16032                 final PackageParser.Package pkg;
16033                 try {
16034                     pkg = scanPackageLI(ps.codePath, parseFlags, SCAN_INITIAL, 0L, null);
16035                     loaded.add(pkg.applicationInfo);
16036                 } catch (PackageManagerException e) {
16037                     Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
16038                 }
16039 
16040                 if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
16041                     deleteCodeCacheDirsLI(ps.volumeUuid, ps.name);
16042                 }
16043             }
16044         }
16045 
16046         synchronized (mPackages) {
16047             int updateFlags = UPDATE_PERMISSIONS_ALL;
16048             if (ver.sdkVersion != mSdkVersion) {
16049                 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
16050                         + mSdkVersion + "; regranting permissions for " + vol.fsUuid);
16051                 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
16052             }
16053             updatePermissionsLPw(null, null, vol.fsUuid, updateFlags);
16054 
16055             // Yay, everything is now upgraded
16056             ver.forceCurrent();
16057 
16058             mSettings.writeLPr();
16059         }
16060 
16061         if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
16062         sendResourcesChangedBroadcast(true, false, loaded, null);
16063     }
16064 
unloadPrivatePackages(final VolumeInfo vol)16065     private void unloadPrivatePackages(final VolumeInfo vol) {
16066         mHandler.post(new Runnable() {
16067             @Override
16068             public void run() {
16069                 unloadPrivatePackagesInner(vol);
16070             }
16071         });
16072     }
16073 
unloadPrivatePackagesInner(VolumeInfo vol)16074     private void unloadPrivatePackagesInner(VolumeInfo vol) {
16075         final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
16076         synchronized (mInstallLock) {
16077         synchronized (mPackages) {
16078             final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(vol.fsUuid);
16079             for (PackageSetting ps : packages) {
16080                 if (ps.pkg == null) continue;
16081 
16082                 final ApplicationInfo info = ps.pkg.applicationInfo;
16083                 final PackageRemovedInfo outInfo = new PackageRemovedInfo();
16084                 if (deletePackageLI(ps.name, null, false, null, null,
16085                         PackageManager.DELETE_KEEP_DATA, outInfo, false)) {
16086                     unloaded.add(info);
16087                 } else {
16088                     Slog.w(TAG, "Failed to unload " + ps.codePath);
16089                 }
16090             }
16091 
16092             mSettings.writeLPr();
16093         }
16094         }
16095 
16096         if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
16097         sendResourcesChangedBroadcast(false, false, unloaded, null);
16098     }
16099 
16100     /**
16101      * Examine all users present on given mounted volume, and destroy data
16102      * belonging to users that are no longer valid, or whose user ID has been
16103      * recycled.
16104      */
reconcileUsers(String volumeUuid)16105     private void reconcileUsers(String volumeUuid) {
16106         final File[] files = FileUtils
16107                 .listFilesOrEmpty(Environment.getDataUserDirectory(volumeUuid));
16108         for (File file : files) {
16109             if (!file.isDirectory()) continue;
16110 
16111             final int userId;
16112             final UserInfo info;
16113             try {
16114                 userId = Integer.parseInt(file.getName());
16115                 info = sUserManager.getUserInfo(userId);
16116             } catch (NumberFormatException e) {
16117                 Slog.w(TAG, "Invalid user directory " + file);
16118                 continue;
16119             }
16120 
16121             boolean destroyUser = false;
16122             if (info == null) {
16123                 logCriticalInfo(Log.WARN, "Destroying user directory " + file
16124                         + " because no matching user was found");
16125                 destroyUser = true;
16126             } else {
16127                 try {
16128                     UserManagerService.enforceSerialNumber(file, info.serialNumber);
16129                 } catch (IOException e) {
16130                     logCriticalInfo(Log.WARN, "Destroying user directory " + file
16131                             + " because we failed to enforce serial number: " + e);
16132                     destroyUser = true;
16133                 }
16134             }
16135 
16136             if (destroyUser) {
16137                 synchronized (mInstallLock) {
16138                     mInstaller.removeUserDataDirs(volumeUuid, userId);
16139                 }
16140             }
16141         }
16142 
16143         final UserManager um = mContext.getSystemService(UserManager.class);
16144         for (UserInfo user : um.getUsers()) {
16145             final File userDir = Environment.getDataUserDirectory(volumeUuid, user.id);
16146             if (userDir.exists()) continue;
16147 
16148             try {
16149                 UserManagerService.prepareUserDirectory(mContext, volumeUuid, user.id);
16150                 UserManagerService.enforceSerialNumber(userDir, user.serialNumber);
16151             } catch (IOException e) {
16152                 Log.wtf(TAG, "Failed to create user directory on " + volumeUuid, e);
16153             }
16154         }
16155     }
16156 
16157     /**
16158      * Examine all apps present on given mounted volume, and destroy apps that
16159      * aren't expected, either due to uninstallation or reinstallation on
16160      * another volume.
16161      */
reconcileApps(String volumeUuid)16162     private void reconcileApps(String volumeUuid) {
16163         final File[] files = FileUtils
16164                 .listFilesOrEmpty(Environment.getDataAppDirectory(volumeUuid));
16165         for (File file : files) {
16166             final boolean isPackage = (isApkFile(file) || file.isDirectory())
16167                     && !PackageInstallerService.isStageName(file.getName());
16168             if (!isPackage) {
16169                 // Ignore entries which are not packages
16170                 continue;
16171             }
16172 
16173             boolean destroyApp = false;
16174             String packageName = null;
16175             try {
16176                 final PackageLite pkg = PackageParser.parsePackageLite(file,
16177                         PackageParser.PARSE_MUST_BE_APK);
16178                 packageName = pkg.packageName;
16179 
16180                 synchronized (mPackages) {
16181                     final PackageSetting ps = mSettings.mPackages.get(packageName);
16182                     if (ps == null) {
16183                         logCriticalInfo(Log.WARN, "Destroying " + packageName + " on + "
16184                                 + volumeUuid + " because we found no install record");
16185                         destroyApp = true;
16186                     } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
16187                         logCriticalInfo(Log.WARN, "Destroying " + packageName + " on "
16188                                 + volumeUuid + " because we expected it on " + ps.volumeUuid);
16189                         destroyApp = true;
16190                     }
16191                 }
16192 
16193             } catch (PackageParserException e) {
16194                 logCriticalInfo(Log.WARN, "Destroying " + file + " due to parse failure: " + e);
16195                 destroyApp = true;
16196             }
16197 
16198             if (destroyApp) {
16199                 synchronized (mInstallLock) {
16200                     if (packageName != null) {
16201                         removeDataDirsLI(volumeUuid, packageName);
16202                     }
16203                     if (file.isDirectory()) {
16204                         mInstaller.rmPackageDir(file.getAbsolutePath());
16205                     } else {
16206                         file.delete();
16207                     }
16208                 }
16209             }
16210         }
16211     }
16212 
unfreezePackage(String packageName)16213     private void unfreezePackage(String packageName) {
16214         synchronized (mPackages) {
16215             final PackageSetting ps = mSettings.mPackages.get(packageName);
16216             if (ps != null) {
16217                 ps.frozen = false;
16218             }
16219         }
16220     }
16221 
16222     @Override
movePackage(final String packageName, final String volumeUuid)16223     public int movePackage(final String packageName, final String volumeUuid) {
16224         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
16225 
16226         final int moveId = mNextMoveId.getAndIncrement();
16227         mHandler.post(new Runnable() {
16228             @Override
16229             public void run() {
16230                 try {
16231                     movePackageInternal(packageName, volumeUuid, moveId);
16232                 } catch (PackageManagerException e) {
16233                     Slog.w(TAG, "Failed to move " + packageName, e);
16234                     mMoveCallbacks.notifyStatusChanged(moveId,
16235                             PackageManager.MOVE_FAILED_INTERNAL_ERROR);
16236                 }
16237             }
16238         });
16239         return moveId;
16240     }
16241 
movePackageInternal(final String packageName, final String volumeUuid, final int moveId)16242     private void movePackageInternal(final String packageName, final String volumeUuid,
16243             final int moveId) throws PackageManagerException {
16244         final UserHandle user = new UserHandle(UserHandle.getCallingUserId());
16245         final StorageManager storage = mContext.getSystemService(StorageManager.class);
16246         final PackageManager pm = mContext.getPackageManager();
16247 
16248         final boolean currentAsec;
16249         final String currentVolumeUuid;
16250         final File codeFile;
16251         final String installerPackageName;
16252         final String packageAbiOverride;
16253         final int appId;
16254         final String seinfo;
16255         final String label;
16256 
16257         // reader
16258         synchronized (mPackages) {
16259             final PackageParser.Package pkg = mPackages.get(packageName);
16260             final PackageSetting ps = mSettings.mPackages.get(packageName);
16261             if (pkg == null || ps == null) {
16262                 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
16263             }
16264 
16265             if (pkg.applicationInfo.isSystemApp()) {
16266                 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
16267                         "Cannot move system application");
16268             }
16269 
16270             if (pkg.applicationInfo.isExternalAsec()) {
16271                 currentAsec = true;
16272                 currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
16273             } else if (pkg.applicationInfo.isForwardLocked()) {
16274                 currentAsec = true;
16275                 currentVolumeUuid = "forward_locked";
16276             } else {
16277                 currentAsec = false;
16278                 currentVolumeUuid = ps.volumeUuid;
16279 
16280                 final File probe = new File(pkg.codePath);
16281                 final File probeOat = new File(probe, "oat");
16282                 if (!probe.isDirectory() || !probeOat.isDirectory()) {
16283                     throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
16284                             "Move only supported for modern cluster style installs");
16285                 }
16286             }
16287 
16288             if (Objects.equals(currentVolumeUuid, volumeUuid)) {
16289                 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
16290                         "Package already moved to " + volumeUuid);
16291             }
16292 
16293             if (ps.frozen) {
16294                 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
16295                         "Failed to move already frozen package");
16296             }
16297             ps.frozen = true;
16298 
16299             codeFile = new File(pkg.codePath);
16300             installerPackageName = ps.installerPackageName;
16301             packageAbiOverride = ps.cpuAbiOverrideString;
16302             appId = UserHandle.getAppId(pkg.applicationInfo.uid);
16303             seinfo = pkg.applicationInfo.seinfo;
16304             label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
16305         }
16306 
16307         // Now that we're guarded by frozen state, kill app during move
16308         final long token = Binder.clearCallingIdentity();
16309         try {
16310             killApplication(packageName, appId, "move pkg");
16311         } finally {
16312             Binder.restoreCallingIdentity(token);
16313         }
16314 
16315         final Bundle extras = new Bundle();
16316         extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
16317         extras.putString(Intent.EXTRA_TITLE, label);
16318         mMoveCallbacks.notifyCreated(moveId, extras);
16319 
16320         int installFlags;
16321         final boolean moveCompleteApp;
16322         final File measurePath;
16323 
16324         if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
16325             installFlags = INSTALL_INTERNAL;
16326             moveCompleteApp = !currentAsec;
16327             measurePath = Environment.getDataAppDirectory(volumeUuid);
16328         } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
16329             installFlags = INSTALL_EXTERNAL;
16330             moveCompleteApp = false;
16331             measurePath = storage.getPrimaryPhysicalVolume().getPath();
16332         } else {
16333             final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
16334             if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
16335                     || !volume.isMountedWritable()) {
16336                 unfreezePackage(packageName);
16337                 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
16338                         "Move location not mounted private volume");
16339             }
16340 
16341             Preconditions.checkState(!currentAsec);
16342 
16343             installFlags = INSTALL_INTERNAL;
16344             moveCompleteApp = true;
16345             measurePath = Environment.getDataAppDirectory(volumeUuid);
16346         }
16347 
16348         final PackageStats stats = new PackageStats(null, -1);
16349         synchronized (mInstaller) {
16350             if (!getPackageSizeInfoLI(packageName, -1, stats)) {
16351                 unfreezePackage(packageName);
16352                 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
16353                         "Failed to measure package size");
16354             }
16355         }
16356 
16357         if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
16358                 + stats.dataSize);
16359 
16360         final long startFreeBytes = measurePath.getFreeSpace();
16361         final long sizeBytes;
16362         if (moveCompleteApp) {
16363             sizeBytes = stats.codeSize + stats.dataSize;
16364         } else {
16365             sizeBytes = stats.codeSize;
16366         }
16367 
16368         if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
16369             unfreezePackage(packageName);
16370             throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
16371                     "Not enough free space to move");
16372         }
16373 
16374         mMoveCallbacks.notifyStatusChanged(moveId, 10);
16375 
16376         final CountDownLatch installedLatch = new CountDownLatch(1);
16377         final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
16378             @Override
16379             public void onUserActionRequired(Intent intent) throws RemoteException {
16380                 throw new IllegalStateException();
16381             }
16382 
16383             @Override
16384             public void onPackageInstalled(String basePackageName, int returnCode, String msg,
16385                     Bundle extras) throws RemoteException {
16386                 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
16387                         + PackageManager.installStatusToString(returnCode, msg));
16388 
16389                 installedLatch.countDown();
16390 
16391                 // Regardless of success or failure of the move operation,
16392                 // always unfreeze the package
16393                 unfreezePackage(packageName);
16394 
16395                 final int status = PackageManager.installStatusToPublicStatus(returnCode);
16396                 switch (status) {
16397                     case PackageInstaller.STATUS_SUCCESS:
16398                         mMoveCallbacks.notifyStatusChanged(moveId,
16399                                 PackageManager.MOVE_SUCCEEDED);
16400                         break;
16401                     case PackageInstaller.STATUS_FAILURE_STORAGE:
16402                         mMoveCallbacks.notifyStatusChanged(moveId,
16403                                 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
16404                         break;
16405                     default:
16406                         mMoveCallbacks.notifyStatusChanged(moveId,
16407                                 PackageManager.MOVE_FAILED_INTERNAL_ERROR);
16408                         break;
16409                 }
16410             }
16411         };
16412 
16413         final MoveInfo move;
16414         if (moveCompleteApp) {
16415             // Kick off a thread to report progress estimates
16416             new Thread() {
16417                 @Override
16418                 public void run() {
16419                     while (true) {
16420                         try {
16421                             if (installedLatch.await(1, TimeUnit.SECONDS)) {
16422                                 break;
16423                             }
16424                         } catch (InterruptedException ignored) {
16425                         }
16426 
16427                         final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace();
16428                         final int progress = 10 + (int) MathUtils.constrain(
16429                                 ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
16430                         mMoveCallbacks.notifyStatusChanged(moveId, progress);
16431                     }
16432                 }
16433             }.start();
16434 
16435             final String dataAppName = codeFile.getName();
16436             move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
16437                     dataAppName, appId, seinfo);
16438         } else {
16439             move = null;
16440         }
16441 
16442         installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
16443 
16444         final Message msg = mHandler.obtainMessage(INIT_COPY);
16445         final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
16446         msg.obj = new InstallParams(origin, move, installObserver, installFlags,
16447                 installerPackageName, volumeUuid, null, user, packageAbiOverride, null);
16448         mHandler.sendMessage(msg);
16449     }
16450 
16451     @Override
movePrimaryStorage(String volumeUuid)16452     public int movePrimaryStorage(String volumeUuid) throws RemoteException {
16453         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
16454 
16455         final int realMoveId = mNextMoveId.getAndIncrement();
16456         final Bundle extras = new Bundle();
16457         extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
16458         mMoveCallbacks.notifyCreated(realMoveId, extras);
16459 
16460         final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
16461             @Override
16462             public void onCreated(int moveId, Bundle extras) {
16463                 // Ignored
16464             }
16465 
16466             @Override
16467             public void onStatusChanged(int moveId, int status, long estMillis) {
16468                 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
16469             }
16470         };
16471 
16472         final StorageManager storage = mContext.getSystemService(StorageManager.class);
16473         storage.setPrimaryStorageUuid(volumeUuid, callback);
16474         return realMoveId;
16475     }
16476 
16477     @Override
getMoveStatus(int moveId)16478     public int getMoveStatus(int moveId) {
16479         mContext.enforceCallingOrSelfPermission(
16480                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
16481         return mMoveCallbacks.mLastStatus.get(moveId);
16482     }
16483 
16484     @Override
registerMoveCallback(IPackageMoveObserver callback)16485     public void registerMoveCallback(IPackageMoveObserver callback) {
16486         mContext.enforceCallingOrSelfPermission(
16487                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
16488         mMoveCallbacks.register(callback);
16489     }
16490 
16491     @Override
unregisterMoveCallback(IPackageMoveObserver callback)16492     public void unregisterMoveCallback(IPackageMoveObserver callback) {
16493         mContext.enforceCallingOrSelfPermission(
16494                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
16495         mMoveCallbacks.unregister(callback);
16496     }
16497 
16498     @Override
setInstallLocation(int loc)16499     public boolean setInstallLocation(int loc) {
16500         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
16501                 null);
16502         if (getInstallLocation() == loc) {
16503             return true;
16504         }
16505         if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
16506                 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
16507             android.provider.Settings.Global.putInt(mContext.getContentResolver(),
16508                     android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
16509             return true;
16510         }
16511         return false;
16512    }
16513 
16514     @Override
getInstallLocation()16515     public int getInstallLocation() {
16516         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
16517                 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
16518                 PackageHelper.APP_INSTALL_AUTO);
16519     }
16520 
16521     /** Called by UserManagerService */
cleanUpUserLILPw(UserManagerService userManager, int userHandle)16522     void cleanUpUserLILPw(UserManagerService userManager, int userHandle) {
16523         mDirtyUsers.remove(userHandle);
16524         mSettings.removeUserLPw(userHandle);
16525         mPendingBroadcasts.remove(userHandle);
16526         if (mInstaller != null) {
16527             // Technically, we shouldn't be doing this with the package lock
16528             // held.  However, this is very rare, and there is already so much
16529             // other disk I/O going on, that we'll let it slide for now.
16530             final StorageManager storage = mContext.getSystemService(StorageManager.class);
16531             for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
16532                 final String volumeUuid = vol.getFsUuid();
16533                 if (DEBUG_INSTALL) Slog.d(TAG, "Removing user data on volume " + volumeUuid);
16534                 mInstaller.removeUserDataDirs(volumeUuid, userHandle);
16535             }
16536         }
16537         mUserNeedsBadging.delete(userHandle);
16538         removeUnusedPackagesLILPw(userManager, userHandle);
16539     }
16540 
16541     /**
16542      * We're removing userHandle and would like to remove any downloaded packages
16543      * that are no longer in use by any other user.
16544      * @param userHandle the user being removed
16545      */
removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle)16546     private void removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle) {
16547         final boolean DEBUG_CLEAN_APKS = false;
16548         int [] users = userManager.getUserIdsLPr();
16549         Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
16550         while (psit.hasNext()) {
16551             PackageSetting ps = psit.next();
16552             if (ps.pkg == null) {
16553                 continue;
16554             }
16555             final String packageName = ps.pkg.packageName;
16556             // Skip over if system app
16557             if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
16558                 continue;
16559             }
16560             if (DEBUG_CLEAN_APKS) {
16561                 Slog.i(TAG, "Checking package " + packageName);
16562             }
16563             boolean keep = false;
16564             for (int i = 0; i < users.length; i++) {
16565                 if (users[i] != userHandle && ps.getInstalled(users[i])) {
16566                     keep = true;
16567                     if (DEBUG_CLEAN_APKS) {
16568                         Slog.i(TAG, "  Keeping package " + packageName + " for user "
16569                                 + users[i]);
16570                     }
16571                     break;
16572                 }
16573             }
16574             if (!keep) {
16575                 if (DEBUG_CLEAN_APKS) {
16576                     Slog.i(TAG, "  Removing package " + packageName);
16577                 }
16578                 mHandler.post(new Runnable() {
16579                     public void run() {
16580                         deletePackageX(packageName, userHandle, 0);
16581                     } //end run
16582                 });
16583             }
16584         }
16585     }
16586 
16587     /** Called by UserManagerService */
createNewUserLILPw(int userHandle)16588     void createNewUserLILPw(int userHandle) {
16589         if (mInstaller != null) {
16590             mInstaller.createUserConfig(userHandle);
16591             mSettings.createNewUserLILPw(this, mInstaller, userHandle);
16592             applyFactoryDefaultBrowserLPw(userHandle);
16593             primeDomainVerificationsLPw(userHandle);
16594         }
16595     }
16596 
newUserCreated(final int userHandle)16597     void newUserCreated(final int userHandle) {
16598         mDefaultPermissionPolicy.grantDefaultPermissions(userHandle);
16599     }
16600 
16601     @Override
getVerifierDeviceIdentity()16602     public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
16603         mContext.enforceCallingOrSelfPermission(
16604                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
16605                 "Only package verification agents can read the verifier device identity");
16606 
16607         synchronized (mPackages) {
16608             return mSettings.getVerifierDeviceIdentityLPw();
16609         }
16610     }
16611 
16612     @Override
setPermissionEnforced(String permission, boolean enforced)16613     public void setPermissionEnforced(String permission, boolean enforced) {
16614         // TODO: Now that we no longer change GID for storage, this should to away.
16615         mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
16616                 "setPermissionEnforced");
16617         if (READ_EXTERNAL_STORAGE.equals(permission)) {
16618             synchronized (mPackages) {
16619                 if (mSettings.mReadExternalStorageEnforced == null
16620                         || mSettings.mReadExternalStorageEnforced != enforced) {
16621                     mSettings.mReadExternalStorageEnforced = enforced;
16622                     mSettings.writeLPr();
16623                 }
16624             }
16625             // kill any non-foreground processes so we restart them and
16626             // grant/revoke the GID.
16627             final IActivityManager am = ActivityManagerNative.getDefault();
16628             if (am != null) {
16629                 final long token = Binder.clearCallingIdentity();
16630                 try {
16631                     am.killProcessesBelowForeground("setPermissionEnforcement");
16632                 } catch (RemoteException e) {
16633                 } finally {
16634                     Binder.restoreCallingIdentity(token);
16635                 }
16636             }
16637         } else {
16638             throw new IllegalArgumentException("No selective enforcement for " + permission);
16639         }
16640     }
16641 
16642     @Override
16643     @Deprecated
isPermissionEnforced(String permission)16644     public boolean isPermissionEnforced(String permission) {
16645         return true;
16646     }
16647 
16648     @Override
isStorageLow()16649     public boolean isStorageLow() {
16650         final long token = Binder.clearCallingIdentity();
16651         try {
16652             final DeviceStorageMonitorInternal
16653                     dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
16654             if (dsm != null) {
16655                 return dsm.isMemoryLow();
16656             } else {
16657                 return false;
16658             }
16659         } finally {
16660             Binder.restoreCallingIdentity(token);
16661         }
16662     }
16663 
16664     @Override
getPackageInstaller()16665     public IPackageInstaller getPackageInstaller() {
16666         return mInstallerService;
16667     }
16668 
userNeedsBadging(int userId)16669     private boolean userNeedsBadging(int userId) {
16670         int index = mUserNeedsBadging.indexOfKey(userId);
16671         if (index < 0) {
16672             final UserInfo userInfo;
16673             final long token = Binder.clearCallingIdentity();
16674             try {
16675                 userInfo = sUserManager.getUserInfo(userId);
16676             } finally {
16677                 Binder.restoreCallingIdentity(token);
16678             }
16679             final boolean b;
16680             if (userInfo != null && userInfo.isManagedProfile()) {
16681                 b = true;
16682             } else {
16683                 b = false;
16684             }
16685             mUserNeedsBadging.put(userId, b);
16686             return b;
16687         }
16688         return mUserNeedsBadging.valueAt(index);
16689     }
16690 
16691     @Override
getKeySetByAlias(String packageName, String alias)16692     public KeySet getKeySetByAlias(String packageName, String alias) {
16693         if (packageName == null || alias == null) {
16694             return null;
16695         }
16696         synchronized(mPackages) {
16697             final PackageParser.Package pkg = mPackages.get(packageName);
16698             if (pkg == null) {
16699                 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
16700                 throw new IllegalArgumentException("Unknown package: " + packageName);
16701             }
16702             KeySetManagerService ksms = mSettings.mKeySetManagerService;
16703             return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
16704         }
16705     }
16706 
16707     @Override
getSigningKeySet(String packageName)16708     public KeySet getSigningKeySet(String packageName) {
16709         if (packageName == null) {
16710             return null;
16711         }
16712         synchronized(mPackages) {
16713             final PackageParser.Package pkg = mPackages.get(packageName);
16714             if (pkg == null) {
16715                 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
16716                 throw new IllegalArgumentException("Unknown package: " + packageName);
16717             }
16718             if (pkg.applicationInfo.uid != Binder.getCallingUid()
16719                     && Process.SYSTEM_UID != Binder.getCallingUid()) {
16720                 throw new SecurityException("May not access signing KeySet of other apps.");
16721             }
16722             KeySetManagerService ksms = mSettings.mKeySetManagerService;
16723             return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
16724         }
16725     }
16726 
16727     @Override
isPackageSignedByKeySet(String packageName, KeySet ks)16728     public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
16729         if (packageName == null || ks == null) {
16730             return false;
16731         }
16732         synchronized(mPackages) {
16733             final PackageParser.Package pkg = mPackages.get(packageName);
16734             if (pkg == null) {
16735                 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
16736                 throw new IllegalArgumentException("Unknown package: " + packageName);
16737             }
16738             IBinder ksh = ks.getToken();
16739             if (ksh instanceof KeySetHandle) {
16740                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
16741                 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
16742             }
16743             return false;
16744         }
16745     }
16746 
16747     @Override
isPackageSignedByKeySetExactly(String packageName, KeySet ks)16748     public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
16749         if (packageName == null || ks == null) {
16750             return false;
16751         }
16752         synchronized(mPackages) {
16753             final PackageParser.Package pkg = mPackages.get(packageName);
16754             if (pkg == null) {
16755                 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
16756                 throw new IllegalArgumentException("Unknown package: " + packageName);
16757             }
16758             IBinder ksh = ks.getToken();
16759             if (ksh instanceof KeySetHandle) {
16760                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
16761                 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
16762             }
16763             return false;
16764         }
16765     }
16766 
getUsageStatsIfNoPackageUsageInfo()16767     public void getUsageStatsIfNoPackageUsageInfo() {
16768         if (!mPackageUsage.isHistoricalPackageUsageAvailable()) {
16769             UsageStatsManager usm = (UsageStatsManager) mContext.getSystemService(Context.USAGE_STATS_SERVICE);
16770             if (usm == null) {
16771                 throw new IllegalStateException("UsageStatsManager must be initialized");
16772             }
16773             long now = System.currentTimeMillis();
16774             Map<String, UsageStats> stats = usm.queryAndAggregateUsageStats(now - mDexOptLRUThresholdInMills, now);
16775             for (Map.Entry<String, UsageStats> entry : stats.entrySet()) {
16776                 String packageName = entry.getKey();
16777                 PackageParser.Package pkg = mPackages.get(packageName);
16778                 if (pkg == null) {
16779                     continue;
16780                 }
16781                 UsageStats usage = entry.getValue();
16782                 pkg.mLastPackageUsageTimeInMills = usage.getLastTimeUsed();
16783                 mPackageUsage.mIsHistoricalPackageUsageAvailable = true;
16784             }
16785         }
16786     }
16787 
16788     /**
16789      * Check and throw if the given before/after packages would be considered a
16790      * downgrade.
16791      */
checkDowngrade(PackageParser.Package before, PackageInfoLite after)16792     private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
16793             throws PackageManagerException {
16794         if (after.versionCode < before.mVersionCode) {
16795             throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
16796                     "Update version code " + after.versionCode + " is older than current "
16797                     + before.mVersionCode);
16798         } else if (after.versionCode == before.mVersionCode) {
16799             if (after.baseRevisionCode < before.baseRevisionCode) {
16800                 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
16801                         "Update base revision code " + after.baseRevisionCode
16802                         + " is older than current " + before.baseRevisionCode);
16803             }
16804 
16805             if (!ArrayUtils.isEmpty(after.splitNames)) {
16806                 for (int i = 0; i < after.splitNames.length; i++) {
16807                     final String splitName = after.splitNames[i];
16808                     final int j = ArrayUtils.indexOf(before.splitNames, splitName);
16809                     if (j != -1) {
16810                         if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
16811                             throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
16812                                     "Update split " + splitName + " revision code "
16813                                     + after.splitRevisionCodes[i] + " is older than current "
16814                                     + before.splitRevisionCodes[j]);
16815                         }
16816                     }
16817                 }
16818             }
16819         }
16820     }
16821 
16822     private static class MoveCallbacks extends Handler {
16823         private static final int MSG_CREATED = 1;
16824         private static final int MSG_STATUS_CHANGED = 2;
16825 
16826         private final RemoteCallbackList<IPackageMoveObserver>
16827                 mCallbacks = new RemoteCallbackList<>();
16828 
16829         private final SparseIntArray mLastStatus = new SparseIntArray();
16830 
MoveCallbacks(Looper looper)16831         public MoveCallbacks(Looper looper) {
16832             super(looper);
16833         }
16834 
register(IPackageMoveObserver callback)16835         public void register(IPackageMoveObserver callback) {
16836             mCallbacks.register(callback);
16837         }
16838 
unregister(IPackageMoveObserver callback)16839         public void unregister(IPackageMoveObserver callback) {
16840             mCallbacks.unregister(callback);
16841         }
16842 
16843         @Override
handleMessage(Message msg)16844         public void handleMessage(Message msg) {
16845             final SomeArgs args = (SomeArgs) msg.obj;
16846             final int n = mCallbacks.beginBroadcast();
16847             for (int i = 0; i < n; i++) {
16848                 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
16849                 try {
16850                     invokeCallback(callback, msg.what, args);
16851                 } catch (RemoteException ignored) {
16852                 }
16853             }
16854             mCallbacks.finishBroadcast();
16855             args.recycle();
16856         }
16857 
invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)16858         private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
16859                 throws RemoteException {
16860             switch (what) {
16861                 case MSG_CREATED: {
16862                     callback.onCreated(args.argi1, (Bundle) args.arg2);
16863                     break;
16864                 }
16865                 case MSG_STATUS_CHANGED: {
16866                     callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
16867                     break;
16868                 }
16869             }
16870         }
16871 
notifyCreated(int moveId, Bundle extras)16872         private void notifyCreated(int moveId, Bundle extras) {
16873             Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
16874 
16875             final SomeArgs args = SomeArgs.obtain();
16876             args.argi1 = moveId;
16877             args.arg2 = extras;
16878             obtainMessage(MSG_CREATED, args).sendToTarget();
16879         }
16880 
notifyStatusChanged(int moveId, int status)16881         private void notifyStatusChanged(int moveId, int status) {
16882             notifyStatusChanged(moveId, status, -1);
16883         }
16884 
notifyStatusChanged(int moveId, int status, long estMillis)16885         private void notifyStatusChanged(int moveId, int status, long estMillis) {
16886             Slog.v(TAG, "Move " + moveId + " status " + status);
16887 
16888             final SomeArgs args = SomeArgs.obtain();
16889             args.argi1 = moveId;
16890             args.argi2 = status;
16891             args.arg3 = estMillis;
16892             obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
16893 
16894             synchronized (mLastStatus) {
16895                 mLastStatus.put(moveId, status);
16896             }
16897         }
16898     }
16899 
16900     private final class OnPermissionChangeListeners extends Handler {
16901         private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
16902 
16903         private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
16904                 new RemoteCallbackList<>();
16905 
OnPermissionChangeListeners(Looper looper)16906         public OnPermissionChangeListeners(Looper looper) {
16907             super(looper);
16908         }
16909 
16910         @Override
handleMessage(Message msg)16911         public void handleMessage(Message msg) {
16912             switch (msg.what) {
16913                 case MSG_ON_PERMISSIONS_CHANGED: {
16914                     final int uid = msg.arg1;
16915                     handleOnPermissionsChanged(uid);
16916                 } break;
16917             }
16918         }
16919 
addListenerLocked(IOnPermissionsChangeListener listener)16920         public void addListenerLocked(IOnPermissionsChangeListener listener) {
16921             mPermissionListeners.register(listener);
16922 
16923         }
16924 
removeListenerLocked(IOnPermissionsChangeListener listener)16925         public void removeListenerLocked(IOnPermissionsChangeListener listener) {
16926             mPermissionListeners.unregister(listener);
16927         }
16928 
onPermissionsChanged(int uid)16929         public void onPermissionsChanged(int uid) {
16930             if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
16931                 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
16932             }
16933         }
16934 
handleOnPermissionsChanged(int uid)16935         private void handleOnPermissionsChanged(int uid) {
16936             final int count = mPermissionListeners.beginBroadcast();
16937             try {
16938                 for (int i = 0; i < count; i++) {
16939                     IOnPermissionsChangeListener callback = mPermissionListeners
16940                             .getBroadcastItem(i);
16941                     try {
16942                         callback.onPermissionsChanged(uid);
16943                     } catch (RemoteException e) {
16944                         Log.e(TAG, "Permission listener is dead", e);
16945                     }
16946                 }
16947             } finally {
16948                 mPermissionListeners.finishBroadcast();
16949             }
16950         }
16951     }
16952 
16953     private class PackageManagerInternalImpl extends PackageManagerInternal {
16954         @Override
setLocationPackagesProvider(PackagesProvider provider)16955         public void setLocationPackagesProvider(PackagesProvider provider) {
16956             synchronized (mPackages) {
16957                 mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
16958             }
16959         }
16960 
16961         @Override
setImePackagesProvider(PackagesProvider provider)16962         public void setImePackagesProvider(PackagesProvider provider) {
16963             synchronized (mPackages) {
16964                 mDefaultPermissionPolicy.setImePackagesProviderLPr(provider);
16965             }
16966         }
16967 
16968         @Override
setVoiceInteractionPackagesProvider(PackagesProvider provider)16969         public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
16970             synchronized (mPackages) {
16971                 mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
16972             }
16973         }
16974 
16975         @Override
setSmsAppPackagesProvider(PackagesProvider provider)16976         public void setSmsAppPackagesProvider(PackagesProvider provider) {
16977             synchronized (mPackages) {
16978                 mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
16979             }
16980         }
16981 
16982         @Override
setDialerAppPackagesProvider(PackagesProvider provider)16983         public void setDialerAppPackagesProvider(PackagesProvider provider) {
16984             synchronized (mPackages) {
16985                 mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
16986             }
16987         }
16988 
16989         @Override
setSimCallManagerPackagesProvider(PackagesProvider provider)16990         public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
16991             synchronized (mPackages) {
16992                 mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider);
16993             }
16994         }
16995 
16996         @Override
setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider)16997         public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
16998             synchronized (mPackages) {
16999                 mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider);
17000             }
17001         }
17002 
17003         @Override
grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId)17004         public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
17005             synchronized (mPackages) {
17006                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
17007                         packageName, userId);
17008             }
17009         }
17010 
17011         @Override
grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId)17012         public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
17013             synchronized (mPackages) {
17014                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
17015                         packageName, userId);
17016             }
17017         }
17018         @Override
grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId)17019         public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
17020             synchronized (mPackages) {
17021                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr(
17022                         packageName, userId);
17023             }
17024         }
17025     }
17026 
17027     @Override
grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId)17028     public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
17029         enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
17030         synchronized (mPackages) {
17031             final long identity = Binder.clearCallingIdentity();
17032             try {
17033                 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
17034                         packageNames, userId);
17035             } finally {
17036                 Binder.restoreCallingIdentity(identity);
17037             }
17038         }
17039     }
17040 
enforceSystemOrPhoneCaller(String tag)17041     private static void enforceSystemOrPhoneCaller(String tag) {
17042         int callingUid = Binder.getCallingUid();
17043         if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
17044             throw new SecurityException(
17045                     "Cannot call " + tag + " from UID " + callingUid);
17046         }
17047     }
17048 }
17049