PackageManagerService.java revision 10fa67c77e11699391e27975fc2d276a0b8c7cbb
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
17package com.android.server.pm;
18
19import static android.Manifest.permission.GRANT_REVOKE_PERMISSIONS;
20import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
21import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
22import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
23import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
24import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
25import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
26import static android.system.OsConstants.S_IRWXU;
27import static android.system.OsConstants.S_IRGRP;
28import static android.system.OsConstants.S_IXGRP;
29import static android.system.OsConstants.S_IROTH;
30import static android.system.OsConstants.S_IXOTH;
31import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_USER_OWNER;
32import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
33import static com.android.internal.util.ArrayUtils.appendInt;
34import static com.android.internal.util.ArrayUtils.removeInt;
35
36import com.android.internal.app.IMediaContainerService;
37import com.android.internal.app.ResolverActivity;
38import com.android.internal.content.NativeLibraryHelper;
39import com.android.internal.content.PackageHelper;
40import com.android.internal.util.FastPrintWriter;
41import com.android.internal.util.FastXmlSerializer;
42import com.android.internal.util.XmlUtils;
43import com.android.server.EventLogTags;
44import com.android.server.IntentResolver;
45import com.android.server.ServiceThread;
46
47import com.android.server.LocalServices;
48import com.android.server.Watchdog;
49import org.xmlpull.v1.XmlPullParser;
50import org.xmlpull.v1.XmlPullParserException;
51import org.xmlpull.v1.XmlSerializer;
52
53import android.app.ActivityManager;
54import android.app.ActivityManagerNative;
55import android.app.IActivityManager;
56import android.app.admin.IDevicePolicyManager;
57import android.app.backup.IBackupManager;
58import android.content.BroadcastReceiver;
59import android.content.ComponentName;
60import android.content.Context;
61import android.content.IIntentReceiver;
62import android.content.Intent;
63import android.content.IntentFilter;
64import android.content.IntentSender;
65import android.content.IntentSender.SendIntentException;
66import android.content.ServiceConnection;
67import android.content.pm.ActivityInfo;
68import android.content.pm.ApplicationInfo;
69import android.content.pm.ContainerEncryptionParams;
70import android.content.pm.FeatureInfo;
71import android.content.pm.IPackageDataObserver;
72import android.content.pm.IPackageDeleteObserver;
73import android.content.pm.IPackageInstallObserver;
74import android.content.pm.IPackageInstallObserver2;
75import android.content.pm.IPackageManager;
76import android.content.pm.IPackageMoveObserver;
77import android.content.pm.IPackageStatsObserver;
78import android.content.pm.InstrumentationInfo;
79import android.content.pm.ManifestDigest;
80import android.content.pm.PackageCleanItem;
81import android.content.pm.PackageInfo;
82import android.content.pm.PackageInfoLite;
83import android.content.pm.PackageManager;
84import android.content.pm.PackageParser;
85import android.content.pm.PackageParser.ActivityIntentInfo;
86import android.content.pm.PackageStats;
87import android.content.pm.PackageUserState;
88import android.content.pm.ParceledListSlice;
89import android.content.pm.PermissionGroupInfo;
90import android.content.pm.PermissionInfo;
91import android.content.pm.ProviderInfo;
92import android.content.pm.ResolveInfo;
93import android.content.pm.ServiceInfo;
94import android.content.pm.Signature;
95import android.content.pm.VerificationParams;
96import android.content.pm.VerifierDeviceIdentity;
97import android.content.pm.VerifierInfo;
98import android.content.res.Resources;
99import android.hardware.display.DisplayManager;
100import android.net.Uri;
101import android.os.Binder;
102import android.os.Build;
103import android.os.Bundle;
104import android.os.Environment;
105import android.os.Environment.UserEnvironment;
106import android.os.FileObserver;
107import android.os.FileUtils;
108import android.os.Handler;
109import android.os.IBinder;
110import android.os.Looper;
111import android.os.Message;
112import android.os.Parcel;
113import android.os.ParcelFileDescriptor;
114import android.os.Process;
115import android.os.RemoteException;
116import android.os.SELinux;
117import android.os.ServiceManager;
118import android.os.SystemClock;
119import android.os.SystemProperties;
120import android.os.UserHandle;
121import android.os.UserManager;
122import android.security.KeyStore;
123import android.security.SystemKeyStore;
124import android.system.ErrnoException;
125import android.system.Os;
126import android.system.StructStat;
127import android.text.TextUtils;
128import android.util.DisplayMetrics;
129import android.util.EventLog;
130import android.util.Log;
131import android.util.LogPrinter;
132import android.util.PrintStreamPrinter;
133import android.util.Slog;
134import android.util.SparseArray;
135import android.util.Xml;
136import android.view.Display;
137
138import java.io.BufferedOutputStream;
139import java.io.File;
140import java.io.FileDescriptor;
141import java.io.FileInputStream;
142import java.io.FileNotFoundException;
143import java.io.FileOutputStream;
144import java.io.FileReader;
145import java.io.FilenameFilter;
146import java.io.IOException;
147import java.io.PrintWriter;
148import java.security.NoSuchAlgorithmException;
149import java.security.PublicKey;
150import java.security.cert.Certificate;
151import java.security.cert.CertificateEncodingException;
152import java.security.cert.CertificateException;
153import java.text.SimpleDateFormat;
154import java.util.ArrayList;
155import java.util.Arrays;
156import java.util.Collection;
157import java.util.Collections;
158import java.util.Comparator;
159import java.util.Date;
160import java.util.HashMap;
161import java.util.HashSet;
162import java.util.Iterator;
163import java.util.List;
164import java.util.Map;
165import java.util.Set;
166
167import libcore.io.IoUtils;
168
169import com.android.internal.R;
170import com.android.server.pm.Settings.DatabaseVersion;
171import com.android.server.storage.DeviceStorageMonitorInternal;
172
173/**
174 * Keep track of all those .apks everywhere.
175 *
176 * This is very central to the platform's security; please run the unit
177 * tests whenever making modifications here:
178 *
179mmm frameworks/base/tests/AndroidTests
180adb install -r -f out/target/product/passion/data/app/AndroidTests.apk
181adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner
182 *
183 * {@hide}
184 */
185public class PackageManagerService extends IPackageManager.Stub {
186    static final String TAG = "PackageManager";
187    static final boolean DEBUG_SETTINGS = false;
188    static final boolean DEBUG_PREFERRED = false;
189    static final boolean DEBUG_UPGRADE = false;
190    private static final boolean DEBUG_INSTALL = false;
191    private static final boolean DEBUG_REMOVE = false;
192    private static final boolean DEBUG_BROADCASTS = false;
193    private static final boolean DEBUG_SHOW_INFO = false;
194    private static final boolean DEBUG_PACKAGE_INFO = false;
195    private static final boolean DEBUG_INTENT_MATCHING = false;
196    private static final boolean DEBUG_PACKAGE_SCANNING = false;
197    private static final boolean DEBUG_APP_DIR_OBSERVER = false;
198    private static final boolean DEBUG_VERIFY = false;
199
200    private static final int RADIO_UID = Process.PHONE_UID;
201    private static final int LOG_UID = Process.LOG_UID;
202    private static final int NFC_UID = Process.NFC_UID;
203    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
204    private static final int SHELL_UID = Process.SHELL_UID;
205
206    // Cap the size of permission trees that 3rd party apps can define
207    private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
208
209    private static final int REMOVE_EVENTS =
210        FileObserver.CLOSE_WRITE | FileObserver.DELETE | FileObserver.MOVED_FROM;
211    private static final int ADD_EVENTS =
212        FileObserver.CLOSE_WRITE /*| FileObserver.CREATE*/ | FileObserver.MOVED_TO;
213
214    private static final int OBSERVER_EVENTS = REMOVE_EVENTS | ADD_EVENTS;
215    // Suffix used during package installation when copying/moving
216    // package apks to install directory.
217    private static final String INSTALL_PACKAGE_SUFFIX = "-";
218
219    static final int SCAN_MONITOR = 1<<0;
220    static final int SCAN_NO_DEX = 1<<1;
221    static final int SCAN_FORCE_DEX = 1<<2;
222    static final int SCAN_UPDATE_SIGNATURE = 1<<3;
223    static final int SCAN_NEW_INSTALL = 1<<4;
224    static final int SCAN_NO_PATHS = 1<<5;
225    static final int SCAN_UPDATE_TIME = 1<<6;
226    static final int SCAN_DEFER_DEX = 1<<7;
227    static final int SCAN_BOOTING = 1<<8;
228    static final int SCAN_TRUSTED_OVERLAY = 1<<9;
229    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10;
230
231    static final int REMOVE_CHATTY = 1<<16;
232
233    /**
234     * Timeout (in milliseconds) after which the watchdog should declare that
235     * our handler thread is wedged.  The usual default for such things is one
236     * minute but we sometimes do very lengthy I/O operations on this thread,
237     * such as installing multi-gigabyte applications, so ours needs to be longer.
238     */
239    private static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
240
241    /**
242     * Whether verification is enabled by default.
243     */
244    private static final boolean DEFAULT_VERIFY_ENABLE = true;
245
246    /**
247     * The default maximum time to wait for the verification agent to return in
248     * milliseconds.
249     */
250    private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
251
252    /**
253     * The default response for package verification timeout.
254     *
255     * This can be either PackageManager.VERIFICATION_ALLOW or
256     * PackageManager.VERIFICATION_REJECT.
257     */
258    private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
259
260    static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
261
262    static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
263            DEFAULT_CONTAINER_PACKAGE,
264            "com.android.defcontainer.DefaultContainerService");
265
266    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
267
268    private static final String LIB_DIR_NAME = "lib";
269    private static final String LIB64_DIR_NAME = "lib64";
270
271    private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
272
273    static final String mTempContainerPrefix = "smdl2tmp";
274
275    final ServiceThread mHandlerThread;
276
277    private static final String IDMAP_PREFIX = "/data/resource-cache/";
278    private static final String IDMAP_SUFFIX = "@idmap";
279
280    final PackageHandler mHandler;
281
282    final int mSdkVersion = Build.VERSION.SDK_INT;
283
284    final Context mContext;
285    final boolean mFactoryTest;
286    final boolean mOnlyCore;
287    final boolean mNoDexOpt;
288    final DisplayMetrics mMetrics;
289    final int mDefParseFlags;
290    final String[] mSeparateProcesses;
291
292    // This is where all application persistent data goes.
293    final File mAppDataDir;
294
295    // This is where all application persistent data goes for secondary users.
296    final File mUserAppDataDir;
297
298    /** The location for ASEC container files on internal storage. */
299    final String mAsecInternalPath;
300
301    // This is the object monitoring the framework dir.
302    final FileObserver mFrameworkInstallObserver;
303
304    // This is the object monitoring the system app dir.
305    final FileObserver mSystemInstallObserver;
306
307    // This is the object monitoring the privileged system app dir.
308    final FileObserver mPrivilegedInstallObserver;
309
310    // This is the object monitoring the vendor app dir.
311    final FileObserver mVendorInstallObserver;
312
313    // This is the object monitoring the vendor overlay package dir.
314    final FileObserver mVendorOverlayInstallObserver;
315
316    // This is the object monitoring the OEM app dir.
317    final FileObserver mOemInstallObserver;
318
319    // This is the object monitoring mAppInstallDir.
320    final FileObserver mAppInstallObserver;
321
322    // This is the object monitoring mDrmAppPrivateInstallDir.
323    final FileObserver mDrmAppInstallObserver;
324
325    // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
326    // LOCK HELD.  Can be called with mInstallLock held.
327    final Installer mInstaller;
328
329    final File mAppInstallDir;
330
331    /**
332     * Directory to which applications installed internally have native
333     * libraries copied.
334     */
335    private File mAppLibInstallDir;
336
337    // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
338    // apps.
339    final File mDrmAppPrivateInstallDir;
340
341    // ----------------------------------------------------------------
342
343    // Lock for state used when installing and doing other long running
344    // operations.  Methods that must be called with this lock held have
345    // the suffix "LI".
346    final Object mInstallLock = new Object();
347
348    // These are the directories in the 3rd party applications installed dir
349    // that we have currently loaded packages from.  Keys are the application's
350    // installed zip file (absolute codePath), and values are Package.
351    final HashMap<String, PackageParser.Package> mAppDirs =
352            new HashMap<String, PackageParser.Package>();
353
354    // Information for the parser to write more useful error messages.
355    int mLastScanError;
356
357    // ----------------------------------------------------------------
358
359    // Keys are String (package name), values are Package.  This also serves
360    // as the lock for the global state.  Methods that must be called with
361    // this lock held have the prefix "LP".
362    final HashMap<String, PackageParser.Package> mPackages =
363            new HashMap<String, PackageParser.Package>();
364
365    // Tracks available target package names -> overlay package paths.
366    final HashMap<String, HashMap<String, PackageParser.Package>> mOverlays =
367        new HashMap<String, HashMap<String, PackageParser.Package>>();
368
369    final Settings mSettings;
370    boolean mRestoredSettings;
371
372    // Group-ids that are given to all packages as read from etc/permissions/*.xml.
373    int[] mGlobalGids;
374
375    // These are the built-in uid -> permission mappings that were read from the
376    // etc/permissions.xml file.
377    final SparseArray<HashSet<String>> mSystemPermissions =
378            new SparseArray<HashSet<String>>();
379
380    static final class SharedLibraryEntry {
381        final String path;
382        final String apk;
383
384        SharedLibraryEntry(String _path, String _apk) {
385            path = _path;
386            apk = _apk;
387        }
388    }
389
390    // These are the built-in shared libraries that were read from the
391    // etc/permissions.xml file.
392    final HashMap<String, SharedLibraryEntry> mSharedLibraries
393            = new HashMap<String, SharedLibraryEntry>();
394
395    // Temporary for building the final shared libraries for an .apk.
396    String[] mTmpSharedLibraries = null;
397
398    // These are the features this devices supports that were read from the
399    // etc/permissions.xml file.
400    final HashMap<String, FeatureInfo> mAvailableFeatures =
401            new HashMap<String, FeatureInfo>();
402
403    // If mac_permissions.xml was found for seinfo labeling.
404    boolean mFoundPolicyFile;
405
406    // If a recursive restorecon of /data/data/<pkg> is needed.
407    private boolean mShouldRestoreconData = SELinuxMMAC.shouldRestorecon();
408
409    // All available activities, for your resolving pleasure.
410    final ActivityIntentResolver mActivities =
411            new ActivityIntentResolver();
412
413    // All available receivers, for your resolving pleasure.
414    final ActivityIntentResolver mReceivers =
415            new ActivityIntentResolver();
416
417    // All available services, for your resolving pleasure.
418    final ServiceIntentResolver mServices = new ServiceIntentResolver();
419
420    // All available providers, for your resolving pleasure.
421    final ProviderIntentResolver mProviders = new ProviderIntentResolver();
422
423    // Mapping from provider base names (first directory in content URI codePath)
424    // to the provider information.
425    final HashMap<String, PackageParser.Provider> mProvidersByAuthority =
426            new HashMap<String, PackageParser.Provider>();
427
428    // Mapping from instrumentation class names to info about them.
429    final HashMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
430            new HashMap<ComponentName, PackageParser.Instrumentation>();
431
432    // Mapping from permission names to info about them.
433    final HashMap<String, PackageParser.PermissionGroup> mPermissionGroups =
434            new HashMap<String, PackageParser.PermissionGroup>();
435
436    // Packages whose data we have transfered into another package, thus
437    // should no longer exist.
438    final HashSet<String> mTransferedPackages = new HashSet<String>();
439
440    // Broadcast actions that are only available to the system.
441    final HashSet<String> mProtectedBroadcasts = new HashSet<String>();
442
443    /** List of packages waiting for verification. */
444    final SparseArray<PackageVerificationState> mPendingVerification
445            = new SparseArray<PackageVerificationState>();
446
447    HashSet<PackageParser.Package> mDeferredDexOpt = null;
448
449    /** Token for keys in mPendingVerification. */
450    private int mPendingVerificationToken = 0;
451
452    boolean mSystemReady;
453    boolean mSafeMode;
454    boolean mHasSystemUidErrors;
455
456    ApplicationInfo mAndroidApplication;
457    final ActivityInfo mResolveActivity = new ActivityInfo();
458    final ResolveInfo mResolveInfo = new ResolveInfo();
459    ComponentName mResolveComponentName;
460    PackageParser.Package mPlatformPackage;
461    ComponentName mCustomResolverComponentName;
462
463    boolean mResolverReplaced = false;
464
465    // Set of pending broadcasts for aggregating enable/disable of components.
466    static class PendingPackageBroadcasts {
467        // for each user id, a map of <package name -> components within that package>
468        final SparseArray<HashMap<String, ArrayList<String>>> mUidMap;
469
470        public PendingPackageBroadcasts() {
471            mUidMap = new SparseArray<HashMap<String, ArrayList<String>>>(2);
472        }
473
474        public ArrayList<String> get(int userId, String packageName) {
475            HashMap<String, ArrayList<String>> packages = getOrAllocate(userId);
476            return packages.get(packageName);
477        }
478
479        public void put(int userId, String packageName, ArrayList<String> components) {
480            HashMap<String, ArrayList<String>> packages = getOrAllocate(userId);
481            packages.put(packageName, components);
482        }
483
484        public void remove(int userId, String packageName) {
485            HashMap<String, ArrayList<String>> packages = mUidMap.get(userId);
486            if (packages != null) {
487                packages.remove(packageName);
488            }
489        }
490
491        public void remove(int userId) {
492            mUidMap.remove(userId);
493        }
494
495        public int userIdCount() {
496            return mUidMap.size();
497        }
498
499        public int userIdAt(int n) {
500            return mUidMap.keyAt(n);
501        }
502
503        public HashMap<String, ArrayList<String>> packagesForUserId(int userId) {
504            return mUidMap.get(userId);
505        }
506
507        public int size() {
508            // total number of pending broadcast entries across all userIds
509            int num = 0;
510            for (int i = 0; i< mUidMap.size(); i++) {
511                num += mUidMap.valueAt(i).size();
512            }
513            return num;
514        }
515
516        public void clear() {
517            mUidMap.clear();
518        }
519
520        private HashMap<String, ArrayList<String>> getOrAllocate(int userId) {
521            HashMap<String, ArrayList<String>> map = mUidMap.get(userId);
522            if (map == null) {
523                map = new HashMap<String, ArrayList<String>>();
524                mUidMap.put(userId, map);
525            }
526            return map;
527        }
528    }
529    final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
530
531    // Service Connection to remote media container service to copy
532    // package uri's from external media onto secure containers
533    // or internal storage.
534    private IMediaContainerService mContainerService = null;
535
536    static final int SEND_PENDING_BROADCAST = 1;
537    static final int MCS_BOUND = 3;
538    static final int END_COPY = 4;
539    static final int INIT_COPY = 5;
540    static final int MCS_UNBIND = 6;
541    static final int START_CLEANING_PACKAGE = 7;
542    static final int FIND_INSTALL_LOC = 8;
543    static final int POST_INSTALL = 9;
544    static final int MCS_RECONNECT = 10;
545    static final int MCS_GIVE_UP = 11;
546    static final int UPDATED_MEDIA_STATUS = 12;
547    static final int WRITE_SETTINGS = 13;
548    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
549    static final int PACKAGE_VERIFIED = 15;
550    static final int CHECK_PENDING_VERIFICATION = 16;
551
552    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
553
554    // Delay time in millisecs
555    static final int BROADCAST_DELAY = 10 * 1000;
556
557    static UserManagerService sUserManager;
558
559    // Stores a list of users whose package restrictions file needs to be updated
560    private HashSet<Integer> mDirtyUsers = new HashSet<Integer>();
561
562    final private DefaultContainerConnection mDefContainerConn =
563            new DefaultContainerConnection();
564    class DefaultContainerConnection implements ServiceConnection {
565        public void onServiceConnected(ComponentName name, IBinder service) {
566            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
567            IMediaContainerService imcs =
568                IMediaContainerService.Stub.asInterface(service);
569            mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
570        }
571
572        public void onServiceDisconnected(ComponentName name) {
573            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
574        }
575    };
576
577    // Recordkeeping of restore-after-install operations that are currently in flight
578    // between the Package Manager and the Backup Manager
579    class PostInstallData {
580        public InstallArgs args;
581        public PackageInstalledInfo res;
582
583        PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
584            args = _a;
585            res = _r;
586        }
587    };
588    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
589    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
590
591    private final String mRequiredVerifierPackage;
592
593    class PackageHandler extends Handler {
594        private boolean mBound = false;
595        final ArrayList<HandlerParams> mPendingInstalls =
596            new ArrayList<HandlerParams>();
597
598        private boolean connectToService() {
599            if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
600                    " DefaultContainerService");
601            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
602            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
603            if (mContext.bindServiceAsUser(service, mDefContainerConn,
604                    Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
605                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
606                mBound = true;
607                return true;
608            }
609            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
610            return false;
611        }
612
613        private void disconnectService() {
614            mContainerService = null;
615            mBound = false;
616            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
617            mContext.unbindService(mDefContainerConn);
618            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
619        }
620
621        PackageHandler(Looper looper) {
622            super(looper);
623        }
624
625        public void handleMessage(Message msg) {
626            try {
627                doHandleMessage(msg);
628            } finally {
629                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
630            }
631        }
632
633        void doHandleMessage(Message msg) {
634            switch (msg.what) {
635                case INIT_COPY: {
636                    HandlerParams params = (HandlerParams) msg.obj;
637                    int idx = mPendingInstalls.size();
638                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
639                    // If a bind was already initiated we dont really
640                    // need to do anything. The pending install
641                    // will be processed later on.
642                    if (!mBound) {
643                        // If this is the only one pending we might
644                        // have to bind to the service again.
645                        if (!connectToService()) {
646                            Slog.e(TAG, "Failed to bind to media container service");
647                            params.serviceError();
648                            return;
649                        } else {
650                            // Once we bind to the service, the first
651                            // pending request will be processed.
652                            mPendingInstalls.add(idx, params);
653                        }
654                    } else {
655                        mPendingInstalls.add(idx, params);
656                        // Already bound to the service. Just make
657                        // sure we trigger off processing the first request.
658                        if (idx == 0) {
659                            mHandler.sendEmptyMessage(MCS_BOUND);
660                        }
661                    }
662                    break;
663                }
664                case MCS_BOUND: {
665                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
666                    if (msg.obj != null) {
667                        mContainerService = (IMediaContainerService) msg.obj;
668                    }
669                    if (mContainerService == null) {
670                        // Something seriously wrong. Bail out
671                        Slog.e(TAG, "Cannot bind to media container service");
672                        for (HandlerParams params : mPendingInstalls) {
673                            // Indicate service bind error
674                            params.serviceError();
675                        }
676                        mPendingInstalls.clear();
677                    } else if (mPendingInstalls.size() > 0) {
678                        HandlerParams params = mPendingInstalls.get(0);
679                        if (params != null) {
680                            if (params.startCopy()) {
681                                // We are done...  look for more work or to
682                                // go idle.
683                                if (DEBUG_SD_INSTALL) Log.i(TAG,
684                                        "Checking for more work or unbind...");
685                                // Delete pending install
686                                if (mPendingInstalls.size() > 0) {
687                                    mPendingInstalls.remove(0);
688                                }
689                                if (mPendingInstalls.size() == 0) {
690                                    if (mBound) {
691                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
692                                                "Posting delayed MCS_UNBIND");
693                                        removeMessages(MCS_UNBIND);
694                                        Message ubmsg = obtainMessage(MCS_UNBIND);
695                                        // Unbind after a little delay, to avoid
696                                        // continual thrashing.
697                                        sendMessageDelayed(ubmsg, 10000);
698                                    }
699                                } else {
700                                    // There are more pending requests in queue.
701                                    // Just post MCS_BOUND message to trigger processing
702                                    // of next pending install.
703                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
704                                            "Posting MCS_BOUND for next work");
705                                    mHandler.sendEmptyMessage(MCS_BOUND);
706                                }
707                            }
708                        }
709                    } else {
710                        // Should never happen ideally.
711                        Slog.w(TAG, "Empty queue");
712                    }
713                    break;
714                }
715                case MCS_RECONNECT: {
716                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
717                    if (mPendingInstalls.size() > 0) {
718                        if (mBound) {
719                            disconnectService();
720                        }
721                        if (!connectToService()) {
722                            Slog.e(TAG, "Failed to bind to media container service");
723                            for (HandlerParams params : mPendingInstalls) {
724                                // Indicate service bind error
725                                params.serviceError();
726                            }
727                            mPendingInstalls.clear();
728                        }
729                    }
730                    break;
731                }
732                case MCS_UNBIND: {
733                    // If there is no actual work left, then time to unbind.
734                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
735
736                    if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
737                        if (mBound) {
738                            if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
739
740                            disconnectService();
741                        }
742                    } else if (mPendingInstalls.size() > 0) {
743                        // There are more pending requests in queue.
744                        // Just post MCS_BOUND message to trigger processing
745                        // of next pending install.
746                        mHandler.sendEmptyMessage(MCS_BOUND);
747                    }
748
749                    break;
750                }
751                case MCS_GIVE_UP: {
752                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
753                    mPendingInstalls.remove(0);
754                    break;
755                }
756                case SEND_PENDING_BROADCAST: {
757                    String packages[];
758                    ArrayList<String> components[];
759                    int size = 0;
760                    int uids[];
761                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
762                    synchronized (mPackages) {
763                        if (mPendingBroadcasts == null) {
764                            return;
765                        }
766                        size = mPendingBroadcasts.size();
767                        if (size <= 0) {
768                            // Nothing to be done. Just return
769                            return;
770                        }
771                        packages = new String[size];
772                        components = new ArrayList[size];
773                        uids = new int[size];
774                        int i = 0;  // filling out the above arrays
775
776                        for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
777                            int packageUserId = mPendingBroadcasts.userIdAt(n);
778                            Iterator<Map.Entry<String, ArrayList<String>>> it
779                                    = mPendingBroadcasts.packagesForUserId(packageUserId)
780                                            .entrySet().iterator();
781                            while (it.hasNext() && i < size) {
782                                Map.Entry<String, ArrayList<String>> ent = it.next();
783                                packages[i] = ent.getKey();
784                                components[i] = ent.getValue();
785                                PackageSetting ps = mSettings.mPackages.get(ent.getKey());
786                                uids[i] = (ps != null)
787                                        ? UserHandle.getUid(packageUserId, ps.appId)
788                                        : -1;
789                                i++;
790                            }
791                        }
792                        size = i;
793                        mPendingBroadcasts.clear();
794                    }
795                    // Send broadcasts
796                    for (int i = 0; i < size; i++) {
797                        sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
798                    }
799                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
800                    break;
801                }
802                case START_CLEANING_PACKAGE: {
803                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
804                    final String packageName = (String)msg.obj;
805                    final int userId = msg.arg1;
806                    final boolean andCode = msg.arg2 != 0;
807                    synchronized (mPackages) {
808                        if (userId == UserHandle.USER_ALL) {
809                            int[] users = sUserManager.getUserIds();
810                            for (int user : users) {
811                                mSettings.addPackageToCleanLPw(
812                                        new PackageCleanItem(user, packageName, andCode));
813                            }
814                        } else {
815                            mSettings.addPackageToCleanLPw(
816                                    new PackageCleanItem(userId, packageName, andCode));
817                        }
818                    }
819                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
820                    startCleaningPackages();
821                } break;
822                case POST_INSTALL: {
823                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
824                    PostInstallData data = mRunningInstalls.get(msg.arg1);
825                    mRunningInstalls.delete(msg.arg1);
826                    boolean deleteOld = false;
827
828                    if (data != null) {
829                        InstallArgs args = data.args;
830                        PackageInstalledInfo res = data.res;
831
832                        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
833                            res.removedInfo.sendBroadcast(false, true, false);
834                            Bundle extras = new Bundle(1);
835                            extras.putInt(Intent.EXTRA_UID, res.uid);
836                            // Determine the set of users who are adding this
837                            // package for the first time vs. those who are seeing
838                            // an update.
839                            int[] firstUsers;
840                            int[] updateUsers = new int[0];
841                            if (res.origUsers == null || res.origUsers.length == 0) {
842                                firstUsers = res.newUsers;
843                            } else {
844                                firstUsers = new int[0];
845                                for (int i=0; i<res.newUsers.length; i++) {
846                                    int user = res.newUsers[i];
847                                    boolean isNew = true;
848                                    for (int j=0; j<res.origUsers.length; j++) {
849                                        if (res.origUsers[j] == user) {
850                                            isNew = false;
851                                            break;
852                                        }
853                                    }
854                                    if (isNew) {
855                                        int[] newFirst = new int[firstUsers.length+1];
856                                        System.arraycopy(firstUsers, 0, newFirst, 0,
857                                                firstUsers.length);
858                                        newFirst[firstUsers.length] = user;
859                                        firstUsers = newFirst;
860                                    } else {
861                                        int[] newUpdate = new int[updateUsers.length+1];
862                                        System.arraycopy(updateUsers, 0, newUpdate, 0,
863                                                updateUsers.length);
864                                        newUpdate[updateUsers.length] = user;
865                                        updateUsers = newUpdate;
866                                    }
867                                }
868                            }
869                            sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
870                                    res.pkg.applicationInfo.packageName,
871                                    extras, null, null, firstUsers);
872                            final boolean update = res.removedInfo.removedPackage != null;
873                            if (update) {
874                                extras.putBoolean(Intent.EXTRA_REPLACING, true);
875                            }
876                            sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
877                                    res.pkg.applicationInfo.packageName,
878                                    extras, null, null, updateUsers);
879                            if (update) {
880                                sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
881                                        res.pkg.applicationInfo.packageName,
882                                        extras, null, null, updateUsers);
883                                sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
884                                        null, null,
885                                        res.pkg.applicationInfo.packageName, null, updateUsers);
886
887                                // treat asec-hosted packages like removable media on upgrade
888                                if (isForwardLocked(res.pkg) || isExternal(res.pkg)) {
889                                    if (DEBUG_INSTALL) {
890                                        Slog.i(TAG, "upgrading pkg " + res.pkg
891                                                + " is ASEC-hosted -> AVAILABLE");
892                                    }
893                                    int[] uidArray = new int[] { res.pkg.applicationInfo.uid };
894                                    ArrayList<String> pkgList = new ArrayList<String>(1);
895                                    pkgList.add(res.pkg.applicationInfo.packageName);
896                                    sendResourcesChangedBroadcast(true, true,
897                                            pkgList,uidArray, null);
898                                }
899                            }
900                            if (res.removedInfo.args != null) {
901                                // Remove the replaced package's older resources safely now
902                                deleteOld = true;
903                            }
904
905                            // Log current value of "unknown sources" setting
906                            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
907                                getUnknownSourcesSettings());
908                        }
909                        // Force a gc to clear up things
910                        Runtime.getRuntime().gc();
911                        // We delete after a gc for applications  on sdcard.
912                        if (deleteOld) {
913                            synchronized (mInstallLock) {
914                                res.removedInfo.args.doPostDeleteLI(true);
915                            }
916                        }
917                        if (args.observer != null) {
918                            try {
919                                args.observer.packageInstalled(res.name, res.returnCode);
920                            } catch (RemoteException e) {
921                                Slog.i(TAG, "Observer no longer exists.");
922                            }
923                        }
924                        if (args.observer2 != null) {
925                            try {
926                                Bundle extras = extrasForInstallResult(res);
927                                args.observer2.packageInstalled(res.name, extras, res.returnCode);
928                            } catch (RemoteException e) {
929                                Slog.i(TAG, "Observer no longer exists.");
930                            }
931                        }
932                    } else {
933                        Slog.e(TAG, "Bogus post-install token " + msg.arg1);
934                    }
935                } break;
936                case UPDATED_MEDIA_STATUS: {
937                    if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
938                    boolean reportStatus = msg.arg1 == 1;
939                    boolean doGc = msg.arg2 == 1;
940                    if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
941                    if (doGc) {
942                        // Force a gc to clear up stale containers.
943                        Runtime.getRuntime().gc();
944                    }
945                    if (msg.obj != null) {
946                        @SuppressWarnings("unchecked")
947                        Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
948                        if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
949                        // Unload containers
950                        unloadAllContainers(args);
951                    }
952                    if (reportStatus) {
953                        try {
954                            if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back");
955                            PackageHelper.getMountService().finishMediaUpdate();
956                        } catch (RemoteException e) {
957                            Log.e(TAG, "MountService not running?");
958                        }
959                    }
960                } break;
961                case WRITE_SETTINGS: {
962                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
963                    synchronized (mPackages) {
964                        removeMessages(WRITE_SETTINGS);
965                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
966                        mSettings.writeLPr();
967                        mDirtyUsers.clear();
968                    }
969                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
970                } break;
971                case WRITE_PACKAGE_RESTRICTIONS: {
972                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
973                    synchronized (mPackages) {
974                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
975                        for (int userId : mDirtyUsers) {
976                            mSettings.writePackageRestrictionsLPr(userId);
977                        }
978                        mDirtyUsers.clear();
979                    }
980                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
981                } break;
982                case CHECK_PENDING_VERIFICATION: {
983                    final int verificationId = msg.arg1;
984                    final PackageVerificationState state = mPendingVerification.get(verificationId);
985
986                    if ((state != null) && !state.timeoutExtended()) {
987                        final InstallArgs args = state.getInstallArgs();
988                        Slog.i(TAG, "Verification timed out for " + args.packageURI.toString());
989                        mPendingVerification.remove(verificationId);
990
991                        int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
992
993                        if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
994                            Slog.i(TAG, "Continuing with installation of "
995                                    + args.packageURI.toString());
996                            state.setVerifierResponse(Binder.getCallingUid(),
997                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
998                            broadcastPackageVerified(verificationId, args.packageURI,
999                                    PackageManager.VERIFICATION_ALLOW,
1000                                    state.getInstallArgs().getUser());
1001                            try {
1002                                ret = args.copyApk(mContainerService, true);
1003                            } catch (RemoteException e) {
1004                                Slog.e(TAG, "Could not contact the ContainerService");
1005                            }
1006                        } else {
1007                            broadcastPackageVerified(verificationId, args.packageURI,
1008                                    PackageManager.VERIFICATION_REJECT,
1009                                    state.getInstallArgs().getUser());
1010                        }
1011
1012                        processPendingInstall(args, ret);
1013                        mHandler.sendEmptyMessage(MCS_UNBIND);
1014                    }
1015                    break;
1016                }
1017                case PACKAGE_VERIFIED: {
1018                    final int verificationId = msg.arg1;
1019
1020                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1021                    if (state == null) {
1022                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1023                        break;
1024                    }
1025
1026                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1027
1028                    state.setVerifierResponse(response.callerUid, response.code);
1029
1030                    if (state.isVerificationComplete()) {
1031                        mPendingVerification.remove(verificationId);
1032
1033                        final InstallArgs args = state.getInstallArgs();
1034
1035                        int ret;
1036                        if (state.isInstallAllowed()) {
1037                            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1038                            broadcastPackageVerified(verificationId, args.packageURI,
1039                                    response.code, state.getInstallArgs().getUser());
1040                            try {
1041                                ret = args.copyApk(mContainerService, true);
1042                            } catch (RemoteException e) {
1043                                Slog.e(TAG, "Could not contact the ContainerService");
1044                            }
1045                        } else {
1046                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1047                        }
1048
1049                        processPendingInstall(args, ret);
1050
1051                        mHandler.sendEmptyMessage(MCS_UNBIND);
1052                    }
1053
1054                    break;
1055                }
1056            }
1057        }
1058    }
1059
1060    Bundle extrasForInstallResult(PackageInstalledInfo res) {
1061        Bundle extras = null;
1062        switch (res.returnCode) {
1063            case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
1064                extras = new Bundle();
1065                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
1066                        res.origPermission);
1067                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
1068                        res.origPackage);
1069                break;
1070            }
1071        }
1072        return extras;
1073    }
1074
1075    void scheduleWriteSettingsLocked() {
1076        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
1077            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
1078        }
1079    }
1080
1081    void scheduleWritePackageRestrictionsLocked(int userId) {
1082        if (!sUserManager.exists(userId)) return;
1083        mDirtyUsers.add(userId);
1084        if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
1085            mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
1086        }
1087    }
1088
1089    public static final IPackageManager main(Context context, Installer installer,
1090            boolean factoryTest, boolean onlyCore) {
1091        PackageManagerService m = new PackageManagerService(context, installer,
1092                factoryTest, onlyCore);
1093        ServiceManager.addService("package", m);
1094        return m;
1095    }
1096
1097    static String[] splitString(String str, char sep) {
1098        int count = 1;
1099        int i = 0;
1100        while ((i=str.indexOf(sep, i)) >= 0) {
1101            count++;
1102            i++;
1103        }
1104
1105        String[] res = new String[count];
1106        i=0;
1107        count = 0;
1108        int lastI=0;
1109        while ((i=str.indexOf(sep, i)) >= 0) {
1110            res[count] = str.substring(lastI, i);
1111            count++;
1112            i++;
1113            lastI = i;
1114        }
1115        res[count] = str.substring(lastI, str.length());
1116        return res;
1117    }
1118
1119    private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
1120        DisplayManager displayManager = (DisplayManager) context.getSystemService(
1121                Context.DISPLAY_SERVICE);
1122        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
1123    }
1124
1125    public PackageManagerService(Context context, Installer installer,
1126            boolean factoryTest, boolean onlyCore) {
1127        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
1128                SystemClock.uptimeMillis());
1129
1130        if (mSdkVersion <= 0) {
1131            Slog.w(TAG, "**** ro.build.version.sdk not set!");
1132        }
1133
1134        mContext = context;
1135        mFactoryTest = factoryTest;
1136        mOnlyCore = onlyCore;
1137        mNoDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));
1138        mMetrics = new DisplayMetrics();
1139        mSettings = new Settings(context);
1140        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
1141                ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1142        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
1143                ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1144        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
1145                ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1146        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
1147                ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1148        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
1149                ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1150        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
1151                ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1152
1153        String separateProcesses = SystemProperties.get("debug.separate_processes");
1154        if (separateProcesses != null && separateProcesses.length() > 0) {
1155            if ("*".equals(separateProcesses)) {
1156                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
1157                mSeparateProcesses = null;
1158                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
1159            } else {
1160                mDefParseFlags = 0;
1161                mSeparateProcesses = separateProcesses.split(",");
1162                Slog.w(TAG, "Running with debug.separate_processes: "
1163                        + separateProcesses);
1164            }
1165        } else {
1166            mDefParseFlags = 0;
1167            mSeparateProcesses = null;
1168        }
1169
1170        mInstaller = installer;
1171
1172        getDefaultDisplayMetrics(context, mMetrics);
1173
1174        synchronized (mInstallLock) {
1175        // writer
1176        synchronized (mPackages) {
1177            mHandlerThread = new ServiceThread(TAG,
1178                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
1179            mHandlerThread.start();
1180            mHandler = new PackageHandler(mHandlerThread.getLooper());
1181            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
1182
1183            File dataDir = Environment.getDataDirectory();
1184            mAppDataDir = new File(dataDir, "data");
1185            mAppInstallDir = new File(dataDir, "app");
1186            mAppLibInstallDir = new File(dataDir, "app-lib");
1187            mAsecInternalPath = new File(dataDir, "app-asec").getPath();
1188            mUserAppDataDir = new File(dataDir, "user");
1189            mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
1190
1191            sUserManager = new UserManagerService(context, this,
1192                    mInstallLock, mPackages);
1193
1194            // Read permissions and features from system
1195            readPermissions(Environment.buildPath(
1196                    Environment.getRootDirectory(), "etc", "permissions"), false);
1197            // Only read features from OEM
1198            readPermissions(Environment.buildPath(
1199                    Environment.getOemDirectory(), "etc", "permissions"), true);
1200
1201            mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
1202
1203            mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false),
1204                    mSdkVersion, mOnlyCore);
1205
1206            String customResolverActivity = Resources.getSystem().getString(
1207                    R.string.config_customResolverActivity);
1208            if (TextUtils.isEmpty(customResolverActivity)) {
1209                customResolverActivity = null;
1210            } else {
1211                mCustomResolverComponentName = ComponentName.unflattenFromString(
1212                        customResolverActivity);
1213            }
1214
1215            long startTime = SystemClock.uptimeMillis();
1216
1217            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
1218                    startTime);
1219
1220            // Set flag to monitor and not change apk file paths when
1221            // scanning install directories.
1222            int scanMode = SCAN_MONITOR | SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING;
1223            if (mNoDexOpt) {
1224                Slog.w(TAG, "Running ENG build: no pre-dexopt!");
1225                scanMode |= SCAN_NO_DEX;
1226            }
1227
1228            final HashSet<String> alreadyDexOpted = new HashSet<String>();
1229
1230            /**
1231             * Add everything in the in the boot class path to the
1232             * list of process files because dexopt will have been run
1233             * if necessary during zygote startup.
1234             */
1235            String bootClassPath = System.getProperty("java.boot.class.path");
1236            if (bootClassPath != null) {
1237                String[] paths = splitString(bootClassPath, ':');
1238                for (int i=0; i<paths.length; i++) {
1239                    alreadyDexOpted.add(paths[i]);
1240                }
1241            } else {
1242                Slog.w(TAG, "No BOOTCLASSPATH found!");
1243            }
1244
1245            boolean didDexOpt = false;
1246
1247            /**
1248             * Ensure all external libraries have had dexopt run on them.
1249             */
1250            if (mSharedLibraries.size() > 0) {
1251                Iterator<SharedLibraryEntry> libs = mSharedLibraries.values().iterator();
1252                while (libs.hasNext()) {
1253                    String lib = libs.next().path;
1254                    if (lib == null) {
1255                        continue;
1256                    }
1257                    try {
1258                        if (dalvik.system.DexFile.isDexOptNeededInternal(lib, null, false)) {
1259                            alreadyDexOpted.add(lib);
1260                            mInstaller.dexopt(lib, Process.SYSTEM_UID, true);
1261                            didDexOpt = true;
1262                        }
1263                    } catch (FileNotFoundException e) {
1264                        Slog.w(TAG, "Library not found: " + lib);
1265                    } catch (IOException e) {
1266                        Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
1267                                + e.getMessage());
1268                    }
1269                }
1270            }
1271
1272            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
1273
1274            // Gross hack for now: we know this file doesn't contain any
1275            // code, so don't dexopt it to avoid the resulting log spew.
1276            alreadyDexOpted.add(frameworkDir.getPath() + "/framework-res.apk");
1277
1278            // Gross hack for now: we know this file is only part of
1279            // the boot class path for art, so don't dexopt it to
1280            // avoid the resulting log spew.
1281            alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar");
1282
1283            /**
1284             * And there are a number of commands implemented in Java, which
1285             * we currently need to do the dexopt on so that they can be
1286             * run from a non-root shell.
1287             */
1288            String[] frameworkFiles = frameworkDir.list();
1289            if (frameworkFiles != null) {
1290                for (int i=0; i<frameworkFiles.length; i++) {
1291                    File libPath = new File(frameworkDir, frameworkFiles[i]);
1292                    String path = libPath.getPath();
1293                    // Skip the file if we alrady did it.
1294                    if (alreadyDexOpted.contains(path)) {
1295                        continue;
1296                    }
1297                    // Skip the file if it is not a type we want to dexopt.
1298                    if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
1299                        continue;
1300                    }
1301                    try {
1302                        if (dalvik.system.DexFile.isDexOptNeededInternal(path, null, false)) {
1303                            mInstaller.dexopt(path, Process.SYSTEM_UID, true);
1304                            didDexOpt = true;
1305                        }
1306                    } catch (FileNotFoundException e) {
1307                        Slog.w(TAG, "Jar not found: " + path);
1308                    } catch (IOException e) {
1309                        Slog.w(TAG, "Exception reading jar: " + path, e);
1310                    }
1311                }
1312            }
1313
1314            if (didDexOpt) {
1315                File dalvikCacheDir = new File(dataDir, "dalvik-cache");
1316
1317                // If we had to do a dexopt of one of the previous
1318                // things, then something on the system has changed.
1319                // Consider this significant, and wipe away all other
1320                // existing dexopt files to ensure we don't leave any
1321                // dangling around.
1322                String[] files = dalvikCacheDir.list();
1323                if (files != null) {
1324                    for (int i=0; i<files.length; i++) {
1325                        String fn = files[i];
1326                        if (fn.startsWith("data@app@")
1327                                || fn.startsWith("data@app-private@")) {
1328                            Slog.i(TAG, "Pruning dalvik file: " + fn);
1329                            (new File(dalvikCacheDir, fn)).delete();
1330                        }
1331                    }
1332                }
1333            }
1334
1335            // Collect vendor overlay packages.
1336            // (Do this before scanning any apps.)
1337            // For security and version matching reason, only consider
1338            // overlay packages if they reside in VENDOR_OVERLAY_DIR.
1339            File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR);
1340            mVendorOverlayInstallObserver = new AppDirObserver(
1341                vendorOverlayDir.getPath(), OBSERVER_EVENTS, true, false);
1342            mVendorOverlayInstallObserver.startWatching();
1343            scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM
1344                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode | SCAN_TRUSTED_OVERLAY, 0);
1345
1346            // Find base frameworks (resource packages without code).
1347            mFrameworkInstallObserver = new AppDirObserver(
1348                frameworkDir.getPath(), OBSERVER_EVENTS, true, false);
1349            mFrameworkInstallObserver.startWatching();
1350            scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM
1351                    | PackageParser.PARSE_IS_SYSTEM_DIR
1352                    | PackageParser.PARSE_IS_PRIVILEGED,
1353                    scanMode | SCAN_NO_DEX, 0);
1354
1355            // Collected privileged system packages.
1356            File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
1357            mPrivilegedInstallObserver = new AppDirObserver(
1358                    privilegedAppDir.getPath(), OBSERVER_EVENTS, true, true);
1359            mPrivilegedInstallObserver.startWatching();
1360                scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM
1361                        | PackageParser.PARSE_IS_SYSTEM_DIR
1362                        | PackageParser.PARSE_IS_PRIVILEGED, scanMode, 0);
1363
1364            // Collect ordinary system packages.
1365            File systemAppDir = new File(Environment.getRootDirectory(), "app");
1366            mSystemInstallObserver = new AppDirObserver(
1367                systemAppDir.getPath(), OBSERVER_EVENTS, true, false);
1368            mSystemInstallObserver.startWatching();
1369            scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM
1370                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
1371
1372            // Collect all vendor packages.
1373            File vendorAppDir = new File("/vendor/app");
1374            try {
1375                vendorAppDir = vendorAppDir.getCanonicalFile();
1376            } catch (IOException e) {
1377                // failed to look up canonical path, continue with original one
1378            }
1379            mVendorInstallObserver = new AppDirObserver(
1380                vendorAppDir.getPath(), OBSERVER_EVENTS, true, false);
1381            mVendorInstallObserver.startWatching();
1382            scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM
1383                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
1384
1385            // Collect all OEM packages.
1386            File oemAppDir = new File(Environment.getOemDirectory(), "app");
1387            mOemInstallObserver = new AppDirObserver(
1388                    oemAppDir.getPath(), OBSERVER_EVENTS, true, false);
1389            mOemInstallObserver.startWatching();
1390            scanDirLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM
1391                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
1392
1393            if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");
1394            mInstaller.moveFiles();
1395
1396            // Prune any system packages that no longer exist.
1397            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
1398            if (!mOnlyCore) {
1399                Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
1400                while (psit.hasNext()) {
1401                    PackageSetting ps = psit.next();
1402
1403                    /*
1404                     * If this is not a system app, it can't be a
1405                     * disable system app.
1406                     */
1407                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
1408                        continue;
1409                    }
1410
1411                    /*
1412                     * If the package is scanned, it's not erased.
1413                     */
1414                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
1415                    if (scannedPkg != null) {
1416                        /*
1417                         * If the system app is both scanned and in the
1418                         * disabled packages list, then it must have been
1419                         * added via OTA. Remove it from the currently
1420                         * scanned package so the previously user-installed
1421                         * application can be scanned.
1422                         */
1423                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
1424                            Slog.i(TAG, "Expecting better updatd system app for " + ps.name
1425                                    + "; removing system app");
1426                            removePackageLI(ps, true);
1427                        }
1428
1429                        continue;
1430                    }
1431
1432                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
1433                        psit.remove();
1434                        String msg = "System package " + ps.name
1435                                + " no longer exists; wiping its data";
1436                        reportSettingsProblem(Log.WARN, msg);
1437                        removeDataDirsLI(ps.name);
1438                    } else {
1439                        final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
1440                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
1441                            possiblyDeletedUpdatedSystemApps.add(ps.name);
1442                        }
1443                    }
1444                }
1445            }
1446
1447            //look for any incomplete package installations
1448            ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
1449            //clean up list
1450            for(int i = 0; i < deletePkgsList.size(); i++) {
1451                //clean up here
1452                cleanupInstallFailedPackage(deletePkgsList.get(i));
1453            }
1454            //delete tmp files
1455            deleteTempPackageFiles();
1456
1457            // Remove any shared userIDs that have no associated packages
1458            mSettings.pruneSharedUsersLPw();
1459
1460            if (!mOnlyCore) {
1461                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
1462                        SystemClock.uptimeMillis());
1463                mAppInstallObserver = new AppDirObserver(
1464                    mAppInstallDir.getPath(), OBSERVER_EVENTS, false, false);
1465                mAppInstallObserver.startWatching();
1466                scanDirLI(mAppInstallDir, 0, scanMode, 0);
1467
1468                mDrmAppInstallObserver = new AppDirObserver(
1469                    mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false, false);
1470                mDrmAppInstallObserver.startWatching();
1471                scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
1472                        scanMode, 0);
1473
1474                /**
1475                 * Remove disable package settings for any updated system
1476                 * apps that were removed via an OTA. If they're not a
1477                 * previously-updated app, remove them completely.
1478                 * Otherwise, just revoke their system-level permissions.
1479                 */
1480                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
1481                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
1482                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
1483
1484                    String msg;
1485                    if (deletedPkg == null) {
1486                        msg = "Updated system package " + deletedAppName
1487                                + " no longer exists; wiping its data";
1488                        removeDataDirsLI(deletedAppName);
1489                    } else {
1490                        msg = "Updated system app + " + deletedAppName
1491                                + " no longer present; removing system privileges for "
1492                                + deletedAppName;
1493
1494                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
1495
1496                        PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
1497                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
1498                    }
1499                    reportSettingsProblem(Log.WARN, msg);
1500                }
1501            } else {
1502                mAppInstallObserver = null;
1503                mDrmAppInstallObserver = null;
1504            }
1505
1506            // Now that we know all of the shared libraries, update all clients to have
1507            // the correct library paths.
1508            updateAllSharedLibrariesLPw();
1509
1510            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
1511                    SystemClock.uptimeMillis());
1512            Slog.i(TAG, "Time to scan packages: "
1513                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
1514                    + " seconds");
1515
1516            // If the platform SDK has changed since the last time we booted,
1517            // we need to re-grant app permission to catch any new ones that
1518            // appear.  This is really a hack, and means that apps can in some
1519            // cases get permissions that the user didn't initially explicitly
1520            // allow...  it would be nice to have some better way to handle
1521            // this situation.
1522            final boolean regrantPermissions = mSettings.mInternalSdkPlatform
1523                    != mSdkVersion;
1524            if (regrantPermissions) Slog.i(TAG, "Platform changed from "
1525                    + mSettings.mInternalSdkPlatform + " to " + mSdkVersion
1526                    + "; regranting permissions for internal storage");
1527            mSettings.mInternalSdkPlatform = mSdkVersion;
1528
1529            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
1530                    | (regrantPermissions
1531                            ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
1532                            : 0));
1533
1534            // If this is the first boot, and it is a normal boot, then
1535            // we need to initialize the default preferred apps.
1536            if (!mRestoredSettings && !onlyCore) {
1537                mSettings.readDefaultPreferredAppsLPw(this, 0);
1538            }
1539
1540            // All the changes are done during package scanning.
1541            mSettings.updateInternalDatabaseVersion();
1542
1543            // can downgrade to reader
1544            mSettings.writeLPr();
1545
1546            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
1547                    SystemClock.uptimeMillis());
1548
1549            // Now after opening every single application zip, make sure they
1550            // are all flushed.  Not really needed, but keeps things nice and
1551            // tidy.
1552            Runtime.getRuntime().gc();
1553
1554            mRequiredVerifierPackage = getRequiredVerifierLPr();
1555        } // synchronized (mPackages)
1556        } // synchronized (mInstallLock)
1557    }
1558
1559    public boolean isFirstBoot() {
1560        return !mRestoredSettings;
1561    }
1562
1563    public boolean isOnlyCoreApps() {
1564        return mOnlyCore;
1565    }
1566
1567    private String getRequiredVerifierLPr() {
1568        final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
1569        final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE,
1570                PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */);
1571
1572        String requiredVerifier = null;
1573
1574        final int N = receivers.size();
1575        for (int i = 0; i < N; i++) {
1576            final ResolveInfo info = receivers.get(i);
1577
1578            if (info.activityInfo == null) {
1579                continue;
1580            }
1581
1582            final String packageName = info.activityInfo.packageName;
1583
1584            final PackageSetting ps = mSettings.mPackages.get(packageName);
1585            if (ps == null) {
1586                continue;
1587            }
1588
1589            final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
1590            if (!gp.grantedPermissions
1591                    .contains(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT)) {
1592                continue;
1593            }
1594
1595            if (requiredVerifier != null) {
1596                throw new RuntimeException("There can be only one required verifier");
1597            }
1598
1599            requiredVerifier = packageName;
1600        }
1601
1602        return requiredVerifier;
1603    }
1604
1605    @Override
1606    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1607            throws RemoteException {
1608        try {
1609            return super.onTransact(code, data, reply, flags);
1610        } catch (RuntimeException e) {
1611            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
1612                Slog.wtf(TAG, "Package Manager Crash", e);
1613            }
1614            throw e;
1615        }
1616    }
1617
1618    void cleanupInstallFailedPackage(PackageSetting ps) {
1619        Slog.i(TAG, "Cleaning up incompletely installed app: " + ps.name);
1620        removeDataDirsLI(ps.name);
1621        if (ps.codePath != null) {
1622            if (!ps.codePath.delete()) {
1623                Slog.w(TAG, "Unable to remove old code file: " + ps.codePath);
1624            }
1625        }
1626        if (ps.resourcePath != null) {
1627            if (!ps.resourcePath.delete() && !ps.resourcePath.equals(ps.codePath)) {
1628                Slog.w(TAG, "Unable to remove old code file: " + ps.resourcePath);
1629            }
1630        }
1631        mSettings.removePackageLPw(ps.name);
1632    }
1633
1634    void readPermissions(File libraryDir, boolean onlyFeatures) {
1635        // Read permissions from .../etc/permission directory.
1636        if (!libraryDir.exists() || !libraryDir.isDirectory()) {
1637            Slog.w(TAG, "No directory " + libraryDir + ", skipping");
1638            return;
1639        }
1640        if (!libraryDir.canRead()) {
1641            Slog.w(TAG, "Directory " + libraryDir + " cannot be read");
1642            return;
1643        }
1644
1645        // Iterate over the files in the directory and scan .xml files
1646        for (File f : libraryDir.listFiles()) {
1647            // We'll read platform.xml last
1648            if (f.getPath().endsWith("etc/permissions/platform.xml")) {
1649                continue;
1650            }
1651
1652            if (!f.getPath().endsWith(".xml")) {
1653                Slog.i(TAG, "Non-xml file " + f + " in " + libraryDir + " directory, ignoring");
1654                continue;
1655            }
1656            if (!f.canRead()) {
1657                Slog.w(TAG, "Permissions library file " + f + " cannot be read");
1658                continue;
1659            }
1660
1661            readPermissionsFromXml(f, onlyFeatures);
1662        }
1663
1664        // Read permissions from .../etc/permissions/platform.xml last so it will take precedence
1665        final File permFile = new File(Environment.getRootDirectory(),
1666                "etc/permissions/platform.xml");
1667        readPermissionsFromXml(permFile, onlyFeatures);
1668    }
1669
1670    private void readPermissionsFromXml(File permFile, boolean onlyFeatures) {
1671        FileReader permReader = null;
1672        try {
1673            permReader = new FileReader(permFile);
1674        } catch (FileNotFoundException e) {
1675            Slog.w(TAG, "Couldn't find or open permissions file " + permFile);
1676            return;
1677        }
1678
1679        try {
1680            XmlPullParser parser = Xml.newPullParser();
1681            parser.setInput(permReader);
1682
1683            XmlUtils.beginDocument(parser, "permissions");
1684
1685            while (true) {
1686                XmlUtils.nextElement(parser);
1687                if (parser.getEventType() == XmlPullParser.END_DOCUMENT) {
1688                    break;
1689                }
1690
1691                String name = parser.getName();
1692                if ("group".equals(name) && !onlyFeatures) {
1693                    String gidStr = parser.getAttributeValue(null, "gid");
1694                    if (gidStr != null) {
1695                        int gid = Process.getGidForName(gidStr);
1696                        mGlobalGids = appendInt(mGlobalGids, gid);
1697                    } else {
1698                        Slog.w(TAG, "<group> without gid at "
1699                                + parser.getPositionDescription());
1700                    }
1701
1702                    XmlUtils.skipCurrentTag(parser);
1703                    continue;
1704                } else if ("permission".equals(name) && !onlyFeatures) {
1705                    String perm = parser.getAttributeValue(null, "name");
1706                    if (perm == null) {
1707                        Slog.w(TAG, "<permission> without name at "
1708                                + parser.getPositionDescription());
1709                        XmlUtils.skipCurrentTag(parser);
1710                        continue;
1711                    }
1712                    perm = perm.intern();
1713                    readPermission(parser, perm);
1714
1715                } else if ("assign-permission".equals(name) && !onlyFeatures) {
1716                    String perm = parser.getAttributeValue(null, "name");
1717                    if (perm == null) {
1718                        Slog.w(TAG, "<assign-permission> without name at "
1719                                + parser.getPositionDescription());
1720                        XmlUtils.skipCurrentTag(parser);
1721                        continue;
1722                    }
1723                    String uidStr = parser.getAttributeValue(null, "uid");
1724                    if (uidStr == null) {
1725                        Slog.w(TAG, "<assign-permission> without uid at "
1726                                + parser.getPositionDescription());
1727                        XmlUtils.skipCurrentTag(parser);
1728                        continue;
1729                    }
1730                    int uid = Process.getUidForName(uidStr);
1731                    if (uid < 0) {
1732                        Slog.w(TAG, "<assign-permission> with unknown uid \""
1733                                + uidStr + "\" at "
1734                                + parser.getPositionDescription());
1735                        XmlUtils.skipCurrentTag(parser);
1736                        continue;
1737                    }
1738                    perm = perm.intern();
1739                    HashSet<String> perms = mSystemPermissions.get(uid);
1740                    if (perms == null) {
1741                        perms = new HashSet<String>();
1742                        mSystemPermissions.put(uid, perms);
1743                    }
1744                    perms.add(perm);
1745                    XmlUtils.skipCurrentTag(parser);
1746
1747                } else if ("library".equals(name) && !onlyFeatures) {
1748                    String lname = parser.getAttributeValue(null, "name");
1749                    String lfile = parser.getAttributeValue(null, "file");
1750                    if (lname == null) {
1751                        Slog.w(TAG, "<library> without name at "
1752                                + parser.getPositionDescription());
1753                    } else if (lfile == null) {
1754                        Slog.w(TAG, "<library> without file at "
1755                                + parser.getPositionDescription());
1756                    } else {
1757                        //Log.i(TAG, "Got library " + lname + " in " + lfile);
1758                        mSharedLibraries.put(lname, new SharedLibraryEntry(lfile, null));
1759                    }
1760                    XmlUtils.skipCurrentTag(parser);
1761                    continue;
1762
1763                } else if ("feature".equals(name)) {
1764                    String fname = parser.getAttributeValue(null, "name");
1765                    if (fname == null) {
1766                        Slog.w(TAG, "<feature> without name at "
1767                                + parser.getPositionDescription());
1768                    } else {
1769                        //Log.i(TAG, "Got feature " + fname);
1770                        FeatureInfo fi = new FeatureInfo();
1771                        fi.name = fname;
1772                        mAvailableFeatures.put(fname, fi);
1773                    }
1774                    XmlUtils.skipCurrentTag(parser);
1775                    continue;
1776
1777                } else {
1778                    XmlUtils.skipCurrentTag(parser);
1779                    continue;
1780                }
1781
1782            }
1783            permReader.close();
1784        } catch (XmlPullParserException e) {
1785            Slog.w(TAG, "Got execption parsing permissions.", e);
1786        } catch (IOException e) {
1787            Slog.w(TAG, "Got execption parsing permissions.", e);
1788        }
1789    }
1790
1791    void readPermission(XmlPullParser parser, String name)
1792            throws IOException, XmlPullParserException {
1793
1794        name = name.intern();
1795
1796        BasePermission bp = mSettings.mPermissions.get(name);
1797        if (bp == null) {
1798            bp = new BasePermission(name, null, BasePermission.TYPE_BUILTIN);
1799            mSettings.mPermissions.put(name, bp);
1800        }
1801        int outerDepth = parser.getDepth();
1802        int type;
1803        while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
1804               && (type != XmlPullParser.END_TAG
1805                       || parser.getDepth() > outerDepth)) {
1806            if (type == XmlPullParser.END_TAG
1807                    || type == XmlPullParser.TEXT) {
1808                continue;
1809            }
1810
1811            String tagName = parser.getName();
1812            if ("group".equals(tagName)) {
1813                String gidStr = parser.getAttributeValue(null, "gid");
1814                if (gidStr != null) {
1815                    int gid = Process.getGidForName(gidStr);
1816                    bp.gids = appendInt(bp.gids, gid);
1817                } else {
1818                    Slog.w(TAG, "<group> without gid at "
1819                            + parser.getPositionDescription());
1820                }
1821            }
1822            XmlUtils.skipCurrentTag(parser);
1823        }
1824    }
1825
1826    static int[] appendInts(int[] cur, int[] add) {
1827        if (add == null) return cur;
1828        if (cur == null) return add;
1829        final int N = add.length;
1830        for (int i=0; i<N; i++) {
1831            cur = appendInt(cur, add[i]);
1832        }
1833        return cur;
1834    }
1835
1836    static int[] removeInts(int[] cur, int[] rem) {
1837        if (rem == null) return cur;
1838        if (cur == null) return cur;
1839        final int N = rem.length;
1840        for (int i=0; i<N; i++) {
1841            cur = removeInt(cur, rem[i]);
1842        }
1843        return cur;
1844    }
1845
1846    PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) {
1847        if (!sUserManager.exists(userId)) return null;
1848        PackageInfo pi;
1849        final PackageSetting ps = (PackageSetting) p.mExtras;
1850        if (ps == null) {
1851            return null;
1852        }
1853        final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
1854        final PackageUserState state = ps.readUserState(userId);
1855        return PackageParser.generatePackageInfo(p, gp.gids, flags,
1856                ps.firstInstallTime, ps.lastUpdateTime, gp.grantedPermissions,
1857                state, userId);
1858    }
1859
1860    public boolean isPackageAvailable(String packageName, int userId) {
1861        if (!sUserManager.exists(userId)) return false;
1862        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "is package available");
1863        synchronized (mPackages) {
1864            PackageParser.Package p = mPackages.get(packageName);
1865            if (p != null) {
1866                final PackageSetting ps = (PackageSetting) p.mExtras;
1867                if (ps != null) {
1868                    final PackageUserState state = ps.readUserState(userId);
1869                    if (state != null) {
1870                        return PackageParser.isAvailable(state);
1871                    }
1872                }
1873            }
1874        }
1875        return false;
1876    }
1877
1878    @Override
1879    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
1880        if (!sUserManager.exists(userId)) return null;
1881        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get package info");
1882        // reader
1883        synchronized (mPackages) {
1884            PackageParser.Package p = mPackages.get(packageName);
1885            if (DEBUG_PACKAGE_INFO)
1886                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
1887            if (p != null) {
1888                return generatePackageInfo(p, flags, userId);
1889            }
1890            if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
1891                return generatePackageInfoFromSettingsLPw(packageName, flags, userId);
1892            }
1893        }
1894        return null;
1895    }
1896
1897    public String[] currentToCanonicalPackageNames(String[] names) {
1898        String[] out = new String[names.length];
1899        // reader
1900        synchronized (mPackages) {
1901            for (int i=names.length-1; i>=0; i--) {
1902                PackageSetting ps = mSettings.mPackages.get(names[i]);
1903                out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
1904            }
1905        }
1906        return out;
1907    }
1908
1909    public String[] canonicalToCurrentPackageNames(String[] names) {
1910        String[] out = new String[names.length];
1911        // reader
1912        synchronized (mPackages) {
1913            for (int i=names.length-1; i>=0; i--) {
1914                String cur = mSettings.mRenamedPackages.get(names[i]);
1915                out[i] = cur != null ? cur : names[i];
1916            }
1917        }
1918        return out;
1919    }
1920
1921    @Override
1922    public int getPackageUid(String packageName, int userId) {
1923        if (!sUserManager.exists(userId)) return -1;
1924        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get package uid");
1925        // reader
1926        synchronized (mPackages) {
1927            PackageParser.Package p = mPackages.get(packageName);
1928            if(p != null) {
1929                return UserHandle.getUid(userId, p.applicationInfo.uid);
1930            }
1931            PackageSetting ps = mSettings.mPackages.get(packageName);
1932            if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) {
1933                return -1;
1934            }
1935            p = ps.pkg;
1936            return p != null ? UserHandle.getUid(userId, p.applicationInfo.uid) : -1;
1937        }
1938    }
1939
1940    @Override
1941    public int[] getPackageGids(String packageName) {
1942        // reader
1943        synchronized (mPackages) {
1944            PackageParser.Package p = mPackages.get(packageName);
1945            if (DEBUG_PACKAGE_INFO)
1946                Log.v(TAG, "getPackageGids" + packageName + ": " + p);
1947            if (p != null) {
1948                final PackageSetting ps = (PackageSetting)p.mExtras;
1949                return ps.getGids();
1950            }
1951        }
1952        // stupid thing to indicate an error.
1953        return new int[0];
1954    }
1955
1956    static final PermissionInfo generatePermissionInfo(
1957            BasePermission bp, int flags) {
1958        if (bp.perm != null) {
1959            return PackageParser.generatePermissionInfo(bp.perm, flags);
1960        }
1961        PermissionInfo pi = new PermissionInfo();
1962        pi.name = bp.name;
1963        pi.packageName = bp.sourcePackage;
1964        pi.nonLocalizedLabel = bp.name;
1965        pi.protectionLevel = bp.protectionLevel;
1966        return pi;
1967    }
1968
1969    public PermissionInfo getPermissionInfo(String name, int flags) {
1970        // reader
1971        synchronized (mPackages) {
1972            final BasePermission p = mSettings.mPermissions.get(name);
1973            if (p != null) {
1974                return generatePermissionInfo(p, flags);
1975            }
1976            return null;
1977        }
1978    }
1979
1980    public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) {
1981        // reader
1982        synchronized (mPackages) {
1983            ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
1984            for (BasePermission p : mSettings.mPermissions.values()) {
1985                if (group == null) {
1986                    if (p.perm == null || p.perm.info.group == null) {
1987                        out.add(generatePermissionInfo(p, flags));
1988                    }
1989                } else {
1990                    if (p.perm != null && group.equals(p.perm.info.group)) {
1991                        out.add(PackageParser.generatePermissionInfo(p.perm, flags));
1992                    }
1993                }
1994            }
1995
1996            if (out.size() > 0) {
1997                return out;
1998            }
1999            return mPermissionGroups.containsKey(group) ? out : null;
2000        }
2001    }
2002
2003    public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
2004        // reader
2005        synchronized (mPackages) {
2006            return PackageParser.generatePermissionGroupInfo(
2007                    mPermissionGroups.get(name), flags);
2008        }
2009    }
2010
2011    public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
2012        // reader
2013        synchronized (mPackages) {
2014            final int N = mPermissionGroups.size();
2015            ArrayList<PermissionGroupInfo> out
2016                    = new ArrayList<PermissionGroupInfo>(N);
2017            for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
2018                out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
2019            }
2020            return out;
2021        }
2022    }
2023
2024    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
2025            int userId) {
2026        if (!sUserManager.exists(userId)) return null;
2027        PackageSetting ps = mSettings.mPackages.get(packageName);
2028        if (ps != null) {
2029            if (ps.pkg == null) {
2030                PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName,
2031                        flags, userId);
2032                if (pInfo != null) {
2033                    return pInfo.applicationInfo;
2034                }
2035                return null;
2036            }
2037            return PackageParser.generateApplicationInfo(ps.pkg, flags,
2038                    ps.readUserState(userId), userId);
2039        }
2040        return null;
2041    }
2042
2043    private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags,
2044            int userId) {
2045        if (!sUserManager.exists(userId)) return null;
2046        PackageSetting ps = mSettings.mPackages.get(packageName);
2047        if (ps != null) {
2048            PackageParser.Package pkg = ps.pkg;
2049            if (pkg == null) {
2050                if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) == 0) {
2051                    return null;
2052                }
2053                pkg = new PackageParser.Package(packageName);
2054                pkg.applicationInfo.packageName = packageName;
2055                pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY;
2056                pkg.applicationInfo.publicSourceDir = ps.resourcePathString;
2057                pkg.applicationInfo.sourceDir = ps.codePathString;
2058                pkg.applicationInfo.dataDir =
2059                        getDataPathForPackage(packageName, 0).getPath();
2060                pkg.applicationInfo.nativeLibraryDir = ps.nativeLibraryPathString;
2061                pkg.applicationInfo.requiredCpuAbi = ps.requiredCpuAbiString;
2062            }
2063            return generatePackageInfo(pkg, flags, userId);
2064        }
2065        return null;
2066    }
2067
2068    @Override
2069    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
2070        if (!sUserManager.exists(userId)) return null;
2071        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get application info");
2072        // writer
2073        synchronized (mPackages) {
2074            PackageParser.Package p = mPackages.get(packageName);
2075            if (DEBUG_PACKAGE_INFO) Log.v(
2076                    TAG, "getApplicationInfo " + packageName
2077                    + ": " + p);
2078            if (p != null) {
2079                PackageSetting ps = mSettings.mPackages.get(packageName);
2080                if (ps == null) return null;
2081                // Note: isEnabledLP() does not apply here - always return info
2082                return PackageParser.generateApplicationInfo(
2083                        p, flags, ps.readUserState(userId), userId);
2084            }
2085            if ("android".equals(packageName)||"system".equals(packageName)) {
2086                return mAndroidApplication;
2087            }
2088            if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
2089                return generateApplicationInfoFromSettingsLPw(packageName, flags, userId);
2090            }
2091        }
2092        return null;
2093    }
2094
2095
2096    public void freeStorageAndNotify(final long freeStorageSize, final IPackageDataObserver observer) {
2097        mContext.enforceCallingOrSelfPermission(
2098                android.Manifest.permission.CLEAR_APP_CACHE, null);
2099        // Queue up an async operation since clearing cache may take a little while.
2100        mHandler.post(new Runnable() {
2101            public void run() {
2102                mHandler.removeCallbacks(this);
2103                int retCode = -1;
2104                synchronized (mInstallLock) {
2105                    retCode = mInstaller.freeCache(freeStorageSize);
2106                    if (retCode < 0) {
2107                        Slog.w(TAG, "Couldn't clear application caches");
2108                    }
2109                }
2110                if (observer != null) {
2111                    try {
2112                        observer.onRemoveCompleted(null, (retCode >= 0));
2113                    } catch (RemoteException e) {
2114                        Slog.w(TAG, "RemoveException when invoking call back");
2115                    }
2116                }
2117            }
2118        });
2119    }
2120
2121    public void freeStorage(final long freeStorageSize, final IntentSender pi) {
2122        mContext.enforceCallingOrSelfPermission(
2123                android.Manifest.permission.CLEAR_APP_CACHE, null);
2124        // Queue up an async operation since clearing cache may take a little while.
2125        mHandler.post(new Runnable() {
2126            public void run() {
2127                mHandler.removeCallbacks(this);
2128                int retCode = -1;
2129                synchronized (mInstallLock) {
2130                    retCode = mInstaller.freeCache(freeStorageSize);
2131                    if (retCode < 0) {
2132                        Slog.w(TAG, "Couldn't clear application caches");
2133                    }
2134                }
2135                if(pi != null) {
2136                    try {
2137                        // Callback via pending intent
2138                        int code = (retCode >= 0) ? 1 : 0;
2139                        pi.sendIntent(null, code, null,
2140                                null, null);
2141                    } catch (SendIntentException e1) {
2142                        Slog.i(TAG, "Failed to send pending intent");
2143                    }
2144                }
2145            }
2146        });
2147    }
2148
2149    @Override
2150    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
2151        if (!sUserManager.exists(userId)) return null;
2152        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get activity info");
2153        synchronized (mPackages) {
2154            PackageParser.Activity a = mActivities.mActivities.get(component);
2155
2156            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
2157            if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
2158                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2159                if (ps == null) return null;
2160                return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
2161                        userId);
2162            }
2163            if (mResolveComponentName.equals(component)) {
2164                return mResolveActivity;
2165            }
2166        }
2167        return null;
2168    }
2169
2170    @Override
2171    public boolean activitySupportsIntent(ComponentName component, Intent intent,
2172            String resolvedType) {
2173        synchronized (mPackages) {
2174            PackageParser.Activity a = mActivities.mActivities.get(component);
2175            if (a == null) {
2176                return false;
2177            }
2178            for (int i=0; i<a.intents.size(); i++) {
2179                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
2180                        intent.getData(), intent.getCategories(), TAG) >= 0) {
2181                    return true;
2182                }
2183            }
2184            return false;
2185        }
2186    }
2187
2188    @Override
2189    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
2190        if (!sUserManager.exists(userId)) return null;
2191        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get receiver info");
2192        synchronized (mPackages) {
2193            PackageParser.Activity a = mReceivers.mActivities.get(component);
2194            if (DEBUG_PACKAGE_INFO) Log.v(
2195                TAG, "getReceiverInfo " + component + ": " + a);
2196            if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
2197                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2198                if (ps == null) return null;
2199                return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
2200                        userId);
2201            }
2202        }
2203        return null;
2204    }
2205
2206    @Override
2207    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
2208        if (!sUserManager.exists(userId)) return null;
2209        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get service info");
2210        synchronized (mPackages) {
2211            PackageParser.Service s = mServices.mServices.get(component);
2212            if (DEBUG_PACKAGE_INFO) Log.v(
2213                TAG, "getServiceInfo " + component + ": " + s);
2214            if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) {
2215                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2216                if (ps == null) return null;
2217                return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
2218                        userId);
2219            }
2220        }
2221        return null;
2222    }
2223
2224    @Override
2225    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
2226        if (!sUserManager.exists(userId)) return null;
2227        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get provider info");
2228        synchronized (mPackages) {
2229            PackageParser.Provider p = mProviders.mProviders.get(component);
2230            if (DEBUG_PACKAGE_INFO) Log.v(
2231                TAG, "getProviderInfo " + component + ": " + p);
2232            if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) {
2233                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2234                if (ps == null) return null;
2235                return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
2236                        userId);
2237            }
2238        }
2239        return null;
2240    }
2241
2242    public String[] getSystemSharedLibraryNames() {
2243        Set<String> libSet;
2244        synchronized (mPackages) {
2245            libSet = mSharedLibraries.keySet();
2246            int size = libSet.size();
2247            if (size > 0) {
2248                String[] libs = new String[size];
2249                libSet.toArray(libs);
2250                return libs;
2251            }
2252        }
2253        return null;
2254    }
2255
2256    public FeatureInfo[] getSystemAvailableFeatures() {
2257        Collection<FeatureInfo> featSet;
2258        synchronized (mPackages) {
2259            featSet = mAvailableFeatures.values();
2260            int size = featSet.size();
2261            if (size > 0) {
2262                FeatureInfo[] features = new FeatureInfo[size+1];
2263                featSet.toArray(features);
2264                FeatureInfo fi = new FeatureInfo();
2265                fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
2266                        FeatureInfo.GL_ES_VERSION_UNDEFINED);
2267                features[size] = fi;
2268                return features;
2269            }
2270        }
2271        return null;
2272    }
2273
2274    public boolean hasSystemFeature(String name) {
2275        synchronized (mPackages) {
2276            return mAvailableFeatures.containsKey(name);
2277        }
2278    }
2279
2280    private void checkValidCaller(int uid, int userId) {
2281        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0)
2282            return;
2283
2284        throw new SecurityException("Caller uid=" + uid
2285                + " is not privileged to communicate with user=" + userId);
2286    }
2287
2288    public int checkPermission(String permName, String pkgName) {
2289        synchronized (mPackages) {
2290            PackageParser.Package p = mPackages.get(pkgName);
2291            if (p != null && p.mExtras != null) {
2292                PackageSetting ps = (PackageSetting)p.mExtras;
2293                if (ps.sharedUser != null) {
2294                    if (ps.sharedUser.grantedPermissions.contains(permName)) {
2295                        return PackageManager.PERMISSION_GRANTED;
2296                    }
2297                } else if (ps.grantedPermissions.contains(permName)) {
2298                    return PackageManager.PERMISSION_GRANTED;
2299                }
2300            }
2301        }
2302        return PackageManager.PERMISSION_DENIED;
2303    }
2304
2305    public int checkUidPermission(String permName, int uid) {
2306        synchronized (mPackages) {
2307            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2308            if (obj != null) {
2309                GrantedPermissions gp = (GrantedPermissions)obj;
2310                if (gp.grantedPermissions.contains(permName)) {
2311                    return PackageManager.PERMISSION_GRANTED;
2312                }
2313            } else {
2314                HashSet<String> perms = mSystemPermissions.get(uid);
2315                if (perms != null && perms.contains(permName)) {
2316                    return PackageManager.PERMISSION_GRANTED;
2317                }
2318            }
2319        }
2320        return PackageManager.PERMISSION_DENIED;
2321    }
2322
2323    /**
2324     * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
2325     * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
2326     * @param message the message to log on security exception
2327     * @return
2328     */
2329    private void enforceCrossUserPermission(int callingUid, int userId,
2330            boolean requireFullPermission, String message) {
2331        if (userId < 0) {
2332            throw new IllegalArgumentException("Invalid userId " + userId);
2333        }
2334        if (userId == UserHandle.getUserId(callingUid)) return;
2335        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
2336            if (requireFullPermission) {
2337                mContext.enforceCallingOrSelfPermission(
2338                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2339            } else {
2340                try {
2341                    mContext.enforceCallingOrSelfPermission(
2342                            android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2343                } catch (SecurityException se) {
2344                    mContext.enforceCallingOrSelfPermission(
2345                            android.Manifest.permission.INTERACT_ACROSS_USERS, message);
2346                }
2347            }
2348        }
2349    }
2350
2351    private BasePermission findPermissionTreeLP(String permName) {
2352        for(BasePermission bp : mSettings.mPermissionTrees.values()) {
2353            if (permName.startsWith(bp.name) &&
2354                    permName.length() > bp.name.length() &&
2355                    permName.charAt(bp.name.length()) == '.') {
2356                return bp;
2357            }
2358        }
2359        return null;
2360    }
2361
2362    private BasePermission checkPermissionTreeLP(String permName) {
2363        if (permName != null) {
2364            BasePermission bp = findPermissionTreeLP(permName);
2365            if (bp != null) {
2366                if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
2367                    return bp;
2368                }
2369                throw new SecurityException("Calling uid "
2370                        + Binder.getCallingUid()
2371                        + " is not allowed to add to permission tree "
2372                        + bp.name + " owned by uid " + bp.uid);
2373            }
2374        }
2375        throw new SecurityException("No permission tree found for " + permName);
2376    }
2377
2378    static boolean compareStrings(CharSequence s1, CharSequence s2) {
2379        if (s1 == null) {
2380            return s2 == null;
2381        }
2382        if (s2 == null) {
2383            return false;
2384        }
2385        if (s1.getClass() != s2.getClass()) {
2386            return false;
2387        }
2388        return s1.equals(s2);
2389    }
2390
2391    static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
2392        if (pi1.icon != pi2.icon) return false;
2393        if (pi1.logo != pi2.logo) return false;
2394        if (pi1.protectionLevel != pi2.protectionLevel) return false;
2395        if (!compareStrings(pi1.name, pi2.name)) return false;
2396        if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
2397        // We'll take care of setting this one.
2398        if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
2399        // These are not currently stored in settings.
2400        //if (!compareStrings(pi1.group, pi2.group)) return false;
2401        //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
2402        //if (pi1.labelRes != pi2.labelRes) return false;
2403        //if (pi1.descriptionRes != pi2.descriptionRes) return false;
2404        return true;
2405    }
2406
2407    int permissionInfoFootprint(PermissionInfo info) {
2408        int size = info.name.length();
2409        if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
2410        if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
2411        return size;
2412    }
2413
2414    int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
2415        int size = 0;
2416        for (BasePermission perm : mSettings.mPermissions.values()) {
2417            if (perm.uid == tree.uid) {
2418                size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
2419            }
2420        }
2421        return size;
2422    }
2423
2424    void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
2425        // We calculate the max size of permissions defined by this uid and throw
2426        // if that plus the size of 'info' would exceed our stated maximum.
2427        if (tree.uid != Process.SYSTEM_UID) {
2428            final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
2429            if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
2430                throw new SecurityException("Permission tree size cap exceeded");
2431            }
2432        }
2433    }
2434
2435    boolean addPermissionLocked(PermissionInfo info, boolean async) {
2436        if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
2437            throw new SecurityException("Label must be specified in permission");
2438        }
2439        BasePermission tree = checkPermissionTreeLP(info.name);
2440        BasePermission bp = mSettings.mPermissions.get(info.name);
2441        boolean added = bp == null;
2442        boolean changed = true;
2443        int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
2444        if (added) {
2445            enforcePermissionCapLocked(info, tree);
2446            bp = new BasePermission(info.name, tree.sourcePackage,
2447                    BasePermission.TYPE_DYNAMIC);
2448        } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
2449            throw new SecurityException(
2450                    "Not allowed to modify non-dynamic permission "
2451                    + info.name);
2452        } else {
2453            if (bp.protectionLevel == fixedLevel
2454                    && bp.perm.owner.equals(tree.perm.owner)
2455                    && bp.uid == tree.uid
2456                    && comparePermissionInfos(bp.perm.info, info)) {
2457                changed = false;
2458            }
2459        }
2460        bp.protectionLevel = fixedLevel;
2461        info = new PermissionInfo(info);
2462        info.protectionLevel = fixedLevel;
2463        bp.perm = new PackageParser.Permission(tree.perm.owner, info);
2464        bp.perm.info.packageName = tree.perm.info.packageName;
2465        bp.uid = tree.uid;
2466        if (added) {
2467            mSettings.mPermissions.put(info.name, bp);
2468        }
2469        if (changed) {
2470            if (!async) {
2471                mSettings.writeLPr();
2472            } else {
2473                scheduleWriteSettingsLocked();
2474            }
2475        }
2476        return added;
2477    }
2478
2479    public boolean addPermission(PermissionInfo info) {
2480        synchronized (mPackages) {
2481            return addPermissionLocked(info, false);
2482        }
2483    }
2484
2485    public boolean addPermissionAsync(PermissionInfo info) {
2486        synchronized (mPackages) {
2487            return addPermissionLocked(info, true);
2488        }
2489    }
2490
2491    public void removePermission(String name) {
2492        synchronized (mPackages) {
2493            checkPermissionTreeLP(name);
2494            BasePermission bp = mSettings.mPermissions.get(name);
2495            if (bp != null) {
2496                if (bp.type != BasePermission.TYPE_DYNAMIC) {
2497                    throw new SecurityException(
2498                            "Not allowed to modify non-dynamic permission "
2499                            + name);
2500                }
2501                mSettings.mPermissions.remove(name);
2502                mSettings.writeLPr();
2503            }
2504        }
2505    }
2506
2507    private static void checkGrantRevokePermissions(PackageParser.Package pkg, BasePermission bp) {
2508        int index = pkg.requestedPermissions.indexOf(bp.name);
2509        if (index == -1) {
2510            throw new SecurityException("Package " + pkg.packageName
2511                    + " has not requested permission " + bp.name);
2512        }
2513        boolean isNormal =
2514                ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
2515                        == PermissionInfo.PROTECTION_NORMAL);
2516        boolean isDangerous =
2517                ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
2518                        == PermissionInfo.PROTECTION_DANGEROUS);
2519        boolean isDevelopment =
2520                ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0);
2521
2522        if (!isNormal && !isDangerous && !isDevelopment) {
2523            throw new SecurityException("Permission " + bp.name
2524                    + " is not a changeable permission type");
2525        }
2526
2527        if (isNormal || isDangerous) {
2528            if (pkg.requestedPermissionsRequired.get(index)) {
2529                throw new SecurityException("Can't change " + bp.name
2530                        + ". It is required by the application");
2531            }
2532        }
2533    }
2534
2535    public void grantPermission(String packageName, String permissionName) {
2536        mContext.enforceCallingOrSelfPermission(
2537                android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
2538        synchronized (mPackages) {
2539            final PackageParser.Package pkg = mPackages.get(packageName);
2540            if (pkg == null) {
2541                throw new IllegalArgumentException("Unknown package: " + packageName);
2542            }
2543            final BasePermission bp = mSettings.mPermissions.get(permissionName);
2544            if (bp == null) {
2545                throw new IllegalArgumentException("Unknown permission: " + permissionName);
2546            }
2547
2548            checkGrantRevokePermissions(pkg, bp);
2549
2550            final PackageSetting ps = (PackageSetting) pkg.mExtras;
2551            if (ps == null) {
2552                return;
2553            }
2554            final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;
2555            if (gp.grantedPermissions.add(permissionName)) {
2556                if (ps.haveGids) {
2557                    gp.gids = appendInts(gp.gids, bp.gids);
2558                }
2559                mSettings.writeLPr();
2560            }
2561        }
2562    }
2563
2564    public void revokePermission(String packageName, String permissionName) {
2565        int changedAppId = -1;
2566
2567        synchronized (mPackages) {
2568            final PackageParser.Package pkg = mPackages.get(packageName);
2569            if (pkg == null) {
2570                throw new IllegalArgumentException("Unknown package: " + packageName);
2571            }
2572            if (pkg.applicationInfo.uid != Binder.getCallingUid()) {
2573                mContext.enforceCallingOrSelfPermission(
2574                        android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
2575            }
2576            final BasePermission bp = mSettings.mPermissions.get(permissionName);
2577            if (bp == null) {
2578                throw new IllegalArgumentException("Unknown permission: " + permissionName);
2579            }
2580
2581            checkGrantRevokePermissions(pkg, bp);
2582
2583            final PackageSetting ps = (PackageSetting) pkg.mExtras;
2584            if (ps == null) {
2585                return;
2586            }
2587            final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;
2588            if (gp.grantedPermissions.remove(permissionName)) {
2589                gp.grantedPermissions.remove(permissionName);
2590                if (ps.haveGids) {
2591                    gp.gids = removeInts(gp.gids, bp.gids);
2592                }
2593                mSettings.writeLPr();
2594                changedAppId = ps.appId;
2595            }
2596        }
2597
2598        if (changedAppId >= 0) {
2599            // We changed the perm on someone, kill its processes.
2600            IActivityManager am = ActivityManagerNative.getDefault();
2601            if (am != null) {
2602                final int callingUserId = UserHandle.getCallingUserId();
2603                final long ident = Binder.clearCallingIdentity();
2604                try {
2605                    //XXX we should only revoke for the calling user's app permissions,
2606                    // but for now we impact all users.
2607                    //am.killUid(UserHandle.getUid(callingUserId, changedAppId),
2608                    //        "revoke " + permissionName);
2609                    int[] users = sUserManager.getUserIds();
2610                    for (int user : users) {
2611                        am.killUid(UserHandle.getUid(user, changedAppId),
2612                                "revoke " + permissionName);
2613                    }
2614                } catch (RemoteException e) {
2615                } finally {
2616                    Binder.restoreCallingIdentity(ident);
2617                }
2618            }
2619        }
2620    }
2621
2622    public boolean isProtectedBroadcast(String actionName) {
2623        synchronized (mPackages) {
2624            return mProtectedBroadcasts.contains(actionName);
2625        }
2626    }
2627
2628    public int checkSignatures(String pkg1, String pkg2) {
2629        synchronized (mPackages) {
2630            final PackageParser.Package p1 = mPackages.get(pkg1);
2631            final PackageParser.Package p2 = mPackages.get(pkg2);
2632            if (p1 == null || p1.mExtras == null
2633                    || p2 == null || p2.mExtras == null) {
2634                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2635            }
2636            return compareSignatures(p1.mSignatures, p2.mSignatures);
2637        }
2638    }
2639
2640    public int checkUidSignatures(int uid1, int uid2) {
2641        // Map to base uids.
2642        uid1 = UserHandle.getAppId(uid1);
2643        uid2 = UserHandle.getAppId(uid2);
2644        // reader
2645        synchronized (mPackages) {
2646            Signature[] s1;
2647            Signature[] s2;
2648            Object obj = mSettings.getUserIdLPr(uid1);
2649            if (obj != null) {
2650                if (obj instanceof SharedUserSetting) {
2651                    s1 = ((SharedUserSetting)obj).signatures.mSignatures;
2652                } else if (obj instanceof PackageSetting) {
2653                    s1 = ((PackageSetting)obj).signatures.mSignatures;
2654                } else {
2655                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2656                }
2657            } else {
2658                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2659            }
2660            obj = mSettings.getUserIdLPr(uid2);
2661            if (obj != null) {
2662                if (obj instanceof SharedUserSetting) {
2663                    s2 = ((SharedUserSetting)obj).signatures.mSignatures;
2664                } else if (obj instanceof PackageSetting) {
2665                    s2 = ((PackageSetting)obj).signatures.mSignatures;
2666                } else {
2667                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2668                }
2669            } else {
2670                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2671            }
2672            return compareSignatures(s1, s2);
2673        }
2674    }
2675
2676    /**
2677     * Compares two sets of signatures. Returns:
2678     * <br />
2679     * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
2680     * <br />
2681     * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
2682     * <br />
2683     * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
2684     * <br />
2685     * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
2686     * <br />
2687     * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
2688     */
2689    static int compareSignatures(Signature[] s1, Signature[] s2) {
2690        if (s1 == null) {
2691            return s2 == null
2692                    ? PackageManager.SIGNATURE_NEITHER_SIGNED
2693                    : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
2694        }
2695
2696        if (s2 == null) {
2697            return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
2698        }
2699
2700        if (s1.length != s2.length) {
2701            return PackageManager.SIGNATURE_NO_MATCH;
2702        }
2703
2704        // Since both signature sets are of size 1, we can compare without HashSets.
2705        if (s1.length == 1) {
2706            return s1[0].equals(s2[0]) ?
2707                    PackageManager.SIGNATURE_MATCH :
2708                    PackageManager.SIGNATURE_NO_MATCH;
2709        }
2710
2711        HashSet<Signature> set1 = new HashSet<Signature>();
2712        for (Signature sig : s1) {
2713            set1.add(sig);
2714        }
2715        HashSet<Signature> set2 = new HashSet<Signature>();
2716        for (Signature sig : s2) {
2717            set2.add(sig);
2718        }
2719        // Make sure s2 contains all signatures in s1.
2720        if (set1.equals(set2)) {
2721            return PackageManager.SIGNATURE_MATCH;
2722        }
2723        return PackageManager.SIGNATURE_NO_MATCH;
2724    }
2725
2726    /**
2727     * If the database version for this type of package (internal storage or
2728     * external storage) is less than the version where package signatures
2729     * were updated, return true.
2730     */
2731    private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
2732        return (isExternal(scannedPkg) && mSettings.isExternalDatabaseVersionOlderThan(
2733                DatabaseVersion.SIGNATURE_END_ENTITY))
2734                || (!isExternal(scannedPkg) && mSettings.isInternalDatabaseVersionOlderThan(
2735                        DatabaseVersion.SIGNATURE_END_ENTITY));
2736    }
2737
2738    /**
2739     * Used for backward compatibility to make sure any packages with
2740     * certificate chains get upgraded to the new style. {@code existingSigs}
2741     * will be in the old format (since they were stored on disk from before the
2742     * system upgrade) and {@code scannedSigs} will be in the newer format.
2743     */
2744    private int compareSignaturesCompat(PackageSignatures existingSigs,
2745            PackageParser.Package scannedPkg) {
2746        if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
2747            return PackageManager.SIGNATURE_NO_MATCH;
2748        }
2749
2750        HashSet<Signature> existingSet = new HashSet<Signature>();
2751        for (Signature sig : existingSigs.mSignatures) {
2752            existingSet.add(sig);
2753        }
2754        HashSet<Signature> scannedCompatSet = new HashSet<Signature>();
2755        for (Signature sig : scannedPkg.mSignatures) {
2756            try {
2757                Signature[] chainSignatures = sig.getChainSignatures();
2758                for (Signature chainSig : chainSignatures) {
2759                    scannedCompatSet.add(chainSig);
2760                }
2761            } catch (CertificateEncodingException e) {
2762                scannedCompatSet.add(sig);
2763            }
2764        }
2765        /*
2766         * Make sure the expanded scanned set contains all signatures in the
2767         * existing one.
2768         */
2769        if (scannedCompatSet.equals(existingSet)) {
2770            // Migrate the old signatures to the new scheme.
2771            existingSigs.assignSignatures(scannedPkg.mSignatures);
2772            // The new KeySets will be re-added later in the scanning process.
2773            mSettings.mKeySetManager.removeAppKeySetData(scannedPkg.packageName);
2774            return PackageManager.SIGNATURE_MATCH;
2775        }
2776        return PackageManager.SIGNATURE_NO_MATCH;
2777    }
2778
2779    public String[] getPackagesForUid(int uid) {
2780        uid = UserHandle.getAppId(uid);
2781        // reader
2782        synchronized (mPackages) {
2783            Object obj = mSettings.getUserIdLPr(uid);
2784            if (obj instanceof SharedUserSetting) {
2785                final SharedUserSetting sus = (SharedUserSetting) obj;
2786                final int N = sus.packages.size();
2787                final String[] res = new String[N];
2788                final Iterator<PackageSetting> it = sus.packages.iterator();
2789                int i = 0;
2790                while (it.hasNext()) {
2791                    res[i++] = it.next().name;
2792                }
2793                return res;
2794            } else if (obj instanceof PackageSetting) {
2795                final PackageSetting ps = (PackageSetting) obj;
2796                return new String[] { ps.name };
2797            }
2798        }
2799        return null;
2800    }
2801
2802    public String getNameForUid(int uid) {
2803        // reader
2804        synchronized (mPackages) {
2805            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2806            if (obj instanceof SharedUserSetting) {
2807                final SharedUserSetting sus = (SharedUserSetting) obj;
2808                return sus.name + ":" + sus.userId;
2809            } else if (obj instanceof PackageSetting) {
2810                final PackageSetting ps = (PackageSetting) obj;
2811                return ps.name;
2812            }
2813        }
2814        return null;
2815    }
2816
2817    public int getUidForSharedUser(String sharedUserName) {
2818        if(sharedUserName == null) {
2819            return -1;
2820        }
2821        // reader
2822        synchronized (mPackages) {
2823            final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, false);
2824            if (suid == null) {
2825                return -1;
2826            }
2827            return suid.userId;
2828        }
2829    }
2830
2831    public int getFlagsForUid(int uid) {
2832        synchronized (mPackages) {
2833            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2834            if (obj instanceof SharedUserSetting) {
2835                final SharedUserSetting sus = (SharedUserSetting) obj;
2836                return sus.pkgFlags;
2837            } else if (obj instanceof PackageSetting) {
2838                final PackageSetting ps = (PackageSetting) obj;
2839                return ps.pkgFlags;
2840            }
2841        }
2842        return 0;
2843    }
2844
2845    @Override
2846    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
2847            int flags, int userId) {
2848        if (!sUserManager.exists(userId)) return null;
2849        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "resolve intent");
2850        List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
2851        return chooseBestActivity(intent, resolvedType, flags, query, userId);
2852    }
2853
2854    @Override
2855    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
2856            IntentFilter filter, int match, ComponentName activity) {
2857        final int userId = UserHandle.getCallingUserId();
2858        if (DEBUG_PREFERRED) {
2859            Log.v(TAG, "setLastChosenActivity intent=" + intent
2860                + " resolvedType=" + resolvedType
2861                + " flags=" + flags
2862                + " filter=" + filter
2863                + " match=" + match
2864                + " activity=" + activity);
2865            filter.dump(new PrintStreamPrinter(System.out), "    ");
2866        }
2867        intent.setComponent(null);
2868        List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
2869        // Find any earlier preferred or last chosen entries and nuke them
2870        findPreferredActivity(intent, resolvedType,
2871                flags, query, 0, false, true, false, userId);
2872        // Add the new activity as the last chosen for this filter
2873        addPreferredActivityInternal(filter, match, null, activity, false, userId);
2874    }
2875
2876    @Override
2877    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
2878        final int userId = UserHandle.getCallingUserId();
2879        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
2880        List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
2881        return findPreferredActivity(intent, resolvedType, flags, query, 0,
2882                false, false, false, userId);
2883    }
2884
2885    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
2886            int flags, List<ResolveInfo> query, int userId) {
2887        if (query != null) {
2888            final int N = query.size();
2889            if (N == 1) {
2890                return query.get(0);
2891            } else if (N > 1) {
2892                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
2893                // If there is more than one activity with the same priority,
2894                // then let the user decide between them.
2895                ResolveInfo r0 = query.get(0);
2896                ResolveInfo r1 = query.get(1);
2897                if (DEBUG_INTENT_MATCHING || debug) {
2898                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
2899                            + r1.activityInfo.name + "=" + r1.priority);
2900                }
2901                // If the first activity has a higher priority, or a different
2902                // default, then it is always desireable to pick it.
2903                if (r0.priority != r1.priority
2904                        || r0.preferredOrder != r1.preferredOrder
2905                        || r0.isDefault != r1.isDefault) {
2906                    return query.get(0);
2907                }
2908                // If we have saved a preference for a preferred activity for
2909                // this Intent, use that.
2910                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
2911                        flags, query, r0.priority, true, false, debug, userId);
2912                if (ri != null) {
2913                    return ri;
2914                }
2915                if (userId != 0) {
2916                    ri = new ResolveInfo(mResolveInfo);
2917                    ri.activityInfo = new ActivityInfo(ri.activityInfo);
2918                    ri.activityInfo.applicationInfo = new ApplicationInfo(
2919                            ri.activityInfo.applicationInfo);
2920                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
2921                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
2922                    return ri;
2923                }
2924                return mResolveInfo;
2925            }
2926        }
2927        return null;
2928    }
2929
2930    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
2931            int flags, List<ResolveInfo> query, boolean debug, int userId) {
2932        final int N = query.size();
2933        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
2934                .get(userId);
2935        // Get the list of persistent preferred activities that handle the intent
2936        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
2937        List<PersistentPreferredActivity> pprefs = ppir != null
2938                ? ppir.queryIntent(intent, resolvedType,
2939                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
2940                : null;
2941        if (pprefs != null && pprefs.size() > 0) {
2942            final int M = pprefs.size();
2943            for (int i=0; i<M; i++) {
2944                final PersistentPreferredActivity ppa = pprefs.get(i);
2945                if (DEBUG_PREFERRED || debug) {
2946                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
2947                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
2948                            + "\n  component=" + ppa.mComponent);
2949                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
2950                }
2951                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
2952                        flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
2953                if (DEBUG_PREFERRED || debug) {
2954                    Slog.v(TAG, "Found persistent preferred activity:");
2955                    if (ai != null) {
2956                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
2957                    } else {
2958                        Slog.v(TAG, "  null");
2959                    }
2960                }
2961                if (ai == null) {
2962                    // This previously registered persistent preferred activity
2963                    // component is no longer known. Ignore it and do NOT remove it.
2964                    continue;
2965                }
2966                for (int j=0; j<N; j++) {
2967                    final ResolveInfo ri = query.get(j);
2968                    if (!ri.activityInfo.applicationInfo.packageName
2969                            .equals(ai.applicationInfo.packageName)) {
2970                        continue;
2971                    }
2972                    if (!ri.activityInfo.name.equals(ai.name)) {
2973                        continue;
2974                    }
2975                    //  Found a persistent preference that can handle the intent.
2976                    if (DEBUG_PREFERRED || debug) {
2977                        Slog.v(TAG, "Returning persistent preferred activity: " +
2978                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
2979                    }
2980                    return ri;
2981                }
2982            }
2983        }
2984        return null;
2985    }
2986
2987    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
2988            List<ResolveInfo> query, int priority, boolean always,
2989            boolean removeMatches, boolean debug, int userId) {
2990        if (!sUserManager.exists(userId)) return null;
2991        // writer
2992        synchronized (mPackages) {
2993            if (intent.getSelector() != null) {
2994                intent = intent.getSelector();
2995            }
2996            if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
2997
2998            // Try to find a matching persistent preferred activity.
2999            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
3000                    debug, userId);
3001
3002            // If a persistent preferred activity matched, use it.
3003            if (pri != null) {
3004                return pri;
3005            }
3006
3007            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
3008            // Get the list of preferred activities that handle the intent
3009            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
3010            List<PreferredActivity> prefs = pir != null
3011                    ? pir.queryIntent(intent, resolvedType,
3012                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
3013                    : null;
3014            if (prefs != null && prefs.size() > 0) {
3015                // First figure out how good the original match set is.
3016                // We will only allow preferred activities that came
3017                // from the same match quality.
3018                int match = 0;
3019
3020                if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
3021
3022                final int N = query.size();
3023                for (int j=0; j<N; j++) {
3024                    final ResolveInfo ri = query.get(j);
3025                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
3026                            + ": 0x" + Integer.toHexString(match));
3027                    if (ri.match > match) {
3028                        match = ri.match;
3029                    }
3030                }
3031
3032                if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
3033                        + Integer.toHexString(match));
3034
3035                match &= IntentFilter.MATCH_CATEGORY_MASK;
3036                final int M = prefs.size();
3037                for (int i=0; i<M; i++) {
3038                    final PreferredActivity pa = prefs.get(i);
3039                    if (DEBUG_PREFERRED || debug) {
3040                        Slog.v(TAG, "Checking PreferredActivity ds="
3041                                + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
3042                                + "\n  component=" + pa.mPref.mComponent);
3043                        pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
3044                    }
3045                    if (pa.mPref.mMatch != match) {
3046                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
3047                                + Integer.toHexString(pa.mPref.mMatch));
3048                        continue;
3049                    }
3050                    // If it's not an "always" type preferred activity and that's what we're
3051                    // looking for, skip it.
3052                    if (always && !pa.mPref.mAlways) {
3053                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
3054                        continue;
3055                    }
3056                    final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent,
3057                            flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
3058                    if (DEBUG_PREFERRED || debug) {
3059                        Slog.v(TAG, "Found preferred activity:");
3060                        if (ai != null) {
3061                            ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
3062                        } else {
3063                            Slog.v(TAG, "  null");
3064                        }
3065                    }
3066                    if (ai == null) {
3067                        // This previously registered preferred activity
3068                        // component is no longer known.  Most likely an update
3069                        // to the app was installed and in the new version this
3070                        // component no longer exists.  Clean it up by removing
3071                        // it from the preferred activities list, and skip it.
3072                        Slog.w(TAG, "Removing dangling preferred activity: "
3073                                + pa.mPref.mComponent);
3074                        pir.removeFilter(pa);
3075                        continue;
3076                    }
3077                    for (int j=0; j<N; j++) {
3078                        final ResolveInfo ri = query.get(j);
3079                        if (!ri.activityInfo.applicationInfo.packageName
3080                                .equals(ai.applicationInfo.packageName)) {
3081                            continue;
3082                        }
3083                        if (!ri.activityInfo.name.equals(ai.name)) {
3084                            continue;
3085                        }
3086
3087                        if (removeMatches) {
3088                            pir.removeFilter(pa);
3089                            if (DEBUG_PREFERRED) {
3090                                Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
3091                            }
3092                            break;
3093                        }
3094
3095                        // Okay we found a previously set preferred or last chosen app.
3096                        // If the result set is different from when this
3097                        // was created, we need to clear it and re-ask the
3098                        // user their preference, if we're looking for an "always" type entry.
3099                        if (always && !pa.mPref.sameSet(query, priority)) {
3100                            Slog.i(TAG, "Result set changed, dropping preferred activity for "
3101                                    + intent + " type " + resolvedType);
3102                            if (DEBUG_PREFERRED) {
3103                                Slog.v(TAG, "Removing preferred activity since set changed "
3104                                        + pa.mPref.mComponent);
3105                            }
3106                            pir.removeFilter(pa);
3107                            // Re-add the filter as a "last chosen" entry (!always)
3108                            PreferredActivity lastChosen = new PreferredActivity(
3109                                    pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
3110                            pir.addFilter(lastChosen);
3111                            mSettings.writePackageRestrictionsLPr(userId);
3112                            return null;
3113                        }
3114
3115                        // Yay! Either the set matched or we're looking for the last chosen
3116                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
3117                                + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
3118                        mSettings.writePackageRestrictionsLPr(userId);
3119                        return ri;
3120                    }
3121                }
3122            }
3123            mSettings.writePackageRestrictionsLPr(userId);
3124        }
3125        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
3126        return null;
3127    }
3128
3129    /*
3130     * Returns if intent can be forwarded from the userId from to dest
3131     */
3132    @Override
3133    public boolean canForwardTo(Intent intent, String resolvedType, int userIdFrom, int userIdDest) {
3134        mContext.enforceCallingOrSelfPermission(
3135                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
3136        List<ForwardingIntentFilter> matches =
3137                getMatchingForwardingIntentFilters(intent, resolvedType, userIdFrom);
3138        if (matches != null) {
3139            int size = matches.size();
3140            for (int i = 0; i < size; i++) {
3141                if (matches.get(i).getUserIdDest() == userIdDest) return true;
3142            }
3143        }
3144        return false;
3145    }
3146
3147    private List<ForwardingIntentFilter> getMatchingForwardingIntentFilters(Intent intent,
3148            String resolvedType, int userId) {
3149        ForwardingIntentResolver fir = mSettings.mForwardingIntentResolvers.get(userId);
3150        if (fir != null) {
3151            return fir.queryIntent(intent, resolvedType, false, userId);
3152        }
3153        return null;
3154    }
3155
3156    @Override
3157    public List<ResolveInfo> queryIntentActivities(Intent intent,
3158            String resolvedType, int flags, int userId) {
3159        if (!sUserManager.exists(userId)) return Collections.emptyList();
3160        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "query intent activities");
3161        ComponentName comp = intent.getComponent();
3162        if (comp == null) {
3163            if (intent.getSelector() != null) {
3164                intent = intent.getSelector();
3165                comp = intent.getComponent();
3166            }
3167        }
3168
3169        if (comp != null) {
3170            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3171            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
3172            if (ai != null) {
3173                final ResolveInfo ri = new ResolveInfo();
3174                ri.activityInfo = ai;
3175                list.add(ri);
3176            }
3177            return list;
3178        }
3179
3180        // reader
3181        synchronized (mPackages) {
3182            final String pkgName = intent.getPackage();
3183            if (pkgName == null) {
3184                List<ResolveInfo> result =
3185                        mActivities.queryIntent(intent, resolvedType, flags, userId);
3186                // Checking if we can forward the intent to another user
3187                List<ForwardingIntentFilter> fifs =
3188                        getMatchingForwardingIntentFilters(intent, resolvedType, userId);
3189                if (fifs != null) {
3190                    ForwardingIntentFilter forwardingIntentFilterWithResult = null;
3191                    HashSet<Integer> alreadyTriedUserIds = new HashSet<Integer>();
3192                    for (ForwardingIntentFilter fif : fifs) {
3193                        int userIdDest = fif.getUserIdDest();
3194                        // Two {@link ForwardingIntentFilter}s can have the same userIdDest and
3195                        // match the same an intent. For performance reasons, it is better not to
3196                        // run queryIntent twice for the same userId
3197                        if (!alreadyTriedUserIds.contains(userIdDest)) {
3198                            List<ResolveInfo> resultUser = mActivities.queryIntent(intent,
3199                                    resolvedType, flags, userIdDest);
3200                            if (resultUser != null) {
3201                                forwardingIntentFilterWithResult = fif;
3202                                // As soon as there is a match in another user, we add the
3203                                // intentForwarderActivity to the list of ResolveInfo.
3204                                break;
3205                            }
3206                            alreadyTriedUserIds.add(userIdDest);
3207                        }
3208                    }
3209                    if (forwardingIntentFilterWithResult != null) {
3210                        ResolveInfo forwardingResolveInfo = createForwardingResolveInfo(
3211                                forwardingIntentFilterWithResult, userId);
3212                        result.add(forwardingResolveInfo);
3213                    }
3214                }
3215                return result;
3216            }
3217            final PackageParser.Package pkg = mPackages.get(pkgName);
3218            if (pkg != null) {
3219                return mActivities.queryIntentForPackage(intent, resolvedType, flags,
3220                        pkg.activities, userId);
3221            }
3222            return new ArrayList<ResolveInfo>();
3223        }
3224    }
3225
3226    private ResolveInfo createForwardingResolveInfo(ForwardingIntentFilter fif, int userIdFrom) {
3227        String className;
3228        int userIdDest = fif.getUserIdDest();
3229        if (userIdDest == UserHandle.USER_OWNER) {
3230            className = FORWARD_INTENT_TO_USER_OWNER;
3231        } else {
3232            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
3233        }
3234        ComponentName forwardingActivityComponentName = new ComponentName(
3235                mAndroidApplication.packageName, className);
3236        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
3237                userIdFrom);
3238        ResolveInfo forwardingResolveInfo = new ResolveInfo();
3239        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
3240        forwardingResolveInfo.priority = 0;
3241        forwardingResolveInfo.preferredOrder = 0;
3242        forwardingResolveInfo.match = 0;
3243        forwardingResolveInfo.isDefault = true;
3244        forwardingResolveInfo.filter = fif;
3245        return forwardingResolveInfo;
3246    }
3247
3248    @Override
3249    public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
3250            Intent[] specifics, String[] specificTypes, Intent intent,
3251            String resolvedType, int flags, int userId) {
3252        if (!sUserManager.exists(userId)) return Collections.emptyList();
3253        enforceCrossUserPermission(Binder.getCallingUid(), userId, false,
3254                "query intent activity options");
3255        final String resultsAction = intent.getAction();
3256
3257        List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags
3258                | PackageManager.GET_RESOLVED_FILTER, userId);
3259
3260        if (DEBUG_INTENT_MATCHING) {
3261            Log.v(TAG, "Query " + intent + ": " + results);
3262        }
3263
3264        int specificsPos = 0;
3265        int N;
3266
3267        // todo: note that the algorithm used here is O(N^2).  This
3268        // isn't a problem in our current environment, but if we start running
3269        // into situations where we have more than 5 or 10 matches then this
3270        // should probably be changed to something smarter...
3271
3272        // First we go through and resolve each of the specific items
3273        // that were supplied, taking care of removing any corresponding
3274        // duplicate items in the generic resolve list.
3275        if (specifics != null) {
3276            for (int i=0; i<specifics.length; i++) {
3277                final Intent sintent = specifics[i];
3278                if (sintent == null) {
3279                    continue;
3280                }
3281
3282                if (DEBUG_INTENT_MATCHING) {
3283                    Log.v(TAG, "Specific #" + i + ": " + sintent);
3284                }
3285
3286                String action = sintent.getAction();
3287                if (resultsAction != null && resultsAction.equals(action)) {
3288                    // If this action was explicitly requested, then don't
3289                    // remove things that have it.
3290                    action = null;
3291                }
3292
3293                ResolveInfo ri = null;
3294                ActivityInfo ai = null;
3295
3296                ComponentName comp = sintent.getComponent();
3297                if (comp == null) {
3298                    ri = resolveIntent(
3299                        sintent,
3300                        specificTypes != null ? specificTypes[i] : null,
3301                            flags, userId);
3302                    if (ri == null) {
3303                        continue;
3304                    }
3305                    if (ri == mResolveInfo) {
3306                        // ACK!  Must do something better with this.
3307                    }
3308                    ai = ri.activityInfo;
3309                    comp = new ComponentName(ai.applicationInfo.packageName,
3310                            ai.name);
3311                } else {
3312                    ai = getActivityInfo(comp, flags, userId);
3313                    if (ai == null) {
3314                        continue;
3315                    }
3316                }
3317
3318                // Look for any generic query activities that are duplicates
3319                // of this specific one, and remove them from the results.
3320                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
3321                N = results.size();
3322                int j;
3323                for (j=specificsPos; j<N; j++) {
3324                    ResolveInfo sri = results.get(j);
3325                    if ((sri.activityInfo.name.equals(comp.getClassName())
3326                            && sri.activityInfo.applicationInfo.packageName.equals(
3327                                    comp.getPackageName()))
3328                        || (action != null && sri.filter.matchAction(action))) {
3329                        results.remove(j);
3330                        if (DEBUG_INTENT_MATCHING) Log.v(
3331                            TAG, "Removing duplicate item from " + j
3332                            + " due to specific " + specificsPos);
3333                        if (ri == null) {
3334                            ri = sri;
3335                        }
3336                        j--;
3337                        N--;
3338                    }
3339                }
3340
3341                // Add this specific item to its proper place.
3342                if (ri == null) {
3343                    ri = new ResolveInfo();
3344                    ri.activityInfo = ai;
3345                }
3346                results.add(specificsPos, ri);
3347                ri.specificIndex = i;
3348                specificsPos++;
3349            }
3350        }
3351
3352        // Now we go through the remaining generic results and remove any
3353        // duplicate actions that are found here.
3354        N = results.size();
3355        for (int i=specificsPos; i<N-1; i++) {
3356            final ResolveInfo rii = results.get(i);
3357            if (rii.filter == null) {
3358                continue;
3359            }
3360
3361            // Iterate over all of the actions of this result's intent
3362            // filter...  typically this should be just one.
3363            final Iterator<String> it = rii.filter.actionsIterator();
3364            if (it == null) {
3365                continue;
3366            }
3367            while (it.hasNext()) {
3368                final String action = it.next();
3369                if (resultsAction != null && resultsAction.equals(action)) {
3370                    // If this action was explicitly requested, then don't
3371                    // remove things that have it.
3372                    continue;
3373                }
3374                for (int j=i+1; j<N; j++) {
3375                    final ResolveInfo rij = results.get(j);
3376                    if (rij.filter != null && rij.filter.hasAction(action)) {
3377                        results.remove(j);
3378                        if (DEBUG_INTENT_MATCHING) Log.v(
3379                            TAG, "Removing duplicate item from " + j
3380                            + " due to action " + action + " at " + i);
3381                        j--;
3382                        N--;
3383                    }
3384                }
3385            }
3386
3387            // If the caller didn't request filter information, drop it now
3388            // so we don't have to marshall/unmarshall it.
3389            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
3390                rii.filter = null;
3391            }
3392        }
3393
3394        // Filter out the caller activity if so requested.
3395        if (caller != null) {
3396            N = results.size();
3397            for (int i=0; i<N; i++) {
3398                ActivityInfo ainfo = results.get(i).activityInfo;
3399                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
3400                        && caller.getClassName().equals(ainfo.name)) {
3401                    results.remove(i);
3402                    break;
3403                }
3404            }
3405        }
3406
3407        // If the caller didn't request filter information,
3408        // drop them now so we don't have to
3409        // marshall/unmarshall it.
3410        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
3411            N = results.size();
3412            for (int i=0; i<N; i++) {
3413                results.get(i).filter = null;
3414            }
3415        }
3416
3417        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
3418        return results;
3419    }
3420
3421    @Override
3422    public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags,
3423            int userId) {
3424        if (!sUserManager.exists(userId)) return Collections.emptyList();
3425        ComponentName comp = intent.getComponent();
3426        if (comp == null) {
3427            if (intent.getSelector() != null) {
3428                intent = intent.getSelector();
3429                comp = intent.getComponent();
3430            }
3431        }
3432        if (comp != null) {
3433            List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3434            ActivityInfo ai = getReceiverInfo(comp, flags, userId);
3435            if (ai != null) {
3436                ResolveInfo ri = new ResolveInfo();
3437                ri.activityInfo = ai;
3438                list.add(ri);
3439            }
3440            return list;
3441        }
3442
3443        // reader
3444        synchronized (mPackages) {
3445            String pkgName = intent.getPackage();
3446            if (pkgName == null) {
3447                return mReceivers.queryIntent(intent, resolvedType, flags, userId);
3448            }
3449            final PackageParser.Package pkg = mPackages.get(pkgName);
3450            if (pkg != null) {
3451                return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
3452                        userId);
3453            }
3454            return null;
3455        }
3456    }
3457
3458    @Override
3459    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
3460        List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId);
3461        if (!sUserManager.exists(userId)) return null;
3462        if (query != null) {
3463            if (query.size() >= 1) {
3464                // If there is more than one service with the same priority,
3465                // just arbitrarily pick the first one.
3466                return query.get(0);
3467            }
3468        }
3469        return null;
3470    }
3471
3472    @Override
3473    public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags,
3474            int userId) {
3475        if (!sUserManager.exists(userId)) return Collections.emptyList();
3476        ComponentName comp = intent.getComponent();
3477        if (comp == null) {
3478            if (intent.getSelector() != null) {
3479                intent = intent.getSelector();
3480                comp = intent.getComponent();
3481            }
3482        }
3483        if (comp != null) {
3484            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3485            final ServiceInfo si = getServiceInfo(comp, flags, userId);
3486            if (si != null) {
3487                final ResolveInfo ri = new ResolveInfo();
3488                ri.serviceInfo = si;
3489                list.add(ri);
3490            }
3491            return list;
3492        }
3493
3494        // reader
3495        synchronized (mPackages) {
3496            String pkgName = intent.getPackage();
3497            if (pkgName == null) {
3498                return mServices.queryIntent(intent, resolvedType, flags, userId);
3499            }
3500            final PackageParser.Package pkg = mPackages.get(pkgName);
3501            if (pkg != null) {
3502                return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
3503                        userId);
3504            }
3505            return null;
3506        }
3507    }
3508
3509    @Override
3510    public List<ResolveInfo> queryIntentContentProviders(
3511            Intent intent, String resolvedType, int flags, int userId) {
3512        if (!sUserManager.exists(userId)) return Collections.emptyList();
3513        ComponentName comp = intent.getComponent();
3514        if (comp == null) {
3515            if (intent.getSelector() != null) {
3516                intent = intent.getSelector();
3517                comp = intent.getComponent();
3518            }
3519        }
3520        if (comp != null) {
3521            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3522            final ProviderInfo pi = getProviderInfo(comp, flags, userId);
3523            if (pi != null) {
3524                final ResolveInfo ri = new ResolveInfo();
3525                ri.providerInfo = pi;
3526                list.add(ri);
3527            }
3528            return list;
3529        }
3530
3531        // reader
3532        synchronized (mPackages) {
3533            String pkgName = intent.getPackage();
3534            if (pkgName == null) {
3535                return mProviders.queryIntent(intent, resolvedType, flags, userId);
3536            }
3537            final PackageParser.Package pkg = mPackages.get(pkgName);
3538            if (pkg != null) {
3539                return mProviders.queryIntentForPackage(
3540                        intent, resolvedType, flags, pkg.providers, userId);
3541            }
3542            return null;
3543        }
3544    }
3545
3546    @Override
3547    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
3548        final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
3549
3550        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "get installed packages");
3551
3552        // writer
3553        synchronized (mPackages) {
3554            ArrayList<PackageInfo> list;
3555            if (listUninstalled) {
3556                list = new ArrayList<PackageInfo>(mSettings.mPackages.size());
3557                for (PackageSetting ps : mSettings.mPackages.values()) {
3558                    PackageInfo pi;
3559                    if (ps.pkg != null) {
3560                        pi = generatePackageInfo(ps.pkg, flags, userId);
3561                    } else {
3562                        pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
3563                    }
3564                    if (pi != null) {
3565                        list.add(pi);
3566                    }
3567                }
3568            } else {
3569                list = new ArrayList<PackageInfo>(mPackages.size());
3570                for (PackageParser.Package p : mPackages.values()) {
3571                    PackageInfo pi = generatePackageInfo(p, flags, userId);
3572                    if (pi != null) {
3573                        list.add(pi);
3574                    }
3575                }
3576            }
3577
3578            return new ParceledListSlice<PackageInfo>(list);
3579        }
3580    }
3581
3582    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
3583            String[] permissions, boolean[] tmp, int flags, int userId) {
3584        int numMatch = 0;
3585        final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
3586        for (int i=0; i<permissions.length; i++) {
3587            if (gp.grantedPermissions.contains(permissions[i])) {
3588                tmp[i] = true;
3589                numMatch++;
3590            } else {
3591                tmp[i] = false;
3592            }
3593        }
3594        if (numMatch == 0) {
3595            return;
3596        }
3597        PackageInfo pi;
3598        if (ps.pkg != null) {
3599            pi = generatePackageInfo(ps.pkg, flags, userId);
3600        } else {
3601            pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
3602        }
3603        if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
3604            if (numMatch == permissions.length) {
3605                pi.requestedPermissions = permissions;
3606            } else {
3607                pi.requestedPermissions = new String[numMatch];
3608                numMatch = 0;
3609                for (int i=0; i<permissions.length; i++) {
3610                    if (tmp[i]) {
3611                        pi.requestedPermissions[numMatch] = permissions[i];
3612                        numMatch++;
3613                    }
3614                }
3615            }
3616        }
3617        list.add(pi);
3618    }
3619
3620    @Override
3621    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
3622            String[] permissions, int flags, int userId) {
3623        if (!sUserManager.exists(userId)) return null;
3624        final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
3625
3626        // writer
3627        synchronized (mPackages) {
3628            ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
3629            boolean[] tmpBools = new boolean[permissions.length];
3630            if (listUninstalled) {
3631                for (PackageSetting ps : mSettings.mPackages.values()) {
3632                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId);
3633                }
3634            } else {
3635                for (PackageParser.Package pkg : mPackages.values()) {
3636                    PackageSetting ps = (PackageSetting)pkg.mExtras;
3637                    if (ps != null) {
3638                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
3639                                userId);
3640                    }
3641                }
3642            }
3643
3644            return new ParceledListSlice<PackageInfo>(list);
3645        }
3646    }
3647
3648    @Override
3649    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
3650        if (!sUserManager.exists(userId)) return null;
3651        final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
3652
3653        // writer
3654        synchronized (mPackages) {
3655            ArrayList<ApplicationInfo> list;
3656            if (listUninstalled) {
3657                list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size());
3658                for (PackageSetting ps : mSettings.mPackages.values()) {
3659                    ApplicationInfo ai;
3660                    if (ps.pkg != null) {
3661                        ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
3662                                ps.readUserState(userId), userId);
3663                    } else {
3664                        ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
3665                    }
3666                    if (ai != null) {
3667                        list.add(ai);
3668                    }
3669                }
3670            } else {
3671                list = new ArrayList<ApplicationInfo>(mPackages.size());
3672                for (PackageParser.Package p : mPackages.values()) {
3673                    if (p.mExtras != null) {
3674                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
3675                                ((PackageSetting)p.mExtras).readUserState(userId), userId);
3676                        if (ai != null) {
3677                            list.add(ai);
3678                        }
3679                    }
3680                }
3681            }
3682
3683            return new ParceledListSlice<ApplicationInfo>(list);
3684        }
3685    }
3686
3687    public List<ApplicationInfo> getPersistentApplications(int flags) {
3688        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
3689
3690        // reader
3691        synchronized (mPackages) {
3692            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
3693            final int userId = UserHandle.getCallingUserId();
3694            while (i.hasNext()) {
3695                final PackageParser.Package p = i.next();
3696                if (p.applicationInfo != null
3697                        && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0
3698                        && (!mSafeMode || isSystemApp(p))) {
3699                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
3700                    if (ps != null) {
3701                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
3702                                ps.readUserState(userId), userId);
3703                        if (ai != null) {
3704                            finalList.add(ai);
3705                        }
3706                    }
3707                }
3708            }
3709        }
3710
3711        return finalList;
3712    }
3713
3714    @Override
3715    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
3716        if (!sUserManager.exists(userId)) return null;
3717        // reader
3718        synchronized (mPackages) {
3719            final PackageParser.Provider provider = mProvidersByAuthority.get(name);
3720            PackageSetting ps = provider != null
3721                    ? mSettings.mPackages.get(provider.owner.packageName)
3722                    : null;
3723            return ps != null
3724                    && mSettings.isEnabledLPr(provider.info, flags, userId)
3725                    && (!mSafeMode || (provider.info.applicationInfo.flags
3726                            &ApplicationInfo.FLAG_SYSTEM) != 0)
3727                    ? PackageParser.generateProviderInfo(provider, flags,
3728                            ps.readUserState(userId), userId)
3729                    : null;
3730        }
3731    }
3732
3733    /**
3734     * @deprecated
3735     */
3736    @Deprecated
3737    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
3738        // reader
3739        synchronized (mPackages) {
3740            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
3741                    .entrySet().iterator();
3742            final int userId = UserHandle.getCallingUserId();
3743            while (i.hasNext()) {
3744                Map.Entry<String, PackageParser.Provider> entry = i.next();
3745                PackageParser.Provider p = entry.getValue();
3746                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
3747
3748                if (ps != null && p.syncable
3749                        && (!mSafeMode || (p.info.applicationInfo.flags
3750                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
3751                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
3752                            ps.readUserState(userId), userId);
3753                    if (info != null) {
3754                        outNames.add(entry.getKey());
3755                        outInfo.add(info);
3756                    }
3757                }
3758            }
3759        }
3760    }
3761
3762    public List<ProviderInfo> queryContentProviders(String processName,
3763            int uid, int flags) {
3764        ArrayList<ProviderInfo> finalList = null;
3765        // reader
3766        synchronized (mPackages) {
3767            final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
3768            final int userId = processName != null ?
3769                    UserHandle.getUserId(uid) : UserHandle.getCallingUserId();
3770            while (i.hasNext()) {
3771                final PackageParser.Provider p = i.next();
3772                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
3773                if (ps != null && p.info.authority != null
3774                        && (processName == null
3775                                || (p.info.processName.equals(processName)
3776                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
3777                        && mSettings.isEnabledLPr(p.info, flags, userId)
3778                        && (!mSafeMode
3779                                || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
3780                    if (finalList == null) {
3781                        finalList = new ArrayList<ProviderInfo>(3);
3782                    }
3783                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
3784                            ps.readUserState(userId), userId);
3785                    if (info != null) {
3786                        finalList.add(info);
3787                    }
3788                }
3789            }
3790        }
3791
3792        if (finalList != null) {
3793            Collections.sort(finalList, mProviderInitOrderSorter);
3794        }
3795
3796        return finalList;
3797    }
3798
3799    public InstrumentationInfo getInstrumentationInfo(ComponentName name,
3800            int flags) {
3801        // reader
3802        synchronized (mPackages) {
3803            final PackageParser.Instrumentation i = mInstrumentation.get(name);
3804            return PackageParser.generateInstrumentationInfo(i, flags);
3805        }
3806    }
3807
3808    public List<InstrumentationInfo> queryInstrumentation(String targetPackage,
3809            int flags) {
3810        ArrayList<InstrumentationInfo> finalList =
3811            new ArrayList<InstrumentationInfo>();
3812
3813        // reader
3814        synchronized (mPackages) {
3815            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
3816            while (i.hasNext()) {
3817                final PackageParser.Instrumentation p = i.next();
3818                if (targetPackage == null
3819                        || targetPackage.equals(p.info.targetPackage)) {
3820                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
3821                            flags);
3822                    if (ii != null) {
3823                        finalList.add(ii);
3824                    }
3825                }
3826            }
3827        }
3828
3829        return finalList;
3830    }
3831
3832    private void createIdmapsForPackageLI(PackageParser.Package pkg) {
3833        HashMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName);
3834        if (overlays == null) {
3835            Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages");
3836            return;
3837        }
3838        for (PackageParser.Package opkg : overlays.values()) {
3839            // Not much to do if idmap fails: we already logged the error
3840            // and we certainly don't want to abort installation of pkg simply
3841            // because an overlay didn't fit properly. For these reasons,
3842            // ignore the return value of createIdmapForPackagePairLI.
3843            createIdmapForPackagePairLI(pkg, opkg);
3844        }
3845    }
3846
3847    private boolean createIdmapForPackagePairLI(PackageParser.Package pkg,
3848            PackageParser.Package opkg) {
3849        if (!opkg.mTrustedOverlay) {
3850            Slog.w(TAG, "Skipping target and overlay pair " + pkg.mScanPath + " and " +
3851                    opkg.mScanPath + ": overlay not trusted");
3852            return false;
3853        }
3854        HashMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName);
3855        if (overlaySet == null) {
3856            Slog.e(TAG, "was about to create idmap for " + pkg.mScanPath + " and " +
3857                    opkg.mScanPath + " but target package has no known overlays");
3858            return false;
3859        }
3860        final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
3861        if (mInstaller.idmap(pkg.mScanPath, opkg.mScanPath, sharedGid) != 0) {
3862            Slog.e(TAG, "Failed to generate idmap for " + pkg.mScanPath + " and " + opkg.mScanPath);
3863            return false;
3864        }
3865        PackageParser.Package[] overlayArray =
3866            overlaySet.values().toArray(new PackageParser.Package[0]);
3867        Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
3868            public int compare(PackageParser.Package p1, PackageParser.Package p2) {
3869                return p1.mOverlayPriority - p2.mOverlayPriority;
3870            }
3871        };
3872        Arrays.sort(overlayArray, cmp);
3873
3874        pkg.applicationInfo.resourceDirs = new String[overlayArray.length];
3875        int i = 0;
3876        for (PackageParser.Package p : overlayArray) {
3877            pkg.applicationInfo.resourceDirs[i++] = p.applicationInfo.sourceDir;
3878        }
3879        return true;
3880    }
3881
3882    private void scanDirLI(File dir, int flags, int scanMode, long currentTime) {
3883        String[] files = dir.list();
3884        if (files == null) {
3885            Log.d(TAG, "No files in app dir " + dir);
3886            return;
3887        }
3888
3889        if (DEBUG_PACKAGE_SCANNING) {
3890            Log.d(TAG, "Scanning app dir " + dir + " scanMode=" + scanMode
3891                    + " flags=0x" + Integer.toHexString(flags));
3892        }
3893
3894        int i;
3895        for (i=0; i<files.length; i++) {
3896            File file = new File(dir, files[i]);
3897            if (!isPackageFilename(files[i])) {
3898                // Ignore entries which are not apk's
3899                continue;
3900            }
3901            PackageParser.Package pkg = scanPackageLI(file,
3902                    flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime, null);
3903            // Don't mess around with apps in system partition.
3904            if (pkg == null && (flags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
3905                    mLastScanError == PackageManager.INSTALL_FAILED_INVALID_APK) {
3906                // Delete the apk
3907                Slog.w(TAG, "Cleaning up failed install of " + file);
3908                file.delete();
3909            }
3910        }
3911    }
3912
3913    private static File getSettingsProblemFile() {
3914        File dataDir = Environment.getDataDirectory();
3915        File systemDir = new File(dataDir, "system");
3916        File fname = new File(systemDir, "uiderrors.txt");
3917        return fname;
3918    }
3919
3920    static void reportSettingsProblem(int priority, String msg) {
3921        try {
3922            File fname = getSettingsProblemFile();
3923            FileOutputStream out = new FileOutputStream(fname, true);
3924            PrintWriter pw = new FastPrintWriter(out);
3925            SimpleDateFormat formatter = new SimpleDateFormat();
3926            String dateString = formatter.format(new Date(System.currentTimeMillis()));
3927            pw.println(dateString + ": " + msg);
3928            pw.close();
3929            FileUtils.setPermissions(
3930                    fname.toString(),
3931                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
3932                    -1, -1);
3933        } catch (java.io.IOException e) {
3934        }
3935        Slog.println(priority, TAG, msg);
3936    }
3937
3938    private boolean collectCertificatesLI(PackageParser pp, PackageSetting ps,
3939            PackageParser.Package pkg, File srcFile, int parseFlags) {
3940        if (ps != null
3941                && ps.codePath.equals(srcFile)
3942                && ps.timeStamp == srcFile.lastModified()
3943                && !isCompatSignatureUpdateNeeded(pkg)) {
3944            if (ps.signatures.mSignatures != null
3945                    && ps.signatures.mSignatures.length != 0) {
3946                // Optimization: reuse the existing cached certificates
3947                // if the package appears to be unchanged.
3948                pkg.mSignatures = ps.signatures.mSignatures;
3949                return true;
3950            }
3951
3952            Slog.w(TAG, "PackageSetting for " + ps.name + " is missing signatures.  Collecting certs again to recover them.");
3953        } else {
3954            Log.i(TAG, srcFile.toString() + " changed; collecting certs");
3955        }
3956
3957        if (!pp.collectCertificates(pkg, parseFlags)) {
3958            mLastScanError = pp.getParseError();
3959            return false;
3960        }
3961        return true;
3962    }
3963
3964    /*
3965     *  Scan a package and return the newly parsed package.
3966     *  Returns null in case of errors and the error code is stored in mLastScanError
3967     */
3968    private PackageParser.Package scanPackageLI(File scanFile,
3969            int parseFlags, int scanMode, long currentTime, UserHandle user) {
3970        mLastScanError = PackageManager.INSTALL_SUCCEEDED;
3971        String scanPath = scanFile.getPath();
3972        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanPath);
3973        parseFlags |= mDefParseFlags;
3974        PackageParser pp = new PackageParser(scanPath);
3975        pp.setSeparateProcesses(mSeparateProcesses);
3976        pp.setOnlyCoreApps(mOnlyCore);
3977        final PackageParser.Package pkg = pp.parsePackage(scanFile,
3978                scanPath, mMetrics, parseFlags, (scanMode & SCAN_TRUSTED_OVERLAY) != 0);
3979
3980        if (pkg == null) {
3981            mLastScanError = pp.getParseError();
3982            return null;
3983        }
3984
3985        PackageSetting ps = null;
3986        PackageSetting updatedPkg;
3987        // reader
3988        synchronized (mPackages) {
3989            // Look to see if we already know about this package.
3990            String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
3991            if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
3992                // This package has been renamed to its original name.  Let's
3993                // use that.
3994                ps = mSettings.peekPackageLPr(oldName);
3995            }
3996            // If there was no original package, see one for the real package name.
3997            if (ps == null) {
3998                ps = mSettings.peekPackageLPr(pkg.packageName);
3999            }
4000            // Check to see if this package could be hiding/updating a system
4001            // package.  Must look for it either under the original or real
4002            // package name depending on our state.
4003            updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
4004            if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
4005        }
4006        boolean updatedPkgBetter = false;
4007        // First check if this is a system package that may involve an update
4008        if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
4009            if (ps != null && !ps.codePath.equals(scanFile)) {
4010                // The path has changed from what was last scanned...  check the
4011                // version of the new path against what we have stored to determine
4012                // what to do.
4013                if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
4014                if (pkg.mVersionCode < ps.versionCode) {
4015                    // The system package has been updated and the code path does not match
4016                    // Ignore entry. Skip it.
4017                    Log.i(TAG, "Package " + ps.name + " at " + scanFile
4018                            + " ignored: updated version " + ps.versionCode
4019                            + " better than this " + pkg.mVersionCode);
4020                    if (!updatedPkg.codePath.equals(scanFile)) {
4021                        Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg : "
4022                                + ps.name + " changing from " + updatedPkg.codePathString
4023                                + " to " + scanFile);
4024                        updatedPkg.codePath = scanFile;
4025                        updatedPkg.codePathString = scanFile.toString();
4026                        // This is the point at which we know that the system-disk APK
4027                        // for this package has moved during a reboot (e.g. due to an OTA),
4028                        // so we need to reevaluate it for privilege policy.
4029                        if (locationIsPrivileged(scanFile)) {
4030                            updatedPkg.pkgFlags |= ApplicationInfo.FLAG_PRIVILEGED;
4031                        }
4032                    }
4033                    updatedPkg.pkg = pkg;
4034                    mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
4035                    return null;
4036                } else {
4037                    // The current app on the system partion is better than
4038                    // what we have updated to on the data partition; switch
4039                    // back to the system partition version.
4040                    // At this point, its safely assumed that package installation for
4041                    // apps in system partition will go through. If not there won't be a working
4042                    // version of the app
4043                    // writer
4044                    synchronized (mPackages) {
4045                        // Just remove the loaded entries from package lists.
4046                        mPackages.remove(ps.name);
4047                    }
4048                    Slog.w(TAG, "Package " + ps.name + " at " + scanFile
4049                            + "reverting from " + ps.codePathString
4050                            + ": new version " + pkg.mVersionCode
4051                            + " better than installed " + ps.versionCode);
4052
4053                    InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps),
4054                            ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString);
4055                    synchronized (mInstallLock) {
4056                        args.cleanUpResourcesLI();
4057                    }
4058                    synchronized (mPackages) {
4059                        mSettings.enableSystemPackageLPw(ps.name);
4060                    }
4061                    updatedPkgBetter = true;
4062                }
4063            }
4064        }
4065
4066        if (updatedPkg != null) {
4067            // An updated system app will not have the PARSE_IS_SYSTEM flag set
4068            // initially
4069            parseFlags |= PackageParser.PARSE_IS_SYSTEM;
4070
4071            // An updated privileged app will not have the PARSE_IS_PRIVILEGED
4072            // flag set initially
4073            if ((updatedPkg.pkgFlags & ApplicationInfo.FLAG_PRIVILEGED) != 0) {
4074                parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
4075            }
4076        }
4077        // Verify certificates against what was last scanned
4078        if (!collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags)) {
4079            Slog.w(TAG, "Failed verifying certificates for package:" + pkg.packageName);
4080            return null;
4081        }
4082
4083        /*
4084         * A new system app appeared, but we already had a non-system one of the
4085         * same name installed earlier.
4086         */
4087        boolean shouldHideSystemApp = false;
4088        if (updatedPkg == null && ps != null
4089                && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
4090            /*
4091             * Check to make sure the signatures match first. If they don't,
4092             * wipe the installed application and its data.
4093             */
4094            if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
4095                    != PackageManager.SIGNATURE_MATCH) {
4096                if (DEBUG_INSTALL) Slog.d(TAG, "Signature mismatch!");
4097                deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false);
4098                ps = null;
4099            } else {
4100                /*
4101                 * If the newly-added system app is an older version than the
4102                 * already installed version, hide it. It will be scanned later
4103                 * and re-added like an update.
4104                 */
4105                if (pkg.mVersionCode < ps.versionCode) {
4106                    shouldHideSystemApp = true;
4107                } else {
4108                    /*
4109                     * The newly found system app is a newer version that the
4110                     * one previously installed. Simply remove the
4111                     * already-installed application and replace it with our own
4112                     * while keeping the application data.
4113                     */
4114                    Slog.w(TAG, "Package " + ps.name + " at " + scanFile + "reverting from "
4115                            + ps.codePathString + ": new version " + pkg.mVersionCode
4116                            + " better than installed " + ps.versionCode);
4117                    InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps),
4118                            ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString);
4119                    synchronized (mInstallLock) {
4120                        args.cleanUpResourcesLI();
4121                    }
4122                }
4123            }
4124        }
4125
4126        // The apk is forward locked (not public) if its code and resources
4127        // are kept in different files. (except for app in either system or
4128        // vendor path).
4129        // TODO grab this value from PackageSettings
4130        if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
4131            if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
4132                parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
4133            }
4134        }
4135
4136        String codePath = null;
4137        String resPath = null;
4138        if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
4139            if (ps != null && ps.resourcePathString != null) {
4140                resPath = ps.resourcePathString;
4141            } else {
4142                // Should not happen at all. Just log an error.
4143                Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName);
4144            }
4145        } else {
4146            resPath = pkg.mScanPath;
4147        }
4148
4149        codePath = pkg.mScanPath;
4150        // Set application objects path explicitly.
4151        setApplicationInfoPaths(pkg, codePath, resPath);
4152        // Applications can run with the primary Cpu Abi unless otherwise is specified
4153        pkg.applicationInfo.requiredCpuAbi = null;
4154        // Note that we invoke the following method only if we are about to unpack an application
4155        PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanMode
4156                | SCAN_UPDATE_SIGNATURE, currentTime, user);
4157
4158        /*
4159         * If the system app should be overridden by a previously installed
4160         * data, hide the system app now and let the /data/app scan pick it up
4161         * again.
4162         */
4163        if (shouldHideSystemApp) {
4164            synchronized (mPackages) {
4165                /*
4166                 * We have to grant systems permissions before we hide, because
4167                 * grantPermissions will assume the package update is trying to
4168                 * expand its permissions.
4169                 */
4170                grantPermissionsLPw(pkg, true);
4171                mSettings.disableSystemPackageLPw(pkg.packageName);
4172            }
4173        }
4174
4175        return scannedPkg;
4176    }
4177
4178    private static void setApplicationInfoPaths(PackageParser.Package pkg, String destCodePath,
4179            String destResPath) {
4180        pkg.mPath = pkg.mScanPath = destCodePath;
4181        pkg.applicationInfo.sourceDir = destCodePath;
4182        pkg.applicationInfo.publicSourceDir = destResPath;
4183    }
4184
4185    private static String fixProcessName(String defProcessName,
4186            String processName, int uid) {
4187        if (processName == null) {
4188            return defProcessName;
4189        }
4190        return processName;
4191    }
4192
4193    private boolean verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg) {
4194        if (pkgSetting.signatures.mSignatures != null) {
4195            // Already existing package. Make sure signatures match
4196            boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
4197                    == PackageManager.SIGNATURE_MATCH;
4198            if (!match) {
4199                match = compareSignaturesCompat(pkgSetting.signatures, pkg)
4200                        == PackageManager.SIGNATURE_MATCH;
4201            }
4202            if (!match) {
4203                Slog.e(TAG, "Package " + pkg.packageName
4204                        + " signatures do not match the previously installed version; ignoring!");
4205                mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
4206                return false;
4207            }
4208        }
4209        // Check for shared user signatures
4210        if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
4211            // Already existing package. Make sure signatures match
4212            boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
4213                    pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
4214            if (!match) {
4215                match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
4216                        == PackageManager.SIGNATURE_MATCH;
4217            }
4218            if (!match) {
4219                Slog.e(TAG, "Package " + pkg.packageName
4220                        + " has no signatures that match those in shared user "
4221                        + pkgSetting.sharedUser.name + "; ignoring!");
4222                mLastScanError = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
4223                return false;
4224            }
4225        }
4226        return true;
4227    }
4228
4229    /**
4230     * Enforces that only the system UID or root's UID can call a method exposed
4231     * via Binder.
4232     *
4233     * @param message used as message if SecurityException is thrown
4234     * @throws SecurityException if the caller is not system or root
4235     */
4236    private static final void enforceSystemOrRoot(String message) {
4237        final int uid = Binder.getCallingUid();
4238        if (uid != Process.SYSTEM_UID && uid != 0) {
4239            throw new SecurityException(message);
4240        }
4241    }
4242
4243    public void performBootDexOpt() {
4244        HashSet<PackageParser.Package> pkgs = null;
4245        synchronized (mPackages) {
4246            pkgs = mDeferredDexOpt;
4247            mDeferredDexOpt = null;
4248        }
4249        if (pkgs != null) {
4250            int i = 0;
4251            for (PackageParser.Package pkg : pkgs) {
4252                if (!isFirstBoot()) {
4253                    i++;
4254                    try {
4255                        ActivityManagerNative.getDefault().showBootMessage(
4256                                mContext.getResources().getString(
4257                                        com.android.internal.R.string.android_upgrading_apk,
4258                                        i, pkgs.size()), true);
4259                    } catch (RemoteException e) {
4260                    }
4261                }
4262                PackageParser.Package p = pkg;
4263                synchronized (mInstallLock) {
4264                    if (!p.mDidDexOpt) {
4265                        performDexOptLI(p, false, false, true);
4266                    }
4267                }
4268            }
4269        }
4270    }
4271
4272    public boolean performDexOpt(String packageName) {
4273        enforceSystemOrRoot("Only the system can request dexopt be performed");
4274
4275        if (!mNoDexOpt) {
4276            return false;
4277        }
4278
4279        PackageParser.Package p;
4280        synchronized (mPackages) {
4281            p = mPackages.get(packageName);
4282            if (p == null || p.mDidDexOpt) {
4283                return false;
4284            }
4285        }
4286        synchronized (mInstallLock) {
4287            return performDexOptLI(p, false, false, true) == DEX_OPT_PERFORMED;
4288        }
4289    }
4290
4291    private void performDexOptLibsLI(ArrayList<String> libs, boolean forceDex, boolean defer,
4292            HashSet<String> done) {
4293        for (int i=0; i<libs.size(); i++) {
4294            PackageParser.Package libPkg;
4295            String libName;
4296            synchronized (mPackages) {
4297                libName = libs.get(i);
4298                SharedLibraryEntry lib = mSharedLibraries.get(libName);
4299                if (lib != null && lib.apk != null) {
4300                    libPkg = mPackages.get(lib.apk);
4301                } else {
4302                    libPkg = null;
4303                }
4304            }
4305            if (libPkg != null && !done.contains(libName)) {
4306                performDexOptLI(libPkg, forceDex, defer, done);
4307            }
4308        }
4309    }
4310
4311    static final int DEX_OPT_SKIPPED = 0;
4312    static final int DEX_OPT_PERFORMED = 1;
4313    static final int DEX_OPT_DEFERRED = 2;
4314    static final int DEX_OPT_FAILED = -1;
4315
4316    private int performDexOptLI(PackageParser.Package pkg, boolean forceDex, boolean defer,
4317            HashSet<String> done) {
4318        boolean performed = false;
4319        if (done != null) {
4320            done.add(pkg.packageName);
4321            if (pkg.usesLibraries != null) {
4322                performDexOptLibsLI(pkg.usesLibraries, forceDex, defer, done);
4323            }
4324            if (pkg.usesOptionalLibraries != null) {
4325                performDexOptLibsLI(pkg.usesOptionalLibraries, forceDex, defer, done);
4326            }
4327        }
4328        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
4329            String path = pkg.mScanPath;
4330            int ret = 0;
4331            try {
4332                if (forceDex || dalvik.system.DexFile.isDexOptNeededInternal(path, pkg.packageName,
4333                                                                             defer)) {
4334                    if (!forceDex && defer) {
4335                        if (mDeferredDexOpt == null) {
4336                            mDeferredDexOpt = new HashSet<PackageParser.Package>();
4337                        }
4338                        mDeferredDexOpt.add(pkg);
4339                        return DEX_OPT_DEFERRED;
4340                    } else {
4341                        Log.i(TAG, "Running dexopt on: " + pkg.applicationInfo.packageName);
4342                        final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
4343                        ret = mInstaller.dexopt(path, sharedGid, !isForwardLocked(pkg),
4344                                                pkg.packageName);
4345                        pkg.mDidDexOpt = true;
4346                        performed = true;
4347                    }
4348                }
4349            } catch (FileNotFoundException e) {
4350                Slog.w(TAG, "Apk not found for dexopt: " + path);
4351                ret = -1;
4352            } catch (IOException e) {
4353                Slog.w(TAG, "IOException reading apk: " + path, e);
4354                ret = -1;
4355            } catch (dalvik.system.StaleDexCacheError e) {
4356                Slog.w(TAG, "StaleDexCacheError when reading apk: " + path, e);
4357                ret = -1;
4358            } catch (Exception e) {
4359                Slog.w(TAG, "Exception when doing dexopt : ", e);
4360                ret = -1;
4361            }
4362            if (ret < 0) {
4363                //error from installer
4364                return DEX_OPT_FAILED;
4365            }
4366        }
4367
4368        return performed ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED;
4369    }
4370
4371    private int performDexOptLI(PackageParser.Package pkg, boolean forceDex, boolean defer,
4372            boolean inclDependencies) {
4373        HashSet<String> done;
4374        boolean performed = false;
4375        if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) {
4376            done = new HashSet<String>();
4377            done.add(pkg.packageName);
4378        } else {
4379            done = null;
4380        }
4381        return performDexOptLI(pkg, forceDex, defer, done);
4382    }
4383
4384    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
4385        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
4386            Slog.w(TAG, "Unable to update from " + oldPkg.name
4387                    + " to " + newPkg.packageName
4388                    + ": old package not in system partition");
4389            return false;
4390        } else if (mPackages.get(oldPkg.name) != null) {
4391            Slog.w(TAG, "Unable to update from " + oldPkg.name
4392                    + " to " + newPkg.packageName
4393                    + ": old package still exists");
4394            return false;
4395        }
4396        return true;
4397    }
4398
4399    File getDataPathForUser(int userId) {
4400        return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId);
4401    }
4402
4403    private File getDataPathForPackage(String packageName, int userId) {
4404        /*
4405         * Until we fully support multiple users, return the directory we
4406         * previously would have. The PackageManagerTests will need to be
4407         * revised when this is changed back..
4408         */
4409        if (userId == 0) {
4410            return new File(mAppDataDir, packageName);
4411        } else {
4412            return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId
4413                + File.separator + packageName);
4414        }
4415    }
4416
4417    private int createDataDirsLI(String packageName, int uid, String seinfo) {
4418        int[] users = sUserManager.getUserIds();
4419        int res = mInstaller.install(packageName, uid, uid, seinfo);
4420        if (res < 0) {
4421            return res;
4422        }
4423        for (int user : users) {
4424            if (user != 0) {
4425                res = mInstaller.createUserData(packageName,
4426                        UserHandle.getUid(user, uid), user, seinfo);
4427                if (res < 0) {
4428                    return res;
4429                }
4430            }
4431        }
4432        return res;
4433    }
4434
4435    private int removeDataDirsLI(String packageName) {
4436        int[] users = sUserManager.getUserIds();
4437        int res = 0;
4438        for (int user : users) {
4439            int resInner = mInstaller.remove(packageName, user);
4440            if (resInner < 0) {
4441                res = resInner;
4442            }
4443        }
4444
4445        final File nativeLibraryFile = new File(mAppLibInstallDir, packageName);
4446        NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryFile);
4447        if (!nativeLibraryFile.delete()) {
4448            Slog.w(TAG, "Couldn't delete native library directory " + nativeLibraryFile.getPath());
4449        }
4450
4451        return res;
4452    }
4453
4454    private int addSharedLibraryLPw(final SharedLibraryEntry file, int num,
4455            PackageParser.Package changingLib) {
4456        if (file.path != null) {
4457            mTmpSharedLibraries[num] = file.path;
4458            return num+1;
4459        }
4460        PackageParser.Package p = mPackages.get(file.apk);
4461        if (changingLib != null && changingLib.packageName.equals(file.apk)) {
4462            // If we are doing this while in the middle of updating a library apk,
4463            // then we need to make sure to use that new apk for determining the
4464            // dependencies here.  (We haven't yet finished committing the new apk
4465            // to the package manager state.)
4466            if (p == null || p.packageName.equals(changingLib.packageName)) {
4467                p = changingLib;
4468            }
4469        }
4470        if (p != null) {
4471            String path = p.mPath;
4472            for (int i=0; i<num; i++) {
4473                if (mTmpSharedLibraries[i].equals(path)) {
4474                    return num;
4475                }
4476            }
4477            mTmpSharedLibraries[num] = p.mPath;
4478            return num+1;
4479        }
4480        return num;
4481    }
4482
4483    private boolean updateSharedLibrariesLPw(PackageParser.Package pkg,
4484            PackageParser.Package changingLib) {
4485        // We might be upgrading from a version of the platform that did not
4486        // provide per-package native library directories for system apps.
4487        // Fix that up here.
4488        if (isSystemApp(pkg)) {
4489            PackageSetting ps = mSettings.mPackages.get(pkg.applicationInfo.packageName);
4490            setInternalAppNativeLibraryPath(pkg, ps);
4491        }
4492
4493        if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
4494            if (mTmpSharedLibraries == null ||
4495                    mTmpSharedLibraries.length < mSharedLibraries.size()) {
4496                mTmpSharedLibraries = new String[mSharedLibraries.size()];
4497            }
4498            int num = 0;
4499            int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
4500            for (int i=0; i<N; i++) {
4501                final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i));
4502                if (file == null) {
4503                    Slog.e(TAG, "Package " + pkg.packageName
4504                            + " requires unavailable shared library "
4505                            + pkg.usesLibraries.get(i) + "; failing!");
4506                    mLastScanError = PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
4507                    return false;
4508                }
4509                num = addSharedLibraryLPw(file, num, changingLib);
4510            }
4511            N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
4512            for (int i=0; i<N; i++) {
4513                final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
4514                if (file == null) {
4515                    Slog.w(TAG, "Package " + pkg.packageName
4516                            + " desires unavailable shared library "
4517                            + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
4518                } else {
4519                    num = addSharedLibraryLPw(file, num, changingLib);
4520                }
4521            }
4522            if (num > 0) {
4523                pkg.usesLibraryFiles = new String[num];
4524                System.arraycopy(mTmpSharedLibraries, 0,
4525                        pkg.usesLibraryFiles, 0, num);
4526            } else {
4527                pkg.usesLibraryFiles = null;
4528            }
4529        }
4530        return true;
4531    }
4532
4533    private static boolean hasString(List<String> list, List<String> which) {
4534        if (list == null) {
4535            return false;
4536        }
4537        for (int i=list.size()-1; i>=0; i--) {
4538            for (int j=which.size()-1; j>=0; j--) {
4539                if (which.get(j).equals(list.get(i))) {
4540                    return true;
4541                }
4542            }
4543        }
4544        return false;
4545    }
4546
4547    private void updateAllSharedLibrariesLPw() {
4548        for (PackageParser.Package pkg : mPackages.values()) {
4549            updateSharedLibrariesLPw(pkg, null);
4550        }
4551    }
4552
4553    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
4554            PackageParser.Package changingPkg) {
4555        ArrayList<PackageParser.Package> res = null;
4556        for (PackageParser.Package pkg : mPackages.values()) {
4557            if (hasString(pkg.usesLibraries, changingPkg.libraryNames)
4558                    || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) {
4559                if (res == null) {
4560                    res = new ArrayList<PackageParser.Package>();
4561                }
4562                res.add(pkg);
4563                updateSharedLibrariesLPw(pkg, changingPkg);
4564            }
4565        }
4566        return res;
4567    }
4568
4569    private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
4570            int parseFlags, int scanMode, long currentTime, UserHandle user) {
4571        File scanFile = new File(pkg.mScanPath);
4572        if (scanFile == null || pkg.applicationInfo.sourceDir == null ||
4573                pkg.applicationInfo.publicSourceDir == null) {
4574            // Bail out. The resource and code paths haven't been set.
4575            Slog.w(TAG, " Code and resource paths haven't been set correctly");
4576            mLastScanError = PackageManager.INSTALL_FAILED_INVALID_APK;
4577            return null;
4578        }
4579
4580        if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
4581            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
4582        }
4583
4584        if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
4585            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_PRIVILEGED;
4586        }
4587
4588        if (mCustomResolverComponentName != null &&
4589                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
4590            setUpCustomResolverActivity(pkg);
4591        }
4592
4593        if (pkg.packageName.equals("android")) {
4594            synchronized (mPackages) {
4595                if (mAndroidApplication != null) {
4596                    Slog.w(TAG, "*************************************************");
4597                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
4598                    Slog.w(TAG, " file=" + scanFile);
4599                    Slog.w(TAG, "*************************************************");
4600                    mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
4601                    return null;
4602                }
4603
4604                // Set up information for our fall-back user intent resolution activity.
4605                mPlatformPackage = pkg;
4606                pkg.mVersionCode = mSdkVersion;
4607                mAndroidApplication = pkg.applicationInfo;
4608
4609                if (!mResolverReplaced) {
4610                    mResolveActivity.applicationInfo = mAndroidApplication;
4611                    mResolveActivity.name = ResolverActivity.class.getName();
4612                    mResolveActivity.packageName = mAndroidApplication.packageName;
4613                    mResolveActivity.processName = "system:ui";
4614                    mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
4615                    mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
4616                    mResolveActivity.theme = com.android.internal.R.style.Theme_Holo_Dialog_Alert;
4617                    mResolveActivity.exported = true;
4618                    mResolveActivity.enabled = true;
4619                    mResolveInfo.activityInfo = mResolveActivity;
4620                    mResolveInfo.priority = 0;
4621                    mResolveInfo.preferredOrder = 0;
4622                    mResolveInfo.match = 0;
4623                    mResolveComponentName = new ComponentName(
4624                            mAndroidApplication.packageName, mResolveActivity.name);
4625                }
4626            }
4627        }
4628
4629        if (DEBUG_PACKAGE_SCANNING) {
4630            if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
4631                Log.d(TAG, "Scanning package " + pkg.packageName);
4632        }
4633
4634        if (mPackages.containsKey(pkg.packageName)
4635                || mSharedLibraries.containsKey(pkg.packageName)) {
4636            Slog.w(TAG, "Application package " + pkg.packageName
4637                    + " already installed.  Skipping duplicate.");
4638            mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
4639            return null;
4640        }
4641
4642        // Initialize package source and resource directories
4643        File destCodeFile = new File(pkg.applicationInfo.sourceDir);
4644        File destResourceFile = new File(pkg.applicationInfo.publicSourceDir);
4645
4646        SharedUserSetting suid = null;
4647        PackageSetting pkgSetting = null;
4648
4649        if (!isSystemApp(pkg)) {
4650            // Only system apps can use these features.
4651            pkg.mOriginalPackages = null;
4652            pkg.mRealPackage = null;
4653            pkg.mAdoptPermissions = null;
4654        }
4655
4656        // writer
4657        synchronized (mPackages) {
4658            if (pkg.mSharedUserId != null) {
4659                suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, true);
4660                if (suid == null) {
4661                    Slog.w(TAG, "Creating application package " + pkg.packageName
4662                            + " for shared user failed");
4663                    mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
4664                    return null;
4665                }
4666                if (DEBUG_PACKAGE_SCANNING) {
4667                    if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
4668                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
4669                                + "): packages=" + suid.packages);
4670                }
4671            }
4672
4673            // Check if we are renaming from an original package name.
4674            PackageSetting origPackage = null;
4675            String realName = null;
4676            if (pkg.mOriginalPackages != null) {
4677                // This package may need to be renamed to a previously
4678                // installed name.  Let's check on that...
4679                final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
4680                if (pkg.mOriginalPackages.contains(renamed)) {
4681                    // This package had originally been installed as the
4682                    // original name, and we have already taken care of
4683                    // transitioning to the new one.  Just update the new
4684                    // one to continue using the old name.
4685                    realName = pkg.mRealPackage;
4686                    if (!pkg.packageName.equals(renamed)) {
4687                        // Callers into this function may have already taken
4688                        // care of renaming the package; only do it here if
4689                        // it is not already done.
4690                        pkg.setPackageName(renamed);
4691                    }
4692
4693                } else {
4694                    for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
4695                        if ((origPackage = mSettings.peekPackageLPr(
4696                                pkg.mOriginalPackages.get(i))) != null) {
4697                            // We do have the package already installed under its
4698                            // original name...  should we use it?
4699                            if (!verifyPackageUpdateLPr(origPackage, pkg)) {
4700                                // New package is not compatible with original.
4701                                origPackage = null;
4702                                continue;
4703                            } else if (origPackage.sharedUser != null) {
4704                                // Make sure uid is compatible between packages.
4705                                if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
4706                                    Slog.w(TAG, "Unable to migrate data from " + origPackage.name
4707                                            + " to " + pkg.packageName + ": old uid "
4708                                            + origPackage.sharedUser.name
4709                                            + " differs from " + pkg.mSharedUserId);
4710                                    origPackage = null;
4711                                    continue;
4712                                }
4713                            } else {
4714                                if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
4715                                        + pkg.packageName + " to old name " + origPackage.name);
4716                            }
4717                            break;
4718                        }
4719                    }
4720                }
4721            }
4722
4723            if (mTransferedPackages.contains(pkg.packageName)) {
4724                Slog.w(TAG, "Package " + pkg.packageName
4725                        + " was transferred to another, but its .apk remains");
4726            }
4727
4728            // Just create the setting, don't add it yet. For already existing packages
4729            // the PkgSetting exists already and doesn't have to be created.
4730            pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
4731                    destResourceFile, pkg.applicationInfo.nativeLibraryDir,
4732                    pkg.applicationInfo.requiredCpuAbi,
4733                    pkg.applicationInfo.flags, user, false);
4734            if (pkgSetting == null) {
4735                Slog.w(TAG, "Creating application package " + pkg.packageName + " failed");
4736                mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
4737                return null;
4738            }
4739
4740            if (pkgSetting.origPackage != null) {
4741                // If we are first transitioning from an original package,
4742                // fix up the new package's name now.  We need to do this after
4743                // looking up the package under its new name, so getPackageLP
4744                // can take care of fiddling things correctly.
4745                pkg.setPackageName(origPackage.name);
4746
4747                // File a report about this.
4748                String msg = "New package " + pkgSetting.realName
4749                        + " renamed to replace old package " + pkgSetting.name;
4750                reportSettingsProblem(Log.WARN, msg);
4751
4752                // Make a note of it.
4753                mTransferedPackages.add(origPackage.name);
4754
4755                // No longer need to retain this.
4756                pkgSetting.origPackage = null;
4757            }
4758
4759            if (realName != null) {
4760                // Make a note of it.
4761                mTransferedPackages.add(pkg.packageName);
4762            }
4763
4764            if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
4765                pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
4766            }
4767
4768            if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
4769                // Check all shared libraries and map to their actual file path.
4770                // We only do this here for apps not on a system dir, because those
4771                // are the only ones that can fail an install due to this.  We
4772                // will take care of the system apps by updating all of their
4773                // library paths after the scan is done.
4774                if (!updateSharedLibrariesLPw(pkg, null)) {
4775                    return null;
4776                }
4777            }
4778
4779            if (mFoundPolicyFile) {
4780                SELinuxMMAC.assignSeinfoValue(pkg);
4781            }
4782
4783            pkg.applicationInfo.uid = pkgSetting.appId;
4784            pkg.mExtras = pkgSetting;
4785
4786            if (!verifySignaturesLP(pkgSetting, pkg)) {
4787                if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
4788                    return null;
4789                }
4790                // The signature has changed, but this package is in the system
4791                // image...  let's recover!
4792                pkgSetting.signatures.mSignatures = pkg.mSignatures;
4793                // However...  if this package is part of a shared user, but it
4794                // doesn't match the signature of the shared user, let's fail.
4795                // What this means is that you can't change the signatures
4796                // associated with an overall shared user, which doesn't seem all
4797                // that unreasonable.
4798                if (pkgSetting.sharedUser != null) {
4799                    if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
4800                            pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
4801                        Log.w(TAG, "Signature mismatch for shared user : " + pkgSetting.sharedUser);
4802                        mLastScanError = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
4803                        return null;
4804                    }
4805                }
4806                // File a report about this.
4807                String msg = "System package " + pkg.packageName
4808                        + " signature changed; retaining data.";
4809                reportSettingsProblem(Log.WARN, msg);
4810            }
4811
4812            // Verify that this new package doesn't have any content providers
4813            // that conflict with existing packages.  Only do this if the
4814            // package isn't already installed, since we don't want to break
4815            // things that are installed.
4816            if ((scanMode&SCAN_NEW_INSTALL) != 0) {
4817                final int N = pkg.providers.size();
4818                int i;
4819                for (i=0; i<N; i++) {
4820                    PackageParser.Provider p = pkg.providers.get(i);
4821                    if (p.info.authority != null) {
4822                        String names[] = p.info.authority.split(";");
4823                        for (int j = 0; j < names.length; j++) {
4824                            if (mProvidersByAuthority.containsKey(names[j])) {
4825                                PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
4826                                Slog.w(TAG, "Can't install because provider name " + names[j] +
4827                                        " (in package " + pkg.applicationInfo.packageName +
4828                                        ") is already used by "
4829                                        + ((other != null && other.getComponentName() != null)
4830                                                ? other.getComponentName().getPackageName() : "?"));
4831                                mLastScanError = PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
4832                                return null;
4833                            }
4834                        }
4835                    }
4836                }
4837            }
4838
4839            if (pkg.mAdoptPermissions != null) {
4840                // This package wants to adopt ownership of permissions from
4841                // another package.
4842                for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
4843                    final String origName = pkg.mAdoptPermissions.get(i);
4844                    final PackageSetting orig = mSettings.peekPackageLPr(origName);
4845                    if (orig != null) {
4846                        if (verifyPackageUpdateLPr(orig, pkg)) {
4847                            Slog.i(TAG, "Adopting permissions from " + origName + " to "
4848                                    + pkg.packageName);
4849                            mSettings.transferPermissionsLPw(origName, pkg.packageName);
4850                        }
4851                    }
4852                }
4853            }
4854        }
4855
4856        final String pkgName = pkg.packageName;
4857
4858        final long scanFileTime = scanFile.lastModified();
4859        final boolean forceDex = (scanMode&SCAN_FORCE_DEX) != 0;
4860        pkg.applicationInfo.processName = fixProcessName(
4861                pkg.applicationInfo.packageName,
4862                pkg.applicationInfo.processName,
4863                pkg.applicationInfo.uid);
4864
4865        File dataPath;
4866        if (mPlatformPackage == pkg) {
4867            // The system package is special.
4868            dataPath = new File (Environment.getDataDirectory(), "system");
4869            pkg.applicationInfo.dataDir = dataPath.getPath();
4870        } else {
4871            // This is a normal package, need to make its data directory.
4872            dataPath = getDataPathForPackage(pkg.packageName, 0);
4873
4874            boolean uidError = false;
4875
4876            if (dataPath.exists()) {
4877                int currentUid = 0;
4878                try {
4879                    StructStat stat = Os.stat(dataPath.getPath());
4880                    currentUid = stat.st_uid;
4881                } catch (ErrnoException e) {
4882                    Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e);
4883                }
4884
4885                // If we have mismatched owners for the data path, we have a problem.
4886                if (currentUid != pkg.applicationInfo.uid) {
4887                    boolean recovered = false;
4888                    if (currentUid == 0) {
4889                        // The directory somehow became owned by root.  Wow.
4890                        // This is probably because the system was stopped while
4891                        // installd was in the middle of messing with its libs
4892                        // directory.  Ask installd to fix that.
4893                        int ret = mInstaller.fixUid(pkgName, pkg.applicationInfo.uid,
4894                                pkg.applicationInfo.uid);
4895                        if (ret >= 0) {
4896                            recovered = true;
4897                            String msg = "Package " + pkg.packageName
4898                                    + " unexpectedly changed to uid 0; recovered to " +
4899                                    + pkg.applicationInfo.uid;
4900                            reportSettingsProblem(Log.WARN, msg);
4901                        }
4902                    }
4903                    if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
4904                            || (scanMode&SCAN_BOOTING) != 0)) {
4905                        // If this is a system app, we can at least delete its
4906                        // current data so the application will still work.
4907                        int ret = removeDataDirsLI(pkgName);
4908                        if (ret >= 0) {
4909                            // TODO: Kill the processes first
4910                            // Old data gone!
4911                            String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
4912                                    ? "System package " : "Third party package ";
4913                            String msg = prefix + pkg.packageName
4914                                    + " has changed from uid: "
4915                                    + currentUid + " to "
4916                                    + pkg.applicationInfo.uid + "; old data erased";
4917                            reportSettingsProblem(Log.WARN, msg);
4918                            recovered = true;
4919
4920                            // And now re-install the app.
4921                            ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid,
4922                                                   pkg.applicationInfo.seinfo);
4923                            if (ret == -1) {
4924                                // Ack should not happen!
4925                                msg = prefix + pkg.packageName
4926                                        + " could not have data directory re-created after delete.";
4927                                reportSettingsProblem(Log.WARN, msg);
4928                                mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
4929                                return null;
4930                            }
4931                        }
4932                        if (!recovered) {
4933                            mHasSystemUidErrors = true;
4934                        }
4935                    } else if (!recovered) {
4936                        // If we allow this install to proceed, we will be broken.
4937                        // Abort, abort!
4938                        mLastScanError = PackageManager.INSTALL_FAILED_UID_CHANGED;
4939                        return null;
4940                    }
4941                    if (!recovered) {
4942                        pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
4943                            + pkg.applicationInfo.uid + "/fs_"
4944                            + currentUid;
4945                        pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
4946                        String msg = "Package " + pkg.packageName
4947                                + " has mismatched uid: "
4948                                + currentUid + " on disk, "
4949                                + pkg.applicationInfo.uid + " in settings";
4950                        // writer
4951                        synchronized (mPackages) {
4952                            mSettings.mReadMessages.append(msg);
4953                            mSettings.mReadMessages.append('\n');
4954                            uidError = true;
4955                            if (!pkgSetting.uidError) {
4956                                reportSettingsProblem(Log.ERROR, msg);
4957                            }
4958                        }
4959                    }
4960                }
4961                pkg.applicationInfo.dataDir = dataPath.getPath();
4962                if (mShouldRestoreconData) {
4963                    Slog.i(TAG, "SELinux relabeling of " + pkg.packageName + " issued.");
4964                    mInstaller.restoreconData(pkg.packageName, pkg.applicationInfo.seinfo,
4965                                pkg.applicationInfo.uid);
4966                }
4967            } else {
4968                if (DEBUG_PACKAGE_SCANNING) {
4969                    if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
4970                        Log.v(TAG, "Want this data dir: " + dataPath);
4971                }
4972                //invoke installer to do the actual installation
4973                int ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid,
4974                                           pkg.applicationInfo.seinfo);
4975                if (ret < 0) {
4976                    // Error from installer
4977                    mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
4978                    return null;
4979                }
4980
4981                if (dataPath.exists()) {
4982                    pkg.applicationInfo.dataDir = dataPath.getPath();
4983                } else {
4984                    Slog.w(TAG, "Unable to create data directory: " + dataPath);
4985                    pkg.applicationInfo.dataDir = null;
4986                }
4987            }
4988
4989            /*
4990             * Set the data dir to the default "/data/data/<package name>/lib"
4991             * if we got here without anyone telling us different (e.g., apps
4992             * stored on SD card have their native libraries stored in the ASEC
4993             * container with the APK).
4994             *
4995             * This happens during an upgrade from a package settings file that
4996             * doesn't have a native library path attribute at all.
4997             */
4998            if (pkg.applicationInfo.nativeLibraryDir == null && pkg.applicationInfo.dataDir != null) {
4999                if (pkgSetting.nativeLibraryPathString == null) {
5000                    setInternalAppNativeLibraryPath(pkg, pkgSetting);
5001                } else {
5002                    pkg.applicationInfo.nativeLibraryDir = pkgSetting.nativeLibraryPathString;
5003                }
5004            }
5005            pkgSetting.uidError = uidError;
5006        }
5007
5008        String path = scanFile.getPath();
5009        /* Note: We don't want to unpack the native binaries for
5010         *        system applications, unless they have been updated
5011         *        (the binaries are already under /system/lib).
5012         *        Also, don't unpack libs for apps on the external card
5013         *        since they should have their libraries in the ASEC
5014         *        container already.
5015         *
5016         *        In other words, we're going to unpack the binaries
5017         *        only for non-system apps and system app upgrades.
5018         */
5019        if (pkg.applicationInfo.nativeLibraryDir != null) {
5020            try {
5021                File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
5022                final String dataPathString = dataPath.getCanonicalPath();
5023
5024                if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
5025                    /*
5026                     * Upgrading from a previous version of the OS sometimes
5027                     * leaves native libraries in the /data/data/<app>/lib
5028                     * directory for system apps even when they shouldn't be.
5029                     * Recent changes in the JNI library search path
5030                     * necessitates we remove those to match previous behavior.
5031                     */
5032                    if (NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryDir)) {
5033                        Log.i(TAG, "removed obsolete native libraries for system package "
5034                                + path);
5035                    }
5036                } else {
5037                    if (!isForwardLocked(pkg) && !isExternal(pkg)) {
5038                        /*
5039                         * Update native library dir if it starts with
5040                         * /data/data
5041                         */
5042                        if (nativeLibraryDir.getPath().startsWith(dataPathString)) {
5043                            setInternalAppNativeLibraryPath(pkg, pkgSetting);
5044                            nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
5045                        }
5046
5047                        try {
5048                            int copyRet = copyNativeLibrariesForInternalApp(scanFile, nativeLibraryDir);
5049                            if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
5050                                Slog.e(TAG, "Unable to copy native libraries");
5051                                mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
5052                                return null;
5053                            }
5054
5055                            // We've successfully copied native libraries across, so we make a
5056                            // note of what ABI we're using
5057                            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
5058                                pkg.applicationInfo.requiredCpuAbi = Build.SUPPORTED_ABIS[copyRet];
5059                            } else {
5060                                pkg.applicationInfo.requiredCpuAbi = null;
5061                            }
5062                        } catch (IOException e) {
5063                            Slog.e(TAG, "Unable to copy native libraries", e);
5064                            mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
5065                            return null;
5066                        }
5067                    }
5068
5069                    if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path);
5070                    final int[] userIds = sUserManager.getUserIds();
5071                    synchronized (mInstallLock) {
5072                        for (int userId : userIds) {
5073                            if (mInstaller.linkNativeLibraryDirectory(pkg.packageName,
5074                                    pkg.applicationInfo.nativeLibraryDir, userId) < 0) {
5075                                Slog.w(TAG, "Failed linking native library dir (user=" + userId
5076                                        + ")");
5077                                mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
5078                                return null;
5079                            }
5080                        }
5081                    }
5082                }
5083            } catch (IOException ioe) {
5084                Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
5085            }
5086        }
5087        pkg.mScanPath = path;
5088
5089        if ((scanMode&SCAN_NO_DEX) == 0) {
5090            if (performDexOptLI(pkg, forceDex, (scanMode&SCAN_DEFER_DEX) != 0, false)
5091                    == DEX_OPT_FAILED) {
5092                if ((scanMode & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
5093                    removeDataDirsLI(pkg.packageName);
5094                }
5095
5096                mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT;
5097                return null;
5098            }
5099        }
5100
5101        if (mFactoryTest && pkg.requestedPermissions.contains(
5102                android.Manifest.permission.FACTORY_TEST)) {
5103            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
5104        }
5105
5106        ArrayList<PackageParser.Package> clientLibPkgs = null;
5107
5108        // writer
5109        synchronized (mPackages) {
5110            if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
5111                // Only system apps can add new shared libraries.
5112                if (pkg.libraryNames != null) {
5113                    for (int i=0; i<pkg.libraryNames.size(); i++) {
5114                        String name = pkg.libraryNames.get(i);
5115                        boolean allowed = false;
5116                        if (isUpdatedSystemApp(pkg)) {
5117                            // New library entries can only be added through the
5118                            // system image.  This is important to get rid of a lot
5119                            // of nasty edge cases: for example if we allowed a non-
5120                            // system update of the app to add a library, then uninstalling
5121                            // the update would make the library go away, and assumptions
5122                            // we made such as through app install filtering would now
5123                            // have allowed apps on the device which aren't compatible
5124                            // with it.  Better to just have the restriction here, be
5125                            // conservative, and create many fewer cases that can negatively
5126                            // impact the user experience.
5127                            final PackageSetting sysPs = mSettings
5128                                    .getDisabledSystemPkgLPr(pkg.packageName);
5129                            if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
5130                                for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) {
5131                                    if (name.equals(sysPs.pkg.libraryNames.get(j))) {
5132                                        allowed = true;
5133                                        allowed = true;
5134                                        break;
5135                                    }
5136                                }
5137                            }
5138                        } else {
5139                            allowed = true;
5140                        }
5141                        if (allowed) {
5142                            if (!mSharedLibraries.containsKey(name)) {
5143                                mSharedLibraries.put(name, new SharedLibraryEntry(null,
5144                                        pkg.packageName));
5145                            } else if (!name.equals(pkg.packageName)) {
5146                                Slog.w(TAG, "Package " + pkg.packageName + " library "
5147                                        + name + " already exists; skipping");
5148                            }
5149                        } else {
5150                            Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
5151                                    + name + " that is not declared on system image; skipping");
5152                        }
5153                    }
5154                    if ((scanMode&SCAN_BOOTING) == 0) {
5155                        // If we are not booting, we need to update any applications
5156                        // that are clients of our shared library.  If we are booting,
5157                        // this will all be done once the scan is complete.
5158                        clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
5159                    }
5160                }
5161            }
5162        }
5163
5164        // We also need to dexopt any apps that are dependent on this library.  Note that
5165        // if these fail, we should abort the install since installing the library will
5166        // result in some apps being broken.
5167        if (clientLibPkgs != null) {
5168            if ((scanMode&SCAN_NO_DEX) == 0) {
5169                for (int i=0; i<clientLibPkgs.size(); i++) {
5170                    PackageParser.Package clientPkg = clientLibPkgs.get(i);
5171                    if (performDexOptLI(clientPkg, forceDex, (scanMode&SCAN_DEFER_DEX) != 0, false)
5172                            == DEX_OPT_FAILED) {
5173                        if ((scanMode & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
5174                            removeDataDirsLI(pkg.packageName);
5175                        }
5176
5177                        mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT;
5178                        return null;
5179                    }
5180                }
5181            }
5182        }
5183
5184        // Request the ActivityManager to kill the process(only for existing packages)
5185        // so that we do not end up in a confused state while the user is still using the older
5186        // version of the application while the new one gets installed.
5187        if ((parseFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
5188            // If the package lives in an asec, tell everyone that the container is going
5189            // away so they can clean up any references to its resources (which would prevent
5190            // vold from being able to unmount the asec)
5191            if (isForwardLocked(pkg) || isExternal(pkg)) {
5192                if (DEBUG_INSTALL) {
5193                    Slog.i(TAG, "upgrading pkg " + pkg + " is ASEC-hosted -> UNAVAILABLE");
5194                }
5195                final int[] uidArray = new int[] { pkg.applicationInfo.uid };
5196                final ArrayList<String> pkgList = new ArrayList<String>(1);
5197                pkgList.add(pkg.applicationInfo.packageName);
5198                sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
5199            }
5200
5201            // Post the request that it be killed now that the going-away broadcast is en route
5202            killApplication(pkg.applicationInfo.packageName,
5203                        pkg.applicationInfo.uid, "update pkg");
5204        }
5205
5206        // Also need to kill any apps that are dependent on the library.
5207        if (clientLibPkgs != null) {
5208            for (int i=0; i<clientLibPkgs.size(); i++) {
5209                PackageParser.Package clientPkg = clientLibPkgs.get(i);
5210                killApplication(clientPkg.applicationInfo.packageName,
5211                        clientPkg.applicationInfo.uid, "update lib");
5212            }
5213        }
5214
5215        // writer
5216        synchronized (mPackages) {
5217            // We don't expect installation to fail beyond this point,
5218            if ((scanMode&SCAN_MONITOR) != 0) {
5219                mAppDirs.put(pkg.mPath, pkg);
5220            }
5221            // Add the new setting to mSettings
5222            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
5223            // Add the new setting to mPackages
5224            mPackages.put(pkg.applicationInfo.packageName, pkg);
5225            // Make sure we don't accidentally delete its data.
5226            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
5227            while (iter.hasNext()) {
5228                PackageCleanItem item = iter.next();
5229                if (pkgName.equals(item.packageName)) {
5230                    iter.remove();
5231                }
5232            }
5233
5234            // Take care of first install / last update times.
5235            if (currentTime != 0) {
5236                if (pkgSetting.firstInstallTime == 0) {
5237                    pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
5238                } else if ((scanMode&SCAN_UPDATE_TIME) != 0) {
5239                    pkgSetting.lastUpdateTime = currentTime;
5240                }
5241            } else if (pkgSetting.firstInstallTime == 0) {
5242                // We need *something*.  Take time time stamp of the file.
5243                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
5244            } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
5245                if (scanFileTime != pkgSetting.timeStamp) {
5246                    // A package on the system image has changed; consider this
5247                    // to be an update.
5248                    pkgSetting.lastUpdateTime = scanFileTime;
5249                }
5250            }
5251
5252            // Add the package's KeySets to the global KeySetManager
5253            KeySetManager ksm = mSettings.mKeySetManager;
5254            try {
5255                ksm.addSigningKeySetToPackage(pkg.packageName, pkg.mSigningKeys);
5256                if (pkg.mKeySetMapping != null) {
5257                    for (Map.Entry<String, Set<PublicKey>> entry : pkg.mKeySetMapping.entrySet()) {
5258                        if (entry.getValue() != null) {
5259                            ksm.addDefinedKeySetToPackage(pkg.packageName,
5260                                entry.getValue(), entry.getKey());
5261                        }
5262                    }
5263                }
5264            } catch (NullPointerException e) {
5265                Slog.e(TAG, "Could not add KeySet to " + pkg.packageName, e);
5266            } catch (IllegalArgumentException e) {
5267                Slog.e(TAG, "Could not add KeySet to malformed package" + pkg.packageName, e);
5268            }
5269
5270            int N = pkg.providers.size();
5271            StringBuilder r = null;
5272            int i;
5273            for (i=0; i<N; i++) {
5274                PackageParser.Provider p = pkg.providers.get(i);
5275                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
5276                        p.info.processName, pkg.applicationInfo.uid);
5277                mProviders.addProvider(p);
5278                p.syncable = p.info.isSyncable;
5279                if (p.info.authority != null) {
5280                    String names[] = p.info.authority.split(";");
5281                    p.info.authority = null;
5282                    for (int j = 0; j < names.length; j++) {
5283                        if (j == 1 && p.syncable) {
5284                            // We only want the first authority for a provider to possibly be
5285                            // syncable, so if we already added this provider using a different
5286                            // authority clear the syncable flag. We copy the provider before
5287                            // changing it because the mProviders object contains a reference
5288                            // to a provider that we don't want to change.
5289                            // Only do this for the second authority since the resulting provider
5290                            // object can be the same for all future authorities for this provider.
5291                            p = new PackageParser.Provider(p);
5292                            p.syncable = false;
5293                        }
5294                        if (!mProvidersByAuthority.containsKey(names[j])) {
5295                            mProvidersByAuthority.put(names[j], p);
5296                            if (p.info.authority == null) {
5297                                p.info.authority = names[j];
5298                            } else {
5299                                p.info.authority = p.info.authority + ";" + names[j];
5300                            }
5301                            if (DEBUG_PACKAGE_SCANNING) {
5302                                if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
5303                                    Log.d(TAG, "Registered content provider: " + names[j]
5304                                            + ", className = " + p.info.name + ", isSyncable = "
5305                                            + p.info.isSyncable);
5306                            }
5307                        } else {
5308                            PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
5309                            Slog.w(TAG, "Skipping provider name " + names[j] +
5310                                    " (in package " + pkg.applicationInfo.packageName +
5311                                    "): name already used by "
5312                                    + ((other != null && other.getComponentName() != null)
5313                                            ? other.getComponentName().getPackageName() : "?"));
5314                        }
5315                    }
5316                }
5317                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
5318                    if (r == null) {
5319                        r = new StringBuilder(256);
5320                    } else {
5321                        r.append(' ');
5322                    }
5323                    r.append(p.info.name);
5324                }
5325            }
5326            if (r != null) {
5327                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
5328            }
5329
5330            N = pkg.services.size();
5331            r = null;
5332            for (i=0; i<N; i++) {
5333                PackageParser.Service s = pkg.services.get(i);
5334                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
5335                        s.info.processName, pkg.applicationInfo.uid);
5336                mServices.addService(s);
5337                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
5338                    if (r == null) {
5339                        r = new StringBuilder(256);
5340                    } else {
5341                        r.append(' ');
5342                    }
5343                    r.append(s.info.name);
5344                }
5345            }
5346            if (r != null) {
5347                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
5348            }
5349
5350            N = pkg.receivers.size();
5351            r = null;
5352            for (i=0; i<N; i++) {
5353                PackageParser.Activity a = pkg.receivers.get(i);
5354                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
5355                        a.info.processName, pkg.applicationInfo.uid);
5356                mReceivers.addActivity(a, "receiver");
5357                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
5358                    if (r == null) {
5359                        r = new StringBuilder(256);
5360                    } else {
5361                        r.append(' ');
5362                    }
5363                    r.append(a.info.name);
5364                }
5365            }
5366            if (r != null) {
5367                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
5368            }
5369
5370            N = pkg.activities.size();
5371            r = null;
5372            for (i=0; i<N; i++) {
5373                PackageParser.Activity a = pkg.activities.get(i);
5374                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
5375                        a.info.processName, pkg.applicationInfo.uid);
5376                mActivities.addActivity(a, "activity");
5377                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
5378                    if (r == null) {
5379                        r = new StringBuilder(256);
5380                    } else {
5381                        r.append(' ');
5382                    }
5383                    r.append(a.info.name);
5384                }
5385            }
5386            if (r != null) {
5387                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
5388            }
5389
5390            N = pkg.permissionGroups.size();
5391            r = null;
5392            for (i=0; i<N; i++) {
5393                PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
5394                PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
5395                if (cur == null) {
5396                    mPermissionGroups.put(pg.info.name, pg);
5397                    if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
5398                        if (r == null) {
5399                            r = new StringBuilder(256);
5400                        } else {
5401                            r.append(' ');
5402                        }
5403                        r.append(pg.info.name);
5404                    }
5405                } else {
5406                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
5407                            + pg.info.packageName + " ignored: original from "
5408                            + cur.info.packageName);
5409                    if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
5410                        if (r == null) {
5411                            r = new StringBuilder(256);
5412                        } else {
5413                            r.append(' ');
5414                        }
5415                        r.append("DUP:");
5416                        r.append(pg.info.name);
5417                    }
5418                }
5419            }
5420            if (r != null) {
5421                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
5422            }
5423
5424            N = pkg.permissions.size();
5425            r = null;
5426            for (i=0; i<N; i++) {
5427                PackageParser.Permission p = pkg.permissions.get(i);
5428                HashMap<String, BasePermission> permissionMap =
5429                        p.tree ? mSettings.mPermissionTrees
5430                        : mSettings.mPermissions;
5431                p.group = mPermissionGroups.get(p.info.group);
5432                if (p.info.group == null || p.group != null) {
5433                    BasePermission bp = permissionMap.get(p.info.name);
5434                    if (bp == null) {
5435                        bp = new BasePermission(p.info.name, p.info.packageName,
5436                                BasePermission.TYPE_NORMAL);
5437                        permissionMap.put(p.info.name, bp);
5438                    }
5439                    if (bp.perm == null) {
5440                        if (bp.sourcePackage != null
5441                                && !bp.sourcePackage.equals(p.info.packageName)) {
5442                            // If this is a permission that was formerly defined by a non-system
5443                            // app, but is now defined by a system app (following an upgrade),
5444                            // discard the previous declaration and consider the system's to be
5445                            // canonical.
5446                            if (isSystemApp(p.owner)) {
5447                                String msg = "New decl " + p.owner + " of permission  "
5448                                        + p.info.name + " is system";
5449                                reportSettingsProblem(Log.WARN, msg);
5450                                bp.sourcePackage = null;
5451                            }
5452                        }
5453                        if (bp.sourcePackage == null
5454                                || bp.sourcePackage.equals(p.info.packageName)) {
5455                            BasePermission tree = findPermissionTreeLP(p.info.name);
5456                            if (tree == null
5457                                    || tree.sourcePackage.equals(p.info.packageName)) {
5458                                bp.packageSetting = pkgSetting;
5459                                bp.perm = p;
5460                                bp.uid = pkg.applicationInfo.uid;
5461                                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
5462                                    if (r == null) {
5463                                        r = new StringBuilder(256);
5464                                    } else {
5465                                        r.append(' ');
5466                                    }
5467                                    r.append(p.info.name);
5468                                }
5469                            } else {
5470                                Slog.w(TAG, "Permission " + p.info.name + " from package "
5471                                        + p.info.packageName + " ignored: base tree "
5472                                        + tree.name + " is from package "
5473                                        + tree.sourcePackage);
5474                            }
5475                        } else {
5476                            Slog.w(TAG, "Permission " + p.info.name + " from package "
5477                                    + p.info.packageName + " ignored: original from "
5478                                    + bp.sourcePackage);
5479                        }
5480                    } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
5481                        if (r == null) {
5482                            r = new StringBuilder(256);
5483                        } else {
5484                            r.append(' ');
5485                        }
5486                        r.append("DUP:");
5487                        r.append(p.info.name);
5488                    }
5489                    if (bp.perm == p) {
5490                        bp.protectionLevel = p.info.protectionLevel;
5491                    }
5492                } else {
5493                    Slog.w(TAG, "Permission " + p.info.name + " from package "
5494                            + p.info.packageName + " ignored: no group "
5495                            + p.group);
5496                }
5497            }
5498            if (r != null) {
5499                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
5500            }
5501
5502            N = pkg.instrumentation.size();
5503            r = null;
5504            for (i=0; i<N; i++) {
5505                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
5506                a.info.packageName = pkg.applicationInfo.packageName;
5507                a.info.sourceDir = pkg.applicationInfo.sourceDir;
5508                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
5509                a.info.dataDir = pkg.applicationInfo.dataDir;
5510                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
5511                mInstrumentation.put(a.getComponentName(), a);
5512                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
5513                    if (r == null) {
5514                        r = new StringBuilder(256);
5515                    } else {
5516                        r.append(' ');
5517                    }
5518                    r.append(a.info.name);
5519                }
5520            }
5521            if (r != null) {
5522                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
5523            }
5524
5525            if (pkg.protectedBroadcasts != null) {
5526                N = pkg.protectedBroadcasts.size();
5527                for (i=0; i<N; i++) {
5528                    mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
5529                }
5530            }
5531
5532            pkgSetting.setTimeStamp(scanFileTime);
5533
5534            // Create idmap files for pairs of (packages, overlay packages).
5535            // Note: "android", ie framework-res.apk, is handled by native layers.
5536            if (pkg.mOverlayTarget != null) {
5537                // This is an overlay package.
5538                if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) {
5539                    if (!mOverlays.containsKey(pkg.mOverlayTarget)) {
5540                        mOverlays.put(pkg.mOverlayTarget,
5541                                new HashMap<String, PackageParser.Package>());
5542                    }
5543                    HashMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget);
5544                    map.put(pkg.packageName, pkg);
5545                    PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget);
5546                    if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) {
5547                        mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
5548                        return null;
5549                    }
5550                }
5551            } else if (mOverlays.containsKey(pkg.packageName) &&
5552                    !pkg.packageName.equals("android")) {
5553                // This is a regular package, with one or more known overlay packages.
5554                createIdmapsForPackageLI(pkg);
5555            }
5556        }
5557
5558        return pkg;
5559    }
5560
5561    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
5562        synchronized (mPackages) {
5563            mResolverReplaced = true;
5564            // Set up information for custom user intent resolution activity.
5565            mResolveActivity.applicationInfo = pkg.applicationInfo;
5566            mResolveActivity.name = mCustomResolverComponentName.getClassName();
5567            mResolveActivity.packageName = pkg.applicationInfo.packageName;
5568            mResolveActivity.processName = null;
5569            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
5570            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
5571                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
5572            mResolveActivity.theme = 0;
5573            mResolveActivity.exported = true;
5574            mResolveActivity.enabled = true;
5575            mResolveInfo.activityInfo = mResolveActivity;
5576            mResolveInfo.priority = 0;
5577            mResolveInfo.preferredOrder = 0;
5578            mResolveInfo.match = 0;
5579            mResolveComponentName = mCustomResolverComponentName;
5580            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
5581                    mResolveComponentName);
5582        }
5583    }
5584
5585    private String calculateApkRoot(final String codePathString) {
5586        final File codePath = new File(codePathString);
5587        final File codeRoot;
5588        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
5589            codeRoot = Environment.getRootDirectory();
5590        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
5591            codeRoot = Environment.getOemDirectory();
5592        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
5593            codeRoot = Environment.getVendorDirectory();
5594        } else {
5595            // Unrecognized code path; take its top real segment as the apk root:
5596            // e.g. /something/app/blah.apk => /something
5597            try {
5598                File f = codePath.getCanonicalFile();
5599                File parent = f.getParentFile();    // non-null because codePath is a file
5600                File tmp;
5601                while ((tmp = parent.getParentFile()) != null) {
5602                    f = parent;
5603                    parent = tmp;
5604                }
5605                codeRoot = f;
5606                Slog.w(TAG, "Unrecognized code path "
5607                        + codePath + " - using " + codeRoot);
5608            } catch (IOException e) {
5609                // Can't canonicalize the lib path -- shenanigans?
5610                Slog.w(TAG, "Can't canonicalize code path " + codePath);
5611                return Environment.getRootDirectory().getPath();
5612            }
5613        }
5614        return codeRoot.getPath();
5615    }
5616
5617    // This is the initial scan-time determination of how to handle a given
5618    // package for purposes of native library location.
5619    private void setInternalAppNativeLibraryPath(PackageParser.Package pkg,
5620            PackageSetting pkgSetting) {
5621        // "bundled" here means system-installed with no overriding update
5622        final boolean bundledApk = isSystemApp(pkg) && !isUpdatedSystemApp(pkg);
5623        final String apkName = getApkName(pkg.applicationInfo.sourceDir);
5624        final File libDir;
5625        if (bundledApk) {
5626            // If "/system/lib64/apkname" exists, assume that is the per-package
5627            // native library directory to use; otherwise use "/system/lib/apkname".
5628            String apkRoot = calculateApkRoot(pkg.applicationInfo.sourceDir);
5629            File lib64 = new File(apkRoot, LIB64_DIR_NAME);
5630            File packLib64 = new File(lib64, apkName);
5631            libDir = (packLib64.exists()) ? lib64 : new File(apkRoot, LIB_DIR_NAME);
5632        } else {
5633            libDir = mAppLibInstallDir;
5634        }
5635        final String nativeLibraryPath = (new File(libDir, apkName)).getPath();
5636        pkg.applicationInfo.nativeLibraryDir = nativeLibraryPath;
5637        pkgSetting.nativeLibraryPathString = nativeLibraryPath;
5638    }
5639
5640    private static int copyNativeLibrariesForInternalApp(File scanFile, final File nativeLibraryDir)
5641            throws IOException {
5642        if (!nativeLibraryDir.isDirectory()) {
5643            nativeLibraryDir.delete();
5644
5645            if (!nativeLibraryDir.mkdir()) {
5646                throw new IOException("Cannot create " + nativeLibraryDir.getPath());
5647            }
5648
5649            try {
5650                Os.chmod(nativeLibraryDir.getPath(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
5651            } catch (ErrnoException e) {
5652                throw new IOException("Cannot chmod native library directory "
5653                        + nativeLibraryDir.getPath(), e);
5654            }
5655        } else if (!SELinux.restorecon(nativeLibraryDir)) {
5656            throw new IOException("Cannot set SELinux context for " + nativeLibraryDir.getPath());
5657        }
5658
5659        /*
5660         * If this is an internal application or our nativeLibraryPath points to
5661         * the app-lib directory, unpack the libraries if necessary.
5662         */
5663        final NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(scanFile);
5664        try {
5665            int abi = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_ABIS);
5666            if (abi >= 0) {
5667                int copyRet = NativeLibraryHelper.copyNativeBinariesIfNeededLI(handle,
5668                        nativeLibraryDir, Build.SUPPORTED_ABIS[abi]);
5669                if (copyRet != PackageManager.INSTALL_SUCCEEDED) {
5670                    return copyRet;
5671                }
5672            }
5673
5674            return abi;
5675        } finally {
5676            handle.close();
5677        }
5678    }
5679
5680    private void killApplication(String pkgName, int appId, String reason) {
5681        // Request the ActivityManager to kill the process(only for existing packages)
5682        // so that we do not end up in a confused state while the user is still using the older
5683        // version of the application while the new one gets installed.
5684        IActivityManager am = ActivityManagerNative.getDefault();
5685        if (am != null) {
5686            try {
5687                am.killApplicationWithAppId(pkgName, appId, reason);
5688            } catch (RemoteException e) {
5689            }
5690        }
5691    }
5692
5693    void removePackageLI(PackageSetting ps, boolean chatty) {
5694        if (DEBUG_INSTALL) {
5695            if (chatty)
5696                Log.d(TAG, "Removing package " + ps.name);
5697        }
5698
5699        // writer
5700        synchronized (mPackages) {
5701            mPackages.remove(ps.name);
5702            if (ps.codePathString != null) {
5703                mAppDirs.remove(ps.codePathString);
5704            }
5705
5706            final PackageParser.Package pkg = ps.pkg;
5707            if (pkg != null) {
5708                cleanPackageDataStructuresLILPw(pkg, chatty);
5709            }
5710        }
5711    }
5712
5713    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
5714        if (DEBUG_INSTALL) {
5715            if (chatty)
5716                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
5717        }
5718
5719        // writer
5720        synchronized (mPackages) {
5721            mPackages.remove(pkg.applicationInfo.packageName);
5722            if (pkg.mPath != null) {
5723                mAppDirs.remove(pkg.mPath);
5724            }
5725            cleanPackageDataStructuresLILPw(pkg, chatty);
5726        }
5727    }
5728
5729    void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
5730        int N = pkg.providers.size();
5731        StringBuilder r = null;
5732        int i;
5733        for (i=0; i<N; i++) {
5734            PackageParser.Provider p = pkg.providers.get(i);
5735            mProviders.removeProvider(p);
5736            if (p.info.authority == null) {
5737
5738                /* There was another ContentProvider with this authority when
5739                 * this app was installed so this authority is null,
5740                 * Ignore it as we don't have to unregister the provider.
5741                 */
5742                continue;
5743            }
5744            String names[] = p.info.authority.split(";");
5745            for (int j = 0; j < names.length; j++) {
5746                if (mProvidersByAuthority.get(names[j]) == p) {
5747                    mProvidersByAuthority.remove(names[j]);
5748                    if (DEBUG_REMOVE) {
5749                        if (chatty)
5750                            Log.d(TAG, "Unregistered content provider: " + names[j]
5751                                    + ", className = " + p.info.name + ", isSyncable = "
5752                                    + p.info.isSyncable);
5753                    }
5754                }
5755            }
5756            if (DEBUG_REMOVE && chatty) {
5757                if (r == null) {
5758                    r = new StringBuilder(256);
5759                } else {
5760                    r.append(' ');
5761                }
5762                r.append(p.info.name);
5763            }
5764        }
5765        if (r != null) {
5766            if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
5767        }
5768
5769        N = pkg.services.size();
5770        r = null;
5771        for (i=0; i<N; i++) {
5772            PackageParser.Service s = pkg.services.get(i);
5773            mServices.removeService(s);
5774            if (chatty) {
5775                if (r == null) {
5776                    r = new StringBuilder(256);
5777                } else {
5778                    r.append(' ');
5779                }
5780                r.append(s.info.name);
5781            }
5782        }
5783        if (r != null) {
5784            if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
5785        }
5786
5787        N = pkg.receivers.size();
5788        r = null;
5789        for (i=0; i<N; i++) {
5790            PackageParser.Activity a = pkg.receivers.get(i);
5791            mReceivers.removeActivity(a, "receiver");
5792            if (DEBUG_REMOVE && chatty) {
5793                if (r == null) {
5794                    r = new StringBuilder(256);
5795                } else {
5796                    r.append(' ');
5797                }
5798                r.append(a.info.name);
5799            }
5800        }
5801        if (r != null) {
5802            if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
5803        }
5804
5805        N = pkg.activities.size();
5806        r = null;
5807        for (i=0; i<N; i++) {
5808            PackageParser.Activity a = pkg.activities.get(i);
5809            mActivities.removeActivity(a, "activity");
5810            if (DEBUG_REMOVE && chatty) {
5811                if (r == null) {
5812                    r = new StringBuilder(256);
5813                } else {
5814                    r.append(' ');
5815                }
5816                r.append(a.info.name);
5817            }
5818        }
5819        if (r != null) {
5820            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
5821        }
5822
5823        N = pkg.permissions.size();
5824        r = null;
5825        for (i=0; i<N; i++) {
5826            PackageParser.Permission p = pkg.permissions.get(i);
5827            BasePermission bp = mSettings.mPermissions.get(p.info.name);
5828            if (bp == null) {
5829                bp = mSettings.mPermissionTrees.get(p.info.name);
5830            }
5831            if (bp != null && bp.perm == p) {
5832                bp.perm = null;
5833                if (DEBUG_REMOVE && chatty) {
5834                    if (r == null) {
5835                        r = new StringBuilder(256);
5836                    } else {
5837                        r.append(' ');
5838                    }
5839                    r.append(p.info.name);
5840                }
5841            }
5842        }
5843        if (r != null) {
5844            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
5845        }
5846
5847        N = pkg.instrumentation.size();
5848        r = null;
5849        for (i=0; i<N; i++) {
5850            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
5851            mInstrumentation.remove(a.getComponentName());
5852            if (DEBUG_REMOVE && chatty) {
5853                if (r == null) {
5854                    r = new StringBuilder(256);
5855                } else {
5856                    r.append(' ');
5857                }
5858                r.append(a.info.name);
5859            }
5860        }
5861        if (r != null) {
5862            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
5863        }
5864
5865        r = null;
5866        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
5867            // Only system apps can hold shared libraries.
5868            if (pkg.libraryNames != null) {
5869                for (i=0; i<pkg.libraryNames.size(); i++) {
5870                    String name = pkg.libraryNames.get(i);
5871                    SharedLibraryEntry cur = mSharedLibraries.get(name);
5872                    if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) {
5873                        mSharedLibraries.remove(name);
5874                        if (DEBUG_REMOVE && chatty) {
5875                            if (r == null) {
5876                                r = new StringBuilder(256);
5877                            } else {
5878                                r.append(' ');
5879                            }
5880                            r.append(name);
5881                        }
5882                    }
5883                }
5884            }
5885        }
5886        if (r != null) {
5887            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
5888        }
5889    }
5890
5891    private static final boolean isPackageFilename(String name) {
5892        return name != null && name.endsWith(".apk");
5893    }
5894
5895    private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
5896        for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
5897            if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
5898                return true;
5899            }
5900        }
5901        return false;
5902    }
5903
5904    static final int UPDATE_PERMISSIONS_ALL = 1<<0;
5905    static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
5906    static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
5907
5908    private void updatePermissionsLPw(String changingPkg,
5909            PackageParser.Package pkgInfo, int flags) {
5910        // Make sure there are no dangling permission trees.
5911        Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
5912        while (it.hasNext()) {
5913            final BasePermission bp = it.next();
5914            if (bp.packageSetting == null) {
5915                // We may not yet have parsed the package, so just see if
5916                // we still know about its settings.
5917                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
5918            }
5919            if (bp.packageSetting == null) {
5920                Slog.w(TAG, "Removing dangling permission tree: " + bp.name
5921                        + " from package " + bp.sourcePackage);
5922                it.remove();
5923            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
5924                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
5925                    Slog.i(TAG, "Removing old permission tree: " + bp.name
5926                            + " from package " + bp.sourcePackage);
5927                    flags |= UPDATE_PERMISSIONS_ALL;
5928                    it.remove();
5929                }
5930            }
5931        }
5932
5933        // Make sure all dynamic permissions have been assigned to a package,
5934        // and make sure there are no dangling permissions.
5935        it = mSettings.mPermissions.values().iterator();
5936        while (it.hasNext()) {
5937            final BasePermission bp = it.next();
5938            if (bp.type == BasePermission.TYPE_DYNAMIC) {
5939                if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
5940                        + bp.name + " pkg=" + bp.sourcePackage
5941                        + " info=" + bp.pendingInfo);
5942                if (bp.packageSetting == null && bp.pendingInfo != null) {
5943                    final BasePermission tree = findPermissionTreeLP(bp.name);
5944                    if (tree != null && tree.perm != null) {
5945                        bp.packageSetting = tree.packageSetting;
5946                        bp.perm = new PackageParser.Permission(tree.perm.owner,
5947                                new PermissionInfo(bp.pendingInfo));
5948                        bp.perm.info.packageName = tree.perm.info.packageName;
5949                        bp.perm.info.name = bp.name;
5950                        bp.uid = tree.uid;
5951                    }
5952                }
5953            }
5954            if (bp.packageSetting == null) {
5955                // We may not yet have parsed the package, so just see if
5956                // we still know about its settings.
5957                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
5958            }
5959            if (bp.packageSetting == null) {
5960                Slog.w(TAG, "Removing dangling permission: " + bp.name
5961                        + " from package " + bp.sourcePackage);
5962                it.remove();
5963            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
5964                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
5965                    Slog.i(TAG, "Removing old permission: " + bp.name
5966                            + " from package " + bp.sourcePackage);
5967                    flags |= UPDATE_PERMISSIONS_ALL;
5968                    it.remove();
5969                }
5970            }
5971        }
5972
5973        // Now update the permissions for all packages, in particular
5974        // replace the granted permissions of the system packages.
5975        if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
5976            for (PackageParser.Package pkg : mPackages.values()) {
5977                if (pkg != pkgInfo) {
5978                    grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0);
5979                }
5980            }
5981        }
5982
5983        if (pkgInfo != null) {
5984            grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0);
5985        }
5986    }
5987
5988    private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace) {
5989        final PackageSetting ps = (PackageSetting) pkg.mExtras;
5990        if (ps == null) {
5991            return;
5992        }
5993        final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
5994        HashSet<String> origPermissions = gp.grantedPermissions;
5995        boolean changedPermission = false;
5996
5997        if (replace) {
5998            ps.permissionsFixed = false;
5999            if (gp == ps) {
6000                origPermissions = new HashSet<String>(gp.grantedPermissions);
6001                gp.grantedPermissions.clear();
6002                gp.gids = mGlobalGids;
6003            }
6004        }
6005
6006        if (gp.gids == null) {
6007            gp.gids = mGlobalGids;
6008        }
6009
6010        final int N = pkg.requestedPermissions.size();
6011        for (int i=0; i<N; i++) {
6012            final String name = pkg.requestedPermissions.get(i);
6013            final boolean required = pkg.requestedPermissionsRequired.get(i);
6014            final BasePermission bp = mSettings.mPermissions.get(name);
6015            if (DEBUG_INSTALL) {
6016                if (gp != ps) {
6017                    Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
6018                }
6019            }
6020
6021            if (bp == null || bp.packageSetting == null) {
6022                Slog.w(TAG, "Unknown permission " + name
6023                        + " in package " + pkg.packageName);
6024                continue;
6025            }
6026
6027            final String perm = bp.name;
6028            boolean allowed;
6029            boolean allowedSig = false;
6030            final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
6031            if (level == PermissionInfo.PROTECTION_NORMAL
6032                    || level == PermissionInfo.PROTECTION_DANGEROUS) {
6033                // We grant a normal or dangerous permission if any of the following
6034                // are true:
6035                // 1) The permission is required
6036                // 2) The permission is optional, but was granted in the past
6037                // 3) The permission is optional, but was requested by an
6038                //    app in /system (not /data)
6039                //
6040                // Otherwise, reject the permission.
6041                allowed = (required || origPermissions.contains(perm)
6042                        || (isSystemApp(ps) && !isUpdatedSystemApp(ps)));
6043            } else if (bp.packageSetting == null) {
6044                // This permission is invalid; skip it.
6045                allowed = false;
6046            } else if (level == PermissionInfo.PROTECTION_SIGNATURE) {
6047                allowed = grantSignaturePermission(perm, pkg, bp, origPermissions);
6048                if (allowed) {
6049                    allowedSig = true;
6050                }
6051            } else {
6052                allowed = false;
6053            }
6054            if (DEBUG_INSTALL) {
6055                if (gp != ps) {
6056                    Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
6057                }
6058            }
6059            if (allowed) {
6060                if (!isSystemApp(ps) && ps.permissionsFixed) {
6061                    // If this is an existing, non-system package, then
6062                    // we can't add any new permissions to it.
6063                    if (!allowedSig && !gp.grantedPermissions.contains(perm)) {
6064                        // Except...  if this is a permission that was added
6065                        // to the platform (note: need to only do this when
6066                        // updating the platform).
6067                        allowed = isNewPlatformPermissionForPackage(perm, pkg);
6068                    }
6069                }
6070                if (allowed) {
6071                    if (!gp.grantedPermissions.contains(perm)) {
6072                        changedPermission = true;
6073                        gp.grantedPermissions.add(perm);
6074                        gp.gids = appendInts(gp.gids, bp.gids);
6075                    } else if (!ps.haveGids) {
6076                        gp.gids = appendInts(gp.gids, bp.gids);
6077                    }
6078                } else {
6079                    Slog.w(TAG, "Not granting permission " + perm
6080                            + " to package " + pkg.packageName
6081                            + " because it was previously installed without");
6082                }
6083            } else {
6084                if (gp.grantedPermissions.remove(perm)) {
6085                    changedPermission = true;
6086                    gp.gids = removeInts(gp.gids, bp.gids);
6087                    Slog.i(TAG, "Un-granting permission " + perm
6088                            + " from package " + pkg.packageName
6089                            + " (protectionLevel=" + bp.protectionLevel
6090                            + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
6091                            + ")");
6092                } else {
6093                    Slog.w(TAG, "Not granting permission " + perm
6094                            + " to package " + pkg.packageName
6095                            + " (protectionLevel=" + bp.protectionLevel
6096                            + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
6097                            + ")");
6098                }
6099            }
6100        }
6101
6102        if ((changedPermission || replace) && !ps.permissionsFixed &&
6103                !isSystemApp(ps) || isUpdatedSystemApp(ps)){
6104            // This is the first that we have heard about this package, so the
6105            // permissions we have now selected are fixed until explicitly
6106            // changed.
6107            ps.permissionsFixed = true;
6108        }
6109        ps.haveGids = true;
6110    }
6111
6112    private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
6113        boolean allowed = false;
6114        final int NP = PackageParser.NEW_PERMISSIONS.length;
6115        for (int ip=0; ip<NP; ip++) {
6116            final PackageParser.NewPermissionInfo npi
6117                    = PackageParser.NEW_PERMISSIONS[ip];
6118            if (npi.name.equals(perm)
6119                    && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
6120                allowed = true;
6121                Log.i(TAG, "Auto-granting " + perm + " to old pkg "
6122                        + pkg.packageName);
6123                break;
6124            }
6125        }
6126        return allowed;
6127    }
6128
6129    private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
6130                                          BasePermission bp, HashSet<String> origPermissions) {
6131        boolean allowed;
6132        allowed = (compareSignatures(
6133                bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
6134                        == PackageManager.SIGNATURE_MATCH)
6135                || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
6136                        == PackageManager.SIGNATURE_MATCH);
6137        if (!allowed && (bp.protectionLevel
6138                & PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) {
6139            if (isSystemApp(pkg)) {
6140                // For updated system applications, a system permission
6141                // is granted only if it had been defined by the original application.
6142                if (isUpdatedSystemApp(pkg)) {
6143                    final PackageSetting sysPs = mSettings
6144                            .getDisabledSystemPkgLPr(pkg.packageName);
6145                    final GrantedPermissions origGp = sysPs.sharedUser != null
6146                            ? sysPs.sharedUser : sysPs;
6147
6148                    if (origGp.grantedPermissions.contains(perm)) {
6149                        // If the original was granted this permission, we take
6150                        // that grant decision as read and propagate it to the
6151                        // update.
6152                        allowed = true;
6153                    } else {
6154                        // The system apk may have been updated with an older
6155                        // version of the one on the data partition, but which
6156                        // granted a new system permission that it didn't have
6157                        // before.  In this case we do want to allow the app to
6158                        // now get the new permission if the ancestral apk is
6159                        // privileged to get it.
6160                        if (sysPs.pkg != null && sysPs.isPrivileged()) {
6161                            for (int j=0;
6162                                    j<sysPs.pkg.requestedPermissions.size(); j++) {
6163                                if (perm.equals(
6164                                        sysPs.pkg.requestedPermissions.get(j))) {
6165                                    allowed = true;
6166                                    break;
6167                                }
6168                            }
6169                        }
6170                    }
6171                } else {
6172                    allowed = isPrivilegedApp(pkg);
6173                }
6174            }
6175        }
6176        if (!allowed && (bp.protectionLevel
6177                & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
6178            // For development permissions, a development permission
6179            // is granted only if it was already granted.
6180            allowed = origPermissions.contains(perm);
6181        }
6182        return allowed;
6183    }
6184
6185    final class ActivityIntentResolver
6186            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
6187        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
6188                boolean defaultOnly, int userId) {
6189            if (!sUserManager.exists(userId)) return null;
6190            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
6191            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
6192        }
6193
6194        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
6195                int userId) {
6196            if (!sUserManager.exists(userId)) return null;
6197            mFlags = flags;
6198            return super.queryIntent(intent, resolvedType,
6199                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
6200        }
6201
6202        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
6203                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
6204            if (!sUserManager.exists(userId)) return null;
6205            if (packageActivities == null) {
6206                return null;
6207            }
6208            mFlags = flags;
6209            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
6210            final int N = packageActivities.size();
6211            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
6212                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
6213
6214            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
6215            for (int i = 0; i < N; ++i) {
6216                intentFilters = packageActivities.get(i).intents;
6217                if (intentFilters != null && intentFilters.size() > 0) {
6218                    PackageParser.ActivityIntentInfo[] array =
6219                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
6220                    intentFilters.toArray(array);
6221                    listCut.add(array);
6222                }
6223            }
6224            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
6225        }
6226
6227        public final void addActivity(PackageParser.Activity a, String type) {
6228            final boolean systemApp = isSystemApp(a.info.applicationInfo);
6229            mActivities.put(a.getComponentName(), a);
6230            if (DEBUG_SHOW_INFO)
6231                Log.v(
6232                TAG, "  " + type + " " +
6233                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
6234            if (DEBUG_SHOW_INFO)
6235                Log.v(TAG, "    Class=" + a.info.name);
6236            final int NI = a.intents.size();
6237            for (int j=0; j<NI; j++) {
6238                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
6239                if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) {
6240                    intent.setPriority(0);
6241                    Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity "
6242                            + a.className + " with priority > 0, forcing to 0");
6243                }
6244                if (DEBUG_SHOW_INFO) {
6245                    Log.v(TAG, "    IntentFilter:");
6246                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
6247                }
6248                if (!intent.debugCheck()) {
6249                    Log.w(TAG, "==> For Activity " + a.info.name);
6250                }
6251                addFilter(intent);
6252            }
6253        }
6254
6255        public final void removeActivity(PackageParser.Activity a, String type) {
6256            mActivities.remove(a.getComponentName());
6257            if (DEBUG_SHOW_INFO) {
6258                Log.v(TAG, "  " + type + " "
6259                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
6260                                : a.info.name) + ":");
6261                Log.v(TAG, "    Class=" + a.info.name);
6262            }
6263            final int NI = a.intents.size();
6264            for (int j=0; j<NI; j++) {
6265                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
6266                if (DEBUG_SHOW_INFO) {
6267                    Log.v(TAG, "    IntentFilter:");
6268                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
6269                }
6270                removeFilter(intent);
6271            }
6272        }
6273
6274        @Override
6275        protected boolean allowFilterResult(
6276                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
6277            ActivityInfo filterAi = filter.activity.info;
6278            for (int i=dest.size()-1; i>=0; i--) {
6279                ActivityInfo destAi = dest.get(i).activityInfo;
6280                if (destAi.name == filterAi.name
6281                        && destAi.packageName == filterAi.packageName) {
6282                    return false;
6283                }
6284            }
6285            return true;
6286        }
6287
6288        @Override
6289        protected ActivityIntentInfo[] newArray(int size) {
6290            return new ActivityIntentInfo[size];
6291        }
6292
6293        @Override
6294        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
6295            if (!sUserManager.exists(userId)) return true;
6296            PackageParser.Package p = filter.activity.owner;
6297            if (p != null) {
6298                PackageSetting ps = (PackageSetting)p.mExtras;
6299                if (ps != null) {
6300                    // System apps are never considered stopped for purposes of
6301                    // filtering, because there may be no way for the user to
6302                    // actually re-launch them.
6303                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
6304                            && ps.getStopped(userId);
6305                }
6306            }
6307            return false;
6308        }
6309
6310        @Override
6311        protected boolean isPackageForFilter(String packageName,
6312                PackageParser.ActivityIntentInfo info) {
6313            return packageName.equals(info.activity.owner.packageName);
6314        }
6315
6316        @Override
6317        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
6318                int match, int userId) {
6319            if (!sUserManager.exists(userId)) return null;
6320            if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) {
6321                return null;
6322            }
6323            final PackageParser.Activity activity = info.activity;
6324            if (mSafeMode && (activity.info.applicationInfo.flags
6325                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
6326                return null;
6327            }
6328            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
6329            if (ps == null) {
6330                return null;
6331            }
6332            ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags,
6333                    ps.readUserState(userId), userId);
6334            if (ai == null) {
6335                return null;
6336            }
6337            final ResolveInfo res = new ResolveInfo();
6338            res.activityInfo = ai;
6339            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
6340                res.filter = info;
6341            }
6342            res.priority = info.getPriority();
6343            res.preferredOrder = activity.owner.mPreferredOrder;
6344            //System.out.println("Result: " + res.activityInfo.className +
6345            //                   " = " + res.priority);
6346            res.match = match;
6347            res.isDefault = info.hasDefault;
6348            res.labelRes = info.labelRes;
6349            res.nonLocalizedLabel = info.nonLocalizedLabel;
6350            res.icon = info.icon;
6351            res.system = isSystemApp(res.activityInfo.applicationInfo);
6352            return res;
6353        }
6354
6355        @Override
6356        protected void sortResults(List<ResolveInfo> results) {
6357            Collections.sort(results, mResolvePrioritySorter);
6358        }
6359
6360        @Override
6361        protected void dumpFilter(PrintWriter out, String prefix,
6362                PackageParser.ActivityIntentInfo filter) {
6363            out.print(prefix); out.print(
6364                    Integer.toHexString(System.identityHashCode(filter.activity)));
6365                    out.print(' ');
6366                    filter.activity.printComponentShortName(out);
6367                    out.print(" filter ");
6368                    out.println(Integer.toHexString(System.identityHashCode(filter)));
6369        }
6370
6371//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
6372//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
6373//            final List<ResolveInfo> retList = Lists.newArrayList();
6374//            while (i.hasNext()) {
6375//                final ResolveInfo resolveInfo = i.next();
6376//                if (isEnabledLP(resolveInfo.activityInfo)) {
6377//                    retList.add(resolveInfo);
6378//                }
6379//            }
6380//            return retList;
6381//        }
6382
6383        // Keys are String (activity class name), values are Activity.
6384        private final HashMap<ComponentName, PackageParser.Activity> mActivities
6385                = new HashMap<ComponentName, PackageParser.Activity>();
6386        private int mFlags;
6387    }
6388
6389    private final class ServiceIntentResolver
6390            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
6391        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
6392                boolean defaultOnly, int userId) {
6393            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
6394            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
6395        }
6396
6397        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
6398                int userId) {
6399            if (!sUserManager.exists(userId)) return null;
6400            mFlags = flags;
6401            return super.queryIntent(intent, resolvedType,
6402                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
6403        }
6404
6405        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
6406                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
6407            if (!sUserManager.exists(userId)) return null;
6408            if (packageServices == null) {
6409                return null;
6410            }
6411            mFlags = flags;
6412            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
6413            final int N = packageServices.size();
6414            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
6415                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
6416
6417            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
6418            for (int i = 0; i < N; ++i) {
6419                intentFilters = packageServices.get(i).intents;
6420                if (intentFilters != null && intentFilters.size() > 0) {
6421                    PackageParser.ServiceIntentInfo[] array =
6422                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
6423                    intentFilters.toArray(array);
6424                    listCut.add(array);
6425                }
6426            }
6427            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
6428        }
6429
6430        public final void addService(PackageParser.Service s) {
6431            mServices.put(s.getComponentName(), s);
6432            if (DEBUG_SHOW_INFO) {
6433                Log.v(TAG, "  "
6434                        + (s.info.nonLocalizedLabel != null
6435                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
6436                Log.v(TAG, "    Class=" + s.info.name);
6437            }
6438            final int NI = s.intents.size();
6439            int j;
6440            for (j=0; j<NI; j++) {
6441                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
6442                if (DEBUG_SHOW_INFO) {
6443                    Log.v(TAG, "    IntentFilter:");
6444                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
6445                }
6446                if (!intent.debugCheck()) {
6447                    Log.w(TAG, "==> For Service " + s.info.name);
6448                }
6449                addFilter(intent);
6450            }
6451        }
6452
6453        public final void removeService(PackageParser.Service s) {
6454            mServices.remove(s.getComponentName());
6455            if (DEBUG_SHOW_INFO) {
6456                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
6457                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
6458                Log.v(TAG, "    Class=" + s.info.name);
6459            }
6460            final int NI = s.intents.size();
6461            int j;
6462            for (j=0; j<NI; j++) {
6463                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
6464                if (DEBUG_SHOW_INFO) {
6465                    Log.v(TAG, "    IntentFilter:");
6466                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
6467                }
6468                removeFilter(intent);
6469            }
6470        }
6471
6472        @Override
6473        protected boolean allowFilterResult(
6474                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
6475            ServiceInfo filterSi = filter.service.info;
6476            for (int i=dest.size()-1; i>=0; i--) {
6477                ServiceInfo destAi = dest.get(i).serviceInfo;
6478                if (destAi.name == filterSi.name
6479                        && destAi.packageName == filterSi.packageName) {
6480                    return false;
6481                }
6482            }
6483            return true;
6484        }
6485
6486        @Override
6487        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
6488            return new PackageParser.ServiceIntentInfo[size];
6489        }
6490
6491        @Override
6492        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
6493            if (!sUserManager.exists(userId)) return true;
6494            PackageParser.Package p = filter.service.owner;
6495            if (p != null) {
6496                PackageSetting ps = (PackageSetting)p.mExtras;
6497                if (ps != null) {
6498                    // System apps are never considered stopped for purposes of
6499                    // filtering, because there may be no way for the user to
6500                    // actually re-launch them.
6501                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
6502                            && ps.getStopped(userId);
6503                }
6504            }
6505            return false;
6506        }
6507
6508        @Override
6509        protected boolean isPackageForFilter(String packageName,
6510                PackageParser.ServiceIntentInfo info) {
6511            return packageName.equals(info.service.owner.packageName);
6512        }
6513
6514        @Override
6515        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
6516                int match, int userId) {
6517            if (!sUserManager.exists(userId)) return null;
6518            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
6519            if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) {
6520                return null;
6521            }
6522            final PackageParser.Service service = info.service;
6523            if (mSafeMode && (service.info.applicationInfo.flags
6524                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
6525                return null;
6526            }
6527            PackageSetting ps = (PackageSetting) service.owner.mExtras;
6528            if (ps == null) {
6529                return null;
6530            }
6531            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
6532                    ps.readUserState(userId), userId);
6533            if (si == null) {
6534                return null;
6535            }
6536            final ResolveInfo res = new ResolveInfo();
6537            res.serviceInfo = si;
6538            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
6539                res.filter = filter;
6540            }
6541            res.priority = info.getPriority();
6542            res.preferredOrder = service.owner.mPreferredOrder;
6543            //System.out.println("Result: " + res.activityInfo.className +
6544            //                   " = " + res.priority);
6545            res.match = match;
6546            res.isDefault = info.hasDefault;
6547            res.labelRes = info.labelRes;
6548            res.nonLocalizedLabel = info.nonLocalizedLabel;
6549            res.icon = info.icon;
6550            res.system = isSystemApp(res.serviceInfo.applicationInfo);
6551            return res;
6552        }
6553
6554        @Override
6555        protected void sortResults(List<ResolveInfo> results) {
6556            Collections.sort(results, mResolvePrioritySorter);
6557        }
6558
6559        @Override
6560        protected void dumpFilter(PrintWriter out, String prefix,
6561                PackageParser.ServiceIntentInfo filter) {
6562            out.print(prefix); out.print(
6563                    Integer.toHexString(System.identityHashCode(filter.service)));
6564                    out.print(' ');
6565                    filter.service.printComponentShortName(out);
6566                    out.print(" filter ");
6567                    out.println(Integer.toHexString(System.identityHashCode(filter)));
6568        }
6569
6570//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
6571//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
6572//            final List<ResolveInfo> retList = Lists.newArrayList();
6573//            while (i.hasNext()) {
6574//                final ResolveInfo resolveInfo = (ResolveInfo) i;
6575//                if (isEnabledLP(resolveInfo.serviceInfo)) {
6576//                    retList.add(resolveInfo);
6577//                }
6578//            }
6579//            return retList;
6580//        }
6581
6582        // Keys are String (activity class name), values are Activity.
6583        private final HashMap<ComponentName, PackageParser.Service> mServices
6584                = new HashMap<ComponentName, PackageParser.Service>();
6585        private int mFlags;
6586    };
6587
6588    private final class ProviderIntentResolver
6589            extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
6590        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
6591                boolean defaultOnly, int userId) {
6592            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
6593            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
6594        }
6595
6596        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
6597                int userId) {
6598            if (!sUserManager.exists(userId))
6599                return null;
6600            mFlags = flags;
6601            return super.queryIntent(intent, resolvedType,
6602                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
6603        }
6604
6605        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
6606                int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
6607            if (!sUserManager.exists(userId))
6608                return null;
6609            if (packageProviders == null) {
6610                return null;
6611            }
6612            mFlags = flags;
6613            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
6614            final int N = packageProviders.size();
6615            ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
6616                    new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
6617
6618            ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
6619            for (int i = 0; i < N; ++i) {
6620                intentFilters = packageProviders.get(i).intents;
6621                if (intentFilters != null && intentFilters.size() > 0) {
6622                    PackageParser.ProviderIntentInfo[] array =
6623                            new PackageParser.ProviderIntentInfo[intentFilters.size()];
6624                    intentFilters.toArray(array);
6625                    listCut.add(array);
6626                }
6627            }
6628            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
6629        }
6630
6631        public final void addProvider(PackageParser.Provider p) {
6632            if (mProviders.containsKey(p.getComponentName())) {
6633                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
6634                return;
6635            }
6636
6637            mProviders.put(p.getComponentName(), p);
6638            if (DEBUG_SHOW_INFO) {
6639                Log.v(TAG, "  "
6640                        + (p.info.nonLocalizedLabel != null
6641                                ? p.info.nonLocalizedLabel : p.info.name) + ":");
6642                Log.v(TAG, "    Class=" + p.info.name);
6643            }
6644            final int NI = p.intents.size();
6645            int j;
6646            for (j = 0; j < NI; j++) {
6647                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
6648                if (DEBUG_SHOW_INFO) {
6649                    Log.v(TAG, "    IntentFilter:");
6650                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
6651                }
6652                if (!intent.debugCheck()) {
6653                    Log.w(TAG, "==> For Provider " + p.info.name);
6654                }
6655                addFilter(intent);
6656            }
6657        }
6658
6659        public final void removeProvider(PackageParser.Provider p) {
6660            mProviders.remove(p.getComponentName());
6661            if (DEBUG_SHOW_INFO) {
6662                Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
6663                        ? p.info.nonLocalizedLabel : p.info.name) + ":");
6664                Log.v(TAG, "    Class=" + p.info.name);
6665            }
6666            final int NI = p.intents.size();
6667            int j;
6668            for (j = 0; j < NI; j++) {
6669                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
6670                if (DEBUG_SHOW_INFO) {
6671                    Log.v(TAG, "    IntentFilter:");
6672                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
6673                }
6674                removeFilter(intent);
6675            }
6676        }
6677
6678        @Override
6679        protected boolean allowFilterResult(
6680                PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
6681            ProviderInfo filterPi = filter.provider.info;
6682            for (int i = dest.size() - 1; i >= 0; i--) {
6683                ProviderInfo destPi = dest.get(i).providerInfo;
6684                if (destPi.name == filterPi.name
6685                        && destPi.packageName == filterPi.packageName) {
6686                    return false;
6687                }
6688            }
6689            return true;
6690        }
6691
6692        @Override
6693        protected PackageParser.ProviderIntentInfo[] newArray(int size) {
6694            return new PackageParser.ProviderIntentInfo[size];
6695        }
6696
6697        @Override
6698        protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
6699            if (!sUserManager.exists(userId))
6700                return true;
6701            PackageParser.Package p = filter.provider.owner;
6702            if (p != null) {
6703                PackageSetting ps = (PackageSetting) p.mExtras;
6704                if (ps != null) {
6705                    // System apps are never considered stopped for purposes of
6706                    // filtering, because there may be no way for the user to
6707                    // actually re-launch them.
6708                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
6709                            && ps.getStopped(userId);
6710                }
6711            }
6712            return false;
6713        }
6714
6715        @Override
6716        protected boolean isPackageForFilter(String packageName,
6717                PackageParser.ProviderIntentInfo info) {
6718            return packageName.equals(info.provider.owner.packageName);
6719        }
6720
6721        @Override
6722        protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
6723                int match, int userId) {
6724            if (!sUserManager.exists(userId))
6725                return null;
6726            final PackageParser.ProviderIntentInfo info = filter;
6727            if (!mSettings.isEnabledLPr(info.provider.info, mFlags, userId)) {
6728                return null;
6729            }
6730            final PackageParser.Provider provider = info.provider;
6731            if (mSafeMode && (provider.info.applicationInfo.flags
6732                    & ApplicationInfo.FLAG_SYSTEM) == 0) {
6733                return null;
6734            }
6735            PackageSetting ps = (PackageSetting) provider.owner.mExtras;
6736            if (ps == null) {
6737                return null;
6738            }
6739            ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
6740                    ps.readUserState(userId), userId);
6741            if (pi == null) {
6742                return null;
6743            }
6744            final ResolveInfo res = new ResolveInfo();
6745            res.providerInfo = pi;
6746            if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
6747                res.filter = filter;
6748            }
6749            res.priority = info.getPriority();
6750            res.preferredOrder = provider.owner.mPreferredOrder;
6751            res.match = match;
6752            res.isDefault = info.hasDefault;
6753            res.labelRes = info.labelRes;
6754            res.nonLocalizedLabel = info.nonLocalizedLabel;
6755            res.icon = info.icon;
6756            res.system = isSystemApp(res.providerInfo.applicationInfo);
6757            return res;
6758        }
6759
6760        @Override
6761        protected void sortResults(List<ResolveInfo> results) {
6762            Collections.sort(results, mResolvePrioritySorter);
6763        }
6764
6765        @Override
6766        protected void dumpFilter(PrintWriter out, String prefix,
6767                PackageParser.ProviderIntentInfo filter) {
6768            out.print(prefix);
6769            out.print(
6770                    Integer.toHexString(System.identityHashCode(filter.provider)));
6771            out.print(' ');
6772            filter.provider.printComponentShortName(out);
6773            out.print(" filter ");
6774            out.println(Integer.toHexString(System.identityHashCode(filter)));
6775        }
6776
6777        private final HashMap<ComponentName, PackageParser.Provider> mProviders
6778                = new HashMap<ComponentName, PackageParser.Provider>();
6779        private int mFlags;
6780    };
6781
6782    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
6783            new Comparator<ResolveInfo>() {
6784        public int compare(ResolveInfo r1, ResolveInfo r2) {
6785            int v1 = r1.priority;
6786            int v2 = r2.priority;
6787            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
6788            if (v1 != v2) {
6789                return (v1 > v2) ? -1 : 1;
6790            }
6791            v1 = r1.preferredOrder;
6792            v2 = r2.preferredOrder;
6793            if (v1 != v2) {
6794                return (v1 > v2) ? -1 : 1;
6795            }
6796            if (r1.isDefault != r2.isDefault) {
6797                return r1.isDefault ? -1 : 1;
6798            }
6799            v1 = r1.match;
6800            v2 = r2.match;
6801            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
6802            if (v1 != v2) {
6803                return (v1 > v2) ? -1 : 1;
6804            }
6805            if (r1.system != r2.system) {
6806                return r1.system ? -1 : 1;
6807            }
6808            return 0;
6809        }
6810    };
6811
6812    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
6813            new Comparator<ProviderInfo>() {
6814        public int compare(ProviderInfo p1, ProviderInfo p2) {
6815            final int v1 = p1.initOrder;
6816            final int v2 = p2.initOrder;
6817            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
6818        }
6819    };
6820
6821    static final void sendPackageBroadcast(String action, String pkg,
6822            Bundle extras, String targetPkg, IIntentReceiver finishedReceiver,
6823            int[] userIds) {
6824        IActivityManager am = ActivityManagerNative.getDefault();
6825        if (am != null) {
6826            try {
6827                if (userIds == null) {
6828                    userIds = am.getRunningUserIds();
6829                }
6830                for (int id : userIds) {
6831                    final Intent intent = new Intent(action,
6832                            pkg != null ? Uri.fromParts("package", pkg, null) : null);
6833                    if (extras != null) {
6834                        intent.putExtras(extras);
6835                    }
6836                    if (targetPkg != null) {
6837                        intent.setPackage(targetPkg);
6838                    }
6839                    // Modify the UID when posting to other users
6840                    int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
6841                    if (uid > 0 && UserHandle.getUserId(uid) != id) {
6842                        uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
6843                        intent.putExtra(Intent.EXTRA_UID, uid);
6844                    }
6845                    intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
6846                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
6847                    if (DEBUG_BROADCASTS) {
6848                        RuntimeException here = new RuntimeException("here");
6849                        here.fillInStackTrace();
6850                        Slog.d(TAG, "Sending to user " + id + ": "
6851                                + intent.toShortString(false, true, false, false)
6852                                + " " + intent.getExtras(), here);
6853                    }
6854                    am.broadcastIntent(null, intent, null, finishedReceiver,
6855                            0, null, null, null, android.app.AppOpsManager.OP_NONE,
6856                            finishedReceiver != null, false, id);
6857                }
6858            } catch (RemoteException ex) {
6859            }
6860        }
6861    }
6862
6863    /**
6864     * Check if the external storage media is available. This is true if there
6865     * is a mounted external storage medium or if the external storage is
6866     * emulated.
6867     */
6868    private boolean isExternalMediaAvailable() {
6869        return mMediaMounted || Environment.isExternalStorageEmulated();
6870    }
6871
6872    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
6873        // writer
6874        synchronized (mPackages) {
6875            if (!isExternalMediaAvailable()) {
6876                // If the external storage is no longer mounted at this point,
6877                // the caller may not have been able to delete all of this
6878                // packages files and can not delete any more.  Bail.
6879                return null;
6880            }
6881            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
6882            if (lastPackage != null) {
6883                pkgs.remove(lastPackage);
6884            }
6885            if (pkgs.size() > 0) {
6886                return pkgs.get(0);
6887            }
6888        }
6889        return null;
6890    }
6891
6892    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
6893        if (false) {
6894            RuntimeException here = new RuntimeException("here");
6895            here.fillInStackTrace();
6896            Slog.d(TAG, "Schedule cleaning " + packageName + " user=" + userId
6897                    + " andCode=" + andCode, here);
6898        }
6899        mHandler.sendMessage(mHandler.obtainMessage(START_CLEANING_PACKAGE,
6900                userId, andCode ? 1 : 0, packageName));
6901    }
6902
6903    void startCleaningPackages() {
6904        // reader
6905        synchronized (mPackages) {
6906            if (!isExternalMediaAvailable()) {
6907                return;
6908            }
6909            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
6910                return;
6911            }
6912        }
6913        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
6914        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
6915        IActivityManager am = ActivityManagerNative.getDefault();
6916        if (am != null) {
6917            try {
6918                am.startService(null, intent, null, UserHandle.USER_OWNER);
6919            } catch (RemoteException e) {
6920            }
6921        }
6922    }
6923
6924    private final class AppDirObserver extends FileObserver {
6925        public AppDirObserver(String path, int mask, boolean isrom, boolean isPrivileged) {
6926            super(path, mask);
6927            mRootDir = path;
6928            mIsRom = isrom;
6929            mIsPrivileged = isPrivileged;
6930        }
6931
6932        public void onEvent(int event, String path) {
6933            String removedPackage = null;
6934            int removedAppId = -1;
6935            int[] removedUsers = null;
6936            String addedPackage = null;
6937            int addedAppId = -1;
6938            int[] addedUsers = null;
6939
6940            // TODO post a message to the handler to obtain serial ordering
6941            synchronized (mInstallLock) {
6942                String fullPathStr = null;
6943                File fullPath = null;
6944                if (path != null) {
6945                    fullPath = new File(mRootDir, path);
6946                    fullPathStr = fullPath.getPath();
6947                }
6948
6949                if (DEBUG_APP_DIR_OBSERVER)
6950                    Log.v(TAG, "File " + fullPathStr + " changed: " + Integer.toHexString(event));
6951
6952                if (!isPackageFilename(path)) {
6953                    if (DEBUG_APP_DIR_OBSERVER)
6954                        Log.v(TAG, "Ignoring change of non-package file: " + fullPathStr);
6955                    return;
6956                }
6957
6958                // Ignore packages that are being installed or
6959                // have just been installed.
6960                if (ignoreCodePath(fullPathStr)) {
6961                    return;
6962                }
6963                PackageParser.Package p = null;
6964                PackageSetting ps = null;
6965                // reader
6966                synchronized (mPackages) {
6967                    p = mAppDirs.get(fullPathStr);
6968                    if (p != null) {
6969                        ps = mSettings.mPackages.get(p.applicationInfo.packageName);
6970                        if (ps != null) {
6971                            removedUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
6972                        } else {
6973                            removedUsers = sUserManager.getUserIds();
6974                        }
6975                    }
6976                    addedUsers = sUserManager.getUserIds();
6977                }
6978                if ((event&REMOVE_EVENTS) != 0) {
6979                    if (ps != null) {
6980                        if (DEBUG_REMOVE) Slog.d(TAG, "Package disappeared: " + ps);
6981                        removePackageLI(ps, true);
6982                        removedPackage = ps.name;
6983                        removedAppId = ps.appId;
6984                    }
6985                }
6986
6987                if ((event&ADD_EVENTS) != 0) {
6988                    if (p == null) {
6989                        if (DEBUG_INSTALL) Slog.d(TAG, "New file appeared: " + fullPath);
6990                        int flags = PackageParser.PARSE_CHATTY | PackageParser.PARSE_MUST_BE_APK;
6991                        if (mIsRom) {
6992                            flags |= PackageParser.PARSE_IS_SYSTEM
6993                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
6994                            if (mIsPrivileged) {
6995                                flags |= PackageParser.PARSE_IS_PRIVILEGED;
6996                            }
6997                        }
6998                        p = scanPackageLI(fullPath, flags,
6999                                SCAN_MONITOR | SCAN_NO_PATHS | SCAN_UPDATE_TIME,
7000                                System.currentTimeMillis(), UserHandle.ALL);
7001                        if (p != null) {
7002                            /*
7003                             * TODO this seems dangerous as the package may have
7004                             * changed since we last acquired the mPackages
7005                             * lock.
7006                             */
7007                            // writer
7008                            synchronized (mPackages) {
7009                                updatePermissionsLPw(p.packageName, p,
7010                                        p.permissions.size() > 0 ? UPDATE_PERMISSIONS_ALL : 0);
7011                            }
7012                            addedPackage = p.applicationInfo.packageName;
7013                            addedAppId = UserHandle.getAppId(p.applicationInfo.uid);
7014                        }
7015                    }
7016                }
7017
7018                // reader
7019                synchronized (mPackages) {
7020                    mSettings.writeLPr();
7021                }
7022            }
7023
7024            if (removedPackage != null) {
7025                Bundle extras = new Bundle(1);
7026                extras.putInt(Intent.EXTRA_UID, removedAppId);
7027                extras.putBoolean(Intent.EXTRA_DATA_REMOVED, false);
7028                sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
7029                        extras, null, null, removedUsers);
7030            }
7031            if (addedPackage != null) {
7032                Bundle extras = new Bundle(1);
7033                extras.putInt(Intent.EXTRA_UID, addedAppId);
7034                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, addedPackage,
7035                        extras, null, null, addedUsers);
7036            }
7037        }
7038
7039        private final String mRootDir;
7040        private final boolean mIsRom;
7041        private final boolean mIsPrivileged;
7042    }
7043
7044    /*
7045     * The old-style observer methods all just trampoline to the newer signature with
7046     * expanded install observer API.  The older API continues to work but does not
7047     * supply the additional details of the Observer2 API.
7048     */
7049
7050    /* Called when a downloaded package installation has been confirmed by the user */
7051    public void installPackage(
7052            final Uri packageURI, final IPackageInstallObserver observer, final int flags) {
7053        installPackageEtc(packageURI, observer, null, flags, null);
7054    }
7055
7056    /* Called when a downloaded package installation has been confirmed by the user */
7057    public void installPackage(
7058            final Uri packageURI, final IPackageInstallObserver observer, final int flags,
7059            final String installerPackageName) {
7060        installPackageWithVerificationEtc(packageURI, observer, null, flags,
7061                installerPackageName, null, null, null);
7062    }
7063
7064    @Override
7065    public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
7066            int flags, String installerPackageName, Uri verificationURI,
7067            ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
7068        VerificationParams verificationParams = new VerificationParams(verificationURI, null, null,
7069                VerificationParams.NO_UID, manifestDigest);
7070        installPackageWithVerificationAndEncryptionEtc(packageURI, observer, null, flags,
7071                installerPackageName, verificationParams, encryptionParams);
7072    }
7073
7074    public void installPackageWithVerificationAndEncryption(Uri packageURI,
7075            IPackageInstallObserver observer, int flags, String installerPackageName,
7076            VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
7077        installPackageWithVerificationAndEncryptionEtc(packageURI, observer, null, flags,
7078                installerPackageName, verificationParams, encryptionParams);
7079    }
7080
7081    /*
7082     * And here are the "live" versions that take both observer arguments
7083     */
7084    public void installPackageEtc(
7085            final Uri packageURI, final IPackageInstallObserver observer,
7086            IPackageInstallObserver2 observer2, final int flags) {
7087        installPackageEtc(packageURI, observer, observer2, flags, null);
7088    }
7089
7090    public void installPackageEtc(
7091            final Uri packageURI, final IPackageInstallObserver observer,
7092            final IPackageInstallObserver2 observer2, final int flags,
7093            final String installerPackageName) {
7094        installPackageWithVerificationEtc(packageURI, observer, observer2, flags,
7095                installerPackageName, null, null, null);
7096    }
7097
7098    @Override
7099    public void installPackageWithVerificationEtc(Uri packageURI, IPackageInstallObserver observer,
7100            IPackageInstallObserver2 observer2,
7101            int flags, String installerPackageName, Uri verificationURI,
7102            ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
7103        VerificationParams verificationParams = new VerificationParams(verificationURI, null, null,
7104                VerificationParams.NO_UID, manifestDigest);
7105        installPackageWithVerificationAndEncryptionEtc(packageURI, observer, observer2, flags,
7106                installerPackageName, verificationParams, encryptionParams);
7107    }
7108
7109    /*
7110     * All of the installPackage...*() methods redirect to this one for the master implementation
7111     */
7112    public void installPackageWithVerificationAndEncryptionEtc(Uri packageURI,
7113            IPackageInstallObserver observer, IPackageInstallObserver2 observer2,
7114            int flags, String installerPackageName,
7115            VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
7116        if (observer == null && observer2 == null) {
7117            throw new IllegalArgumentException("No install observer supplied");
7118        }
7119        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
7120                null);
7121
7122        final int uid = Binder.getCallingUid();
7123        if (isUserRestricted(UserHandle.getUserId(uid), UserManager.DISALLOW_INSTALL_APPS)) {
7124            try {
7125                if (observer != null) {
7126                    observer.packageInstalled("", PackageManager.INSTALL_FAILED_USER_RESTRICTED);
7127                }
7128                if (observer2 != null) {
7129                    observer2.packageInstalled("", null, PackageManager.INSTALL_FAILED_USER_RESTRICTED);
7130                }
7131            } catch (RemoteException re) {
7132            }
7133            return;
7134        }
7135
7136        UserHandle user;
7137        if ((flags&PackageManager.INSTALL_ALL_USERS) != 0) {
7138            user = UserHandle.ALL;
7139        } else {
7140            user = new UserHandle(UserHandle.getUserId(uid));
7141        }
7142
7143        final int filteredFlags;
7144
7145        if (uid == Process.SHELL_UID || uid == 0) {
7146            if (DEBUG_INSTALL) {
7147                Slog.v(TAG, "Install from ADB");
7148            }
7149            filteredFlags = flags | PackageManager.INSTALL_FROM_ADB;
7150        } else {
7151            filteredFlags = flags & ~PackageManager.INSTALL_FROM_ADB;
7152        }
7153
7154        verificationParams.setInstallerUid(uid);
7155
7156        final Message msg = mHandler.obtainMessage(INIT_COPY);
7157        msg.obj = new InstallParams(packageURI, observer, observer2, filteredFlags,
7158                installerPackageName, verificationParams, encryptionParams, user);
7159        mHandler.sendMessage(msg);
7160    }
7161
7162    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId) {
7163        Bundle extras = new Bundle(1);
7164        extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId));
7165
7166        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
7167                packageName, extras, null, null, new int[] {userId});
7168        try {
7169            IActivityManager am = ActivityManagerNative.getDefault();
7170            final boolean isSystem =
7171                    isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
7172            if (isSystem && am.isUserRunning(userId, false)) {
7173                // The just-installed/enabled app is bundled on the system, so presumed
7174                // to be able to run automatically without needing an explicit launch.
7175                // Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
7176                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED)
7177                        .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
7178                        .setPackage(packageName);
7179                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
7180                        android.app.AppOpsManager.OP_NONE, false, false, userId);
7181            }
7182        } catch (RemoteException e) {
7183            // shouldn't happen
7184            Slog.w(TAG, "Unable to bootstrap installed package", e);
7185        }
7186    }
7187
7188    @Override
7189    public boolean setApplicationBlockedSettingAsUser(String packageName, boolean blocked,
7190            int userId) {
7191        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
7192        PackageSetting pkgSetting;
7193        final int uid = Binder.getCallingUid();
7194        if (UserHandle.getUserId(uid) != userId) {
7195            mContext.enforceCallingOrSelfPermission(
7196                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
7197                    "setApplicationBlockedSetting for user " + userId);
7198        }
7199
7200        if (blocked && isPackageDeviceAdmin(packageName, userId)) {
7201            Slog.w(TAG, "Not blocking package " + packageName + ": has active device admin");
7202            return false;
7203        }
7204
7205        long callingId = Binder.clearCallingIdentity();
7206        try {
7207            boolean sendAdded = false;
7208            boolean sendRemoved = false;
7209            // writer
7210            synchronized (mPackages) {
7211                pkgSetting = mSettings.mPackages.get(packageName);
7212                if (pkgSetting == null) {
7213                    return false;
7214                }
7215                if (pkgSetting.getBlocked(userId) != blocked) {
7216                    pkgSetting.setBlocked(blocked, userId);
7217                    mSettings.writePackageRestrictionsLPr(userId);
7218                    if (blocked) {
7219                        sendRemoved = true;
7220                    } else {
7221                        sendAdded = true;
7222                    }
7223                }
7224            }
7225            if (sendAdded) {
7226                sendPackageAddedForUser(packageName, pkgSetting, userId);
7227                return true;
7228            }
7229            if (sendRemoved) {
7230                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
7231                        "blocking pkg");
7232                sendPackageBlockedForUser(packageName, pkgSetting, userId);
7233            }
7234        } finally {
7235            Binder.restoreCallingIdentity(callingId);
7236        }
7237        return false;
7238    }
7239
7240    private void sendPackageBlockedForUser(String packageName, PackageSetting pkgSetting,
7241            int userId) {
7242        final PackageRemovedInfo info = new PackageRemovedInfo();
7243        info.removedPackage = packageName;
7244        info.removedUsers = new int[] {userId};
7245        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
7246        info.sendBroadcast(false, false, false);
7247    }
7248
7249    /**
7250     * Returns true if application is not found or there was an error. Otherwise it returns
7251     * the blocked state of the package for the given user.
7252     */
7253    @Override
7254    public boolean getApplicationBlockedSettingAsUser(String packageName, int userId) {
7255        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
7256        PackageSetting pkgSetting;
7257        final int uid = Binder.getCallingUid();
7258        if (UserHandle.getUserId(uid) != userId) {
7259            mContext.enforceCallingPermission(
7260                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
7261                    "getApplicationBlocked for user " + userId);
7262        }
7263        long callingId = Binder.clearCallingIdentity();
7264        try {
7265            // writer
7266            synchronized (mPackages) {
7267                pkgSetting = mSettings.mPackages.get(packageName);
7268                if (pkgSetting == null) {
7269                    return true;
7270                }
7271                return pkgSetting.getBlocked(userId);
7272            }
7273        } finally {
7274            Binder.restoreCallingIdentity(callingId);
7275        }
7276    }
7277
7278    /**
7279     * @hide
7280     */
7281    @Override
7282    public int installExistingPackageAsUser(String packageName, int userId) {
7283        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
7284                null);
7285        PackageSetting pkgSetting;
7286        final int uid = Binder.getCallingUid();
7287        if (UserHandle.getUserId(uid) != userId) {
7288            mContext.enforceCallingPermission(
7289                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
7290                    "installExistingPackage for user " + userId);
7291        }
7292        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
7293            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
7294        }
7295
7296        long callingId = Binder.clearCallingIdentity();
7297        try {
7298            boolean sendAdded = false;
7299            Bundle extras = new Bundle(1);
7300
7301            // writer
7302            synchronized (mPackages) {
7303                pkgSetting = mSettings.mPackages.get(packageName);
7304                if (pkgSetting == null) {
7305                    return PackageManager.INSTALL_FAILED_INVALID_URI;
7306                }
7307                if (!pkgSetting.getInstalled(userId)) {
7308                    pkgSetting.setInstalled(true, userId);
7309                    pkgSetting.setBlocked(false, userId);
7310                    mSettings.writePackageRestrictionsLPr(userId);
7311                    sendAdded = true;
7312                }
7313            }
7314
7315            if (sendAdded) {
7316                sendPackageAddedForUser(packageName, pkgSetting, userId);
7317            }
7318        } finally {
7319            Binder.restoreCallingIdentity(callingId);
7320        }
7321
7322        return PackageManager.INSTALL_SUCCEEDED;
7323    }
7324
7325    private boolean isUserRestricted(int userId, String restrictionKey) {
7326        Bundle restrictions = sUserManager.getUserRestrictions(userId);
7327        if (restrictions.getBoolean(restrictionKey, false)) {
7328            Log.w(TAG, "User is restricted: " + restrictionKey);
7329            return true;
7330        }
7331        return false;
7332    }
7333
7334    @Override
7335    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
7336        mContext.enforceCallingOrSelfPermission(
7337                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
7338                "Only package verification agents can verify applications");
7339
7340        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
7341        final PackageVerificationResponse response = new PackageVerificationResponse(
7342                verificationCode, Binder.getCallingUid());
7343        msg.arg1 = id;
7344        msg.obj = response;
7345        mHandler.sendMessage(msg);
7346    }
7347
7348    @Override
7349    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
7350            long millisecondsToDelay) {
7351        mContext.enforceCallingOrSelfPermission(
7352                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
7353                "Only package verification agents can extend verification timeouts");
7354
7355        final PackageVerificationState state = mPendingVerification.get(id);
7356        final PackageVerificationResponse response = new PackageVerificationResponse(
7357                verificationCodeAtTimeout, Binder.getCallingUid());
7358
7359        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
7360            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
7361        }
7362        if (millisecondsToDelay < 0) {
7363            millisecondsToDelay = 0;
7364        }
7365        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
7366                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
7367            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
7368        }
7369
7370        if ((state != null) && !state.timeoutExtended()) {
7371            state.extendTimeout();
7372
7373            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
7374            msg.arg1 = id;
7375            msg.obj = response;
7376            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
7377        }
7378    }
7379
7380    private void broadcastPackageVerified(int verificationId, Uri packageUri,
7381            int verificationCode, UserHandle user) {
7382        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
7383        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
7384        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
7385        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
7386        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
7387
7388        mContext.sendBroadcastAsUser(intent, user,
7389                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
7390    }
7391
7392    private ComponentName matchComponentForVerifier(String packageName,
7393            List<ResolveInfo> receivers) {
7394        ActivityInfo targetReceiver = null;
7395
7396        final int NR = receivers.size();
7397        for (int i = 0; i < NR; i++) {
7398            final ResolveInfo info = receivers.get(i);
7399            if (info.activityInfo == null) {
7400                continue;
7401            }
7402
7403            if (packageName.equals(info.activityInfo.packageName)) {
7404                targetReceiver = info.activityInfo;
7405                break;
7406            }
7407        }
7408
7409        if (targetReceiver == null) {
7410            return null;
7411        }
7412
7413        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
7414    }
7415
7416    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
7417            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
7418        if (pkgInfo.verifiers.length == 0) {
7419            return null;
7420        }
7421
7422        final int N = pkgInfo.verifiers.length;
7423        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
7424        for (int i = 0; i < N; i++) {
7425            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
7426
7427            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
7428                    receivers);
7429            if (comp == null) {
7430                continue;
7431            }
7432
7433            final int verifierUid = getUidForVerifier(verifierInfo);
7434            if (verifierUid == -1) {
7435                continue;
7436            }
7437
7438            if (DEBUG_VERIFY) {
7439                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
7440                        + " with the correct signature");
7441            }
7442            sufficientVerifiers.add(comp);
7443            verificationState.addSufficientVerifier(verifierUid);
7444        }
7445
7446        return sufficientVerifiers;
7447    }
7448
7449    private int getUidForVerifier(VerifierInfo verifierInfo) {
7450        synchronized (mPackages) {
7451            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
7452            if (pkg == null) {
7453                return -1;
7454            } else if (pkg.mSignatures.length != 1) {
7455                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
7456                        + " has more than one signature; ignoring");
7457                return -1;
7458            }
7459
7460            /*
7461             * If the public key of the package's signature does not match
7462             * our expected public key, then this is a different package and
7463             * we should skip.
7464             */
7465
7466            final byte[] expectedPublicKey;
7467            try {
7468                final Signature verifierSig = pkg.mSignatures[0];
7469                final PublicKey publicKey = verifierSig.getPublicKey();
7470                expectedPublicKey = publicKey.getEncoded();
7471            } catch (CertificateException e) {
7472                return -1;
7473            }
7474
7475            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
7476
7477            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
7478                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
7479                        + " does not have the expected public key; ignoring");
7480                return -1;
7481            }
7482
7483            return pkg.applicationInfo.uid;
7484        }
7485    }
7486
7487    public void finishPackageInstall(int token) {
7488        enforceSystemOrRoot("Only the system is allowed to finish installs");
7489
7490        if (DEBUG_INSTALL) {
7491            Slog.v(TAG, "BM finishing package install for " + token);
7492        }
7493
7494        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
7495        mHandler.sendMessage(msg);
7496    }
7497
7498    /**
7499     * Get the verification agent timeout.
7500     *
7501     * @return verification timeout in milliseconds
7502     */
7503    private long getVerificationTimeout() {
7504        return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
7505                android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
7506                DEFAULT_VERIFICATION_TIMEOUT);
7507    }
7508
7509    /**
7510     * Get the default verification agent response code.
7511     *
7512     * @return default verification response code
7513     */
7514    private int getDefaultVerificationResponse() {
7515        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
7516                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
7517                DEFAULT_VERIFICATION_RESPONSE);
7518    }
7519
7520    /**
7521     * Check whether or not package verification has been enabled.
7522     *
7523     * @return true if verification should be performed
7524     */
7525    private boolean isVerificationEnabled(int flags) {
7526        if (!DEFAULT_VERIFY_ENABLE) {
7527            return false;
7528        }
7529
7530        // Check if installing from ADB
7531        if ((flags & PackageManager.INSTALL_FROM_ADB) != 0) {
7532            // Do not run verification in a test harness environment
7533            if (ActivityManager.isRunningInTestHarness()) {
7534                return false;
7535            }
7536            // Check if the developer does not want package verification for ADB installs
7537            if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
7538                    android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
7539                return false;
7540            }
7541        }
7542
7543        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
7544                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
7545    }
7546
7547    /**
7548     * Get the "allow unknown sources" setting.
7549     *
7550     * @return the current "allow unknown sources" setting
7551     */
7552    private int getUnknownSourcesSettings() {
7553        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
7554                android.provider.Settings.Global.INSTALL_NON_MARKET_APPS,
7555                -1);
7556    }
7557
7558    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
7559        final int uid = Binder.getCallingUid();
7560        // writer
7561        synchronized (mPackages) {
7562            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
7563            if (targetPackageSetting == null) {
7564                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
7565            }
7566
7567            PackageSetting installerPackageSetting;
7568            if (installerPackageName != null) {
7569                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
7570                if (installerPackageSetting == null) {
7571                    throw new IllegalArgumentException("Unknown installer package: "
7572                            + installerPackageName);
7573                }
7574            } else {
7575                installerPackageSetting = null;
7576            }
7577
7578            Signature[] callerSignature;
7579            Object obj = mSettings.getUserIdLPr(uid);
7580            if (obj != null) {
7581                if (obj instanceof SharedUserSetting) {
7582                    callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
7583                } else if (obj instanceof PackageSetting) {
7584                    callerSignature = ((PackageSetting)obj).signatures.mSignatures;
7585                } else {
7586                    throw new SecurityException("Bad object " + obj + " for uid " + uid);
7587                }
7588            } else {
7589                throw new SecurityException("Unknown calling uid " + uid);
7590            }
7591
7592            // Verify: can't set installerPackageName to a package that is
7593            // not signed with the same cert as the caller.
7594            if (installerPackageSetting != null) {
7595                if (compareSignatures(callerSignature,
7596                        installerPackageSetting.signatures.mSignatures)
7597                        != PackageManager.SIGNATURE_MATCH) {
7598                    throw new SecurityException(
7599                            "Caller does not have same cert as new installer package "
7600                            + installerPackageName);
7601                }
7602            }
7603
7604            // Verify: if target already has an installer package, it must
7605            // be signed with the same cert as the caller.
7606            if (targetPackageSetting.installerPackageName != null) {
7607                PackageSetting setting = mSettings.mPackages.get(
7608                        targetPackageSetting.installerPackageName);
7609                // If the currently set package isn't valid, then it's always
7610                // okay to change it.
7611                if (setting != null) {
7612                    if (compareSignatures(callerSignature,
7613                            setting.signatures.mSignatures)
7614                            != PackageManager.SIGNATURE_MATCH) {
7615                        throw new SecurityException(
7616                                "Caller does not have same cert as old installer package "
7617                                + targetPackageSetting.installerPackageName);
7618                    }
7619                }
7620            }
7621
7622            // Okay!
7623            targetPackageSetting.installerPackageName = installerPackageName;
7624            scheduleWriteSettingsLocked();
7625        }
7626    }
7627
7628    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
7629        // Queue up an async operation since the package installation may take a little while.
7630        mHandler.post(new Runnable() {
7631            public void run() {
7632                mHandler.removeCallbacks(this);
7633                 // Result object to be returned
7634                PackageInstalledInfo res = new PackageInstalledInfo();
7635                res.returnCode = currentStatus;
7636                res.uid = -1;
7637                res.pkg = null;
7638                res.removedInfo = new PackageRemovedInfo();
7639                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
7640                    args.doPreInstall(res.returnCode);
7641                    synchronized (mInstallLock) {
7642                        installPackageLI(args, true, res);
7643                    }
7644                    args.doPostInstall(res.returnCode, res.uid);
7645                }
7646
7647                // A restore should be performed at this point if (a) the install
7648                // succeeded, (b) the operation is not an update, and (c) the new
7649                // package has a backupAgent defined.
7650                final boolean update = res.removedInfo.removedPackage != null;
7651                boolean doRestore = (!update
7652                        && res.pkg != null
7653                        && res.pkg.applicationInfo.backupAgentName != null);
7654
7655                // Set up the post-install work request bookkeeping.  This will be used
7656                // and cleaned up by the post-install event handling regardless of whether
7657                // there's a restore pass performed.  Token values are >= 1.
7658                int token;
7659                if (mNextInstallToken < 0) mNextInstallToken = 1;
7660                token = mNextInstallToken++;
7661
7662                PostInstallData data = new PostInstallData(args, res);
7663                mRunningInstalls.put(token, data);
7664                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
7665
7666                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
7667                    // Pass responsibility to the Backup Manager.  It will perform a
7668                    // restore if appropriate, then pass responsibility back to the
7669                    // Package Manager to run the post-install observer callbacks
7670                    // and broadcasts.
7671                    IBackupManager bm = IBackupManager.Stub.asInterface(
7672                            ServiceManager.getService(Context.BACKUP_SERVICE));
7673                    if (bm != null) {
7674                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
7675                                + " to BM for possible restore");
7676                        try {
7677                            bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
7678                        } catch (RemoteException e) {
7679                            // can't happen; the backup manager is local
7680                        } catch (Exception e) {
7681                            Slog.e(TAG, "Exception trying to enqueue restore", e);
7682                            doRestore = false;
7683                        }
7684                    } else {
7685                        Slog.e(TAG, "Backup Manager not found!");
7686                        doRestore = false;
7687                    }
7688                }
7689
7690                if (!doRestore) {
7691                    // No restore possible, or the Backup Manager was mysteriously not
7692                    // available -- just fire the post-install work request directly.
7693                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
7694                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
7695                    mHandler.sendMessage(msg);
7696                }
7697            }
7698        });
7699    }
7700
7701    private abstract class HandlerParams {
7702        private static final int MAX_RETRIES = 4;
7703
7704        /**
7705         * Number of times startCopy() has been attempted and had a non-fatal
7706         * error.
7707         */
7708        private int mRetries = 0;
7709
7710        /** User handle for the user requesting the information or installation. */
7711        private final UserHandle mUser;
7712
7713        HandlerParams(UserHandle user) {
7714            mUser = user;
7715        }
7716
7717        UserHandle getUser() {
7718            return mUser;
7719        }
7720
7721        final boolean startCopy() {
7722            boolean res;
7723            try {
7724                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
7725
7726                if (++mRetries > MAX_RETRIES) {
7727                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
7728                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
7729                    handleServiceError();
7730                    return false;
7731                } else {
7732                    handleStartCopy();
7733                    res = true;
7734                }
7735            } catch (RemoteException e) {
7736                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
7737                mHandler.sendEmptyMessage(MCS_RECONNECT);
7738                res = false;
7739            }
7740            handleReturnCode();
7741            return res;
7742        }
7743
7744        final void serviceError() {
7745            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
7746            handleServiceError();
7747            handleReturnCode();
7748        }
7749
7750        abstract void handleStartCopy() throws RemoteException;
7751        abstract void handleServiceError();
7752        abstract void handleReturnCode();
7753    }
7754
7755    class MeasureParams extends HandlerParams {
7756        private final PackageStats mStats;
7757        private boolean mSuccess;
7758
7759        private final IPackageStatsObserver mObserver;
7760
7761        public MeasureParams(PackageStats stats, IPackageStatsObserver observer) {
7762            super(new UserHandle(stats.userHandle));
7763            mObserver = observer;
7764            mStats = stats;
7765        }
7766
7767        @Override
7768        public String toString() {
7769            return "MeasureParams{"
7770                + Integer.toHexString(System.identityHashCode(this))
7771                + " " + mStats.packageName + "}";
7772        }
7773
7774        @Override
7775        void handleStartCopy() throws RemoteException {
7776            synchronized (mInstallLock) {
7777                mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats);
7778            }
7779
7780            if (mSuccess) {
7781                final boolean mounted;
7782                if (Environment.isExternalStorageEmulated()) {
7783                    mounted = true;
7784                } else {
7785                    final String status = Environment.getExternalStorageState();
7786                    mounted = (Environment.MEDIA_MOUNTED.equals(status)
7787                            || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status));
7788                }
7789
7790                if (mounted) {
7791                    final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle);
7792
7793                    mStats.externalCacheSize = calculateDirectorySize(mContainerService,
7794                            userEnv.buildExternalStorageAppCacheDirs(mStats.packageName));
7795
7796                    mStats.externalDataSize = calculateDirectorySize(mContainerService,
7797                            userEnv.buildExternalStorageAppDataDirs(mStats.packageName));
7798
7799                    // Always subtract cache size, since it's a subdirectory
7800                    mStats.externalDataSize -= mStats.externalCacheSize;
7801
7802                    mStats.externalMediaSize = calculateDirectorySize(mContainerService,
7803                            userEnv.buildExternalStorageAppMediaDirs(mStats.packageName));
7804
7805                    mStats.externalObbSize = calculateDirectorySize(mContainerService,
7806                            userEnv.buildExternalStorageAppObbDirs(mStats.packageName));
7807                }
7808            }
7809        }
7810
7811        @Override
7812        void handleReturnCode() {
7813            if (mObserver != null) {
7814                try {
7815                    mObserver.onGetStatsCompleted(mStats, mSuccess);
7816                } catch (RemoteException e) {
7817                    Slog.i(TAG, "Observer no longer exists.");
7818                }
7819            }
7820        }
7821
7822        @Override
7823        void handleServiceError() {
7824            Slog.e(TAG, "Could not measure application " + mStats.packageName
7825                            + " external storage");
7826        }
7827    }
7828
7829    private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths)
7830            throws RemoteException {
7831        long result = 0;
7832        for (File path : paths) {
7833            result += mcs.calculateDirectorySize(path.getAbsolutePath());
7834        }
7835        return result;
7836    }
7837
7838    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
7839        for (File path : paths) {
7840            try {
7841                mcs.clearDirectory(path.getAbsolutePath());
7842            } catch (RemoteException e) {
7843            }
7844        }
7845    }
7846
7847    class InstallParams extends HandlerParams {
7848        final IPackageInstallObserver observer;
7849        final IPackageInstallObserver2 observer2;
7850        int flags;
7851
7852        private final Uri mPackageURI;
7853        final String installerPackageName;
7854        final VerificationParams verificationParams;
7855        private InstallArgs mArgs;
7856        private int mRet;
7857        private File mTempPackage;
7858        final ContainerEncryptionParams encryptionParams;
7859
7860        InstallParams(Uri packageURI,
7861                IPackageInstallObserver observer, IPackageInstallObserver2 observer2,
7862                int flags, String installerPackageName, VerificationParams verificationParams,
7863                ContainerEncryptionParams encryptionParams, UserHandle user) {
7864            super(user);
7865            this.mPackageURI = packageURI;
7866            this.flags = flags;
7867            this.observer = observer;
7868            this.observer2 = observer2;
7869            this.installerPackageName = installerPackageName;
7870            this.verificationParams = verificationParams;
7871            this.encryptionParams = encryptionParams;
7872        }
7873
7874        @Override
7875        public String toString() {
7876            return "InstallParams{"
7877                + Integer.toHexString(System.identityHashCode(this))
7878                + " " + mPackageURI + "}";
7879        }
7880
7881        public ManifestDigest getManifestDigest() {
7882            if (verificationParams == null) {
7883                return null;
7884            }
7885            return verificationParams.getManifestDigest();
7886        }
7887
7888        private int installLocationPolicy(PackageInfoLite pkgLite, int flags) {
7889            String packageName = pkgLite.packageName;
7890            int installLocation = pkgLite.installLocation;
7891            boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0;
7892            // reader
7893            synchronized (mPackages) {
7894                PackageParser.Package pkg = mPackages.get(packageName);
7895                if (pkg != null) {
7896                    if ((flags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
7897                        // Check for downgrading.
7898                        if ((flags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0) {
7899                            if (pkgLite.versionCode < pkg.mVersionCode) {
7900                                Slog.w(TAG, "Can't install update of " + packageName
7901                                        + " update version " + pkgLite.versionCode
7902                                        + " is older than installed version "
7903                                        + pkg.mVersionCode);
7904                                return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
7905                            }
7906                        }
7907                        // Check for updated system application.
7908                        if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7909                            if (onSd) {
7910                                Slog.w(TAG, "Cannot install update to system app on sdcard");
7911                                return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
7912                            }
7913                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
7914                        } else {
7915                            if (onSd) {
7916                                // Install flag overrides everything.
7917                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
7918                            }
7919                            // If current upgrade specifies particular preference
7920                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
7921                                // Application explicitly specified internal.
7922                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
7923                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
7924                                // App explictly prefers external. Let policy decide
7925                            } else {
7926                                // Prefer previous location
7927                                if (isExternal(pkg)) {
7928                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
7929                                }
7930                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
7931                            }
7932                        }
7933                    } else {
7934                        // Invalid install. Return error code
7935                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
7936                    }
7937                }
7938            }
7939            // All the special cases have been taken care of.
7940            // Return result based on recommended install location.
7941            if (onSd) {
7942                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
7943            }
7944            return pkgLite.recommendedInstallLocation;
7945        }
7946
7947        private long getMemoryLowThreshold() {
7948            final DeviceStorageMonitorInternal
7949                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
7950            if (dsm == null) {
7951                return 0L;
7952            }
7953            return dsm.getMemoryLowThreshold();
7954        }
7955
7956        /*
7957         * Invoke remote method to get package information and install
7958         * location values. Override install location based on default
7959         * policy if needed and then create install arguments based
7960         * on the install location.
7961         */
7962        public void handleStartCopy() throws RemoteException {
7963            int ret = PackageManager.INSTALL_SUCCEEDED;
7964            final boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0;
7965            final boolean onInt = (flags & PackageManager.INSTALL_INTERNAL) != 0;
7966            PackageInfoLite pkgLite = null;
7967
7968            if (onInt && onSd) {
7969                // Check if both bits are set.
7970                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
7971                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
7972            } else {
7973                final long lowThreshold = getMemoryLowThreshold();
7974                if (lowThreshold == 0L) {
7975                    Log.w(TAG, "Couldn't get low memory threshold; no free limit imposed");
7976                }
7977
7978                try {
7979                    mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, mPackageURI,
7980                            Intent.FLAG_GRANT_READ_URI_PERMISSION);
7981
7982                    final File packageFile;
7983                    if (encryptionParams != null || !"file".equals(mPackageURI.getScheme())) {
7984                        mTempPackage = createTempPackageFile(mDrmAppPrivateInstallDir);
7985                        if (mTempPackage != null) {
7986                            ParcelFileDescriptor out;
7987                            try {
7988                                out = ParcelFileDescriptor.open(mTempPackage,
7989                                        ParcelFileDescriptor.MODE_READ_WRITE);
7990                            } catch (FileNotFoundException e) {
7991                                out = null;
7992                                Slog.e(TAG, "Failed to create temporary file for : " + mPackageURI);
7993                            }
7994
7995                            // Make a temporary file for decryption.
7996                            ret = mContainerService
7997                                    .copyResource(mPackageURI, encryptionParams, out);
7998                            IoUtils.closeQuietly(out);
7999
8000                            packageFile = mTempPackage;
8001
8002                            FileUtils.setPermissions(packageFile.getAbsolutePath(),
8003                                    FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP
8004                                            | FileUtils.S_IROTH,
8005                                    -1, -1);
8006                        } else {
8007                            packageFile = null;
8008                        }
8009                    } else {
8010                        packageFile = new File(mPackageURI.getPath());
8011                    }
8012
8013                    if (packageFile != null) {
8014                        // Remote call to find out default install location
8015                        final String packageFilePath = packageFile.getAbsolutePath();
8016                        pkgLite = mContainerService.getMinimalPackageInfo(packageFilePath, flags,
8017                                lowThreshold);
8018
8019                        /*
8020                         * If we have too little free space, try to free cache
8021                         * before giving up.
8022                         */
8023                        if (pkgLite.recommendedInstallLocation
8024                                == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
8025                            final long size = mContainerService.calculateInstalledSize(
8026                                    packageFilePath, isForwardLocked());
8027                            if (mInstaller.freeCache(size + lowThreshold) >= 0) {
8028                                pkgLite = mContainerService.getMinimalPackageInfo(packageFilePath,
8029                                        flags, lowThreshold);
8030                            }
8031                            /*
8032                             * The cache free must have deleted the file we
8033                             * downloaded to install.
8034                             *
8035                             * TODO: fix the "freeCache" call to not delete
8036                             *       the file we care about.
8037                             */
8038                            if (pkgLite.recommendedInstallLocation
8039                                    == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
8040                                pkgLite.recommendedInstallLocation
8041                                    = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
8042                            }
8043                        }
8044                    }
8045                } finally {
8046                    mContext.revokeUriPermission(mPackageURI,
8047                            Intent.FLAG_GRANT_READ_URI_PERMISSION);
8048                }
8049            }
8050
8051            if (ret == PackageManager.INSTALL_SUCCEEDED) {
8052                int loc = pkgLite.recommendedInstallLocation;
8053                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
8054                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
8055                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
8056                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
8057                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
8058                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
8059                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
8060                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
8061                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
8062                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
8063                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
8064                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
8065                } else {
8066                    // Override with defaults if needed.
8067                    loc = installLocationPolicy(pkgLite, flags);
8068                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
8069                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
8070                    } else if (!onSd && !onInt) {
8071                        // Override install location with flags
8072                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
8073                            // Set the flag to install on external media.
8074                            flags |= PackageManager.INSTALL_EXTERNAL;
8075                            flags &= ~PackageManager.INSTALL_INTERNAL;
8076                        } else {
8077                            // Make sure the flag for installing on external
8078                            // media is unset
8079                            flags |= PackageManager.INSTALL_INTERNAL;
8080                            flags &= ~PackageManager.INSTALL_EXTERNAL;
8081                        }
8082                    }
8083                }
8084            }
8085
8086            final InstallArgs args = createInstallArgs(this);
8087            mArgs = args;
8088
8089            if (ret == PackageManager.INSTALL_SUCCEEDED) {
8090                 /*
8091                 * ADB installs appear as UserHandle.USER_ALL, and can only be performed by
8092                 * UserHandle.USER_OWNER, so use the package verifier for UserHandle.USER_OWNER.
8093                 */
8094                int userIdentifier = getUser().getIdentifier();
8095                if (userIdentifier == UserHandle.USER_ALL
8096                        && ((flags & PackageManager.INSTALL_FROM_ADB) != 0)) {
8097                    userIdentifier = UserHandle.USER_OWNER;
8098                }
8099
8100                /*
8101                 * Determine if we have any installed package verifiers. If we
8102                 * do, then we'll defer to them to verify the packages.
8103                 */
8104                final int requiredUid = mRequiredVerifierPackage == null ? -1
8105                        : getPackageUid(mRequiredVerifierPackage, userIdentifier);
8106                if (requiredUid != -1 && isVerificationEnabled(flags)) {
8107                    final Intent verification = new Intent(
8108                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
8109                    verification.setDataAndType(getPackageUri(), PACKAGE_MIME_TYPE);
8110                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
8111
8112                    final List<ResolveInfo> receivers = queryIntentReceivers(verification,
8113                            PACKAGE_MIME_TYPE, PackageManager.GET_DISABLED_COMPONENTS,
8114                            0 /* TODO: Which userId? */);
8115
8116                    if (DEBUG_VERIFY) {
8117                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
8118                                + verification.toString() + " with " + pkgLite.verifiers.length
8119                                + " optional verifiers");
8120                    }
8121
8122                    final int verificationId = mPendingVerificationToken++;
8123
8124                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
8125
8126                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
8127                            installerPackageName);
8128
8129                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, flags);
8130
8131                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
8132                            pkgLite.packageName);
8133
8134                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
8135                            pkgLite.versionCode);
8136
8137                    if (verificationParams != null) {
8138                        if (verificationParams.getVerificationURI() != null) {
8139                           verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI,
8140                                 verificationParams.getVerificationURI());
8141                        }
8142                        if (verificationParams.getOriginatingURI() != null) {
8143                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
8144                                  verificationParams.getOriginatingURI());
8145                        }
8146                        if (verificationParams.getReferrer() != null) {
8147                            verification.putExtra(Intent.EXTRA_REFERRER,
8148                                  verificationParams.getReferrer());
8149                        }
8150                        if (verificationParams.getOriginatingUid() >= 0) {
8151                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
8152                                  verificationParams.getOriginatingUid());
8153                        }
8154                        if (verificationParams.getInstallerUid() >= 0) {
8155                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
8156                                  verificationParams.getInstallerUid());
8157                        }
8158                    }
8159
8160                    final PackageVerificationState verificationState = new PackageVerificationState(
8161                            requiredUid, args);
8162
8163                    mPendingVerification.append(verificationId, verificationState);
8164
8165                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
8166                            receivers, verificationState);
8167
8168                    /*
8169                     * If any sufficient verifiers were listed in the package
8170                     * manifest, attempt to ask them.
8171                     */
8172                    if (sufficientVerifiers != null) {
8173                        final int N = sufficientVerifiers.size();
8174                        if (N == 0) {
8175                            Slog.i(TAG, "Additional verifiers required, but none installed.");
8176                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
8177                        } else {
8178                            for (int i = 0; i < N; i++) {
8179                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
8180
8181                                final Intent sufficientIntent = new Intent(verification);
8182                                sufficientIntent.setComponent(verifierComponent);
8183
8184                                mContext.sendBroadcastAsUser(sufficientIntent, getUser());
8185                            }
8186                        }
8187                    }
8188
8189                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
8190                            mRequiredVerifierPackage, receivers);
8191                    if (ret == PackageManager.INSTALL_SUCCEEDED
8192                            && mRequiredVerifierPackage != null) {
8193                        /*
8194                         * Send the intent to the required verification agent,
8195                         * but only start the verification timeout after the
8196                         * target BroadcastReceivers have run.
8197                         */
8198                        verification.setComponent(requiredVerifierComponent);
8199                        mContext.sendOrderedBroadcastAsUser(verification, getUser(),
8200                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
8201                                new BroadcastReceiver() {
8202                                    @Override
8203                                    public void onReceive(Context context, Intent intent) {
8204                                        final Message msg = mHandler
8205                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
8206                                        msg.arg1 = verificationId;
8207                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
8208                                    }
8209                                }, null, 0, null, null);
8210
8211                        /*
8212                         * We don't want the copy to proceed until verification
8213                         * succeeds, so null out this field.
8214                         */
8215                        mArgs = null;
8216                    }
8217                } else {
8218                    /*
8219                     * No package verification is enabled, so immediately start
8220                     * the remote call to initiate copy using temporary file.
8221                     */
8222                    ret = args.copyApk(mContainerService, true);
8223                }
8224            }
8225
8226            mRet = ret;
8227        }
8228
8229        @Override
8230        void handleReturnCode() {
8231            // If mArgs is null, then MCS couldn't be reached. When it
8232            // reconnects, it will try again to install. At that point, this
8233            // will succeed.
8234            if (mArgs != null) {
8235                processPendingInstall(mArgs, mRet);
8236
8237                if (mTempPackage != null) {
8238                    if (!mTempPackage.delete()) {
8239                        Slog.w(TAG, "Couldn't delete temporary file: " +
8240                                mTempPackage.getAbsolutePath());
8241                    }
8242                }
8243            }
8244        }
8245
8246        @Override
8247        void handleServiceError() {
8248            mArgs = createInstallArgs(this);
8249            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
8250        }
8251
8252        public boolean isForwardLocked() {
8253            return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
8254        }
8255
8256        public Uri getPackageUri() {
8257            if (mTempPackage != null) {
8258                return Uri.fromFile(mTempPackage);
8259            } else {
8260                return mPackageURI;
8261            }
8262        }
8263    }
8264
8265    /*
8266     * Utility class used in movePackage api.
8267     * srcArgs and targetArgs are not set for invalid flags and make
8268     * sure to do null checks when invoking methods on them.
8269     * We probably want to return ErrorPrams for both failed installs
8270     * and moves.
8271     */
8272    class MoveParams extends HandlerParams {
8273        final IPackageMoveObserver observer;
8274        final int flags;
8275        final String packageName;
8276        final InstallArgs srcArgs;
8277        final InstallArgs targetArgs;
8278        int uid;
8279        int mRet;
8280
8281        MoveParams(InstallArgs srcArgs, IPackageMoveObserver observer, int flags,
8282                String packageName, String dataDir, int uid, UserHandle user) {
8283            super(user);
8284            this.srcArgs = srcArgs;
8285            this.observer = observer;
8286            this.flags = flags;
8287            this.packageName = packageName;
8288            this.uid = uid;
8289            if (srcArgs != null) {
8290                Uri packageUri = Uri.fromFile(new File(srcArgs.getCodePath()));
8291                targetArgs = createInstallArgs(packageUri, flags, packageName, dataDir);
8292            } else {
8293                targetArgs = null;
8294            }
8295        }
8296
8297        @Override
8298        public String toString() {
8299            return "MoveParams{"
8300                + Integer.toHexString(System.identityHashCode(this))
8301                + " " + packageName + "}";
8302        }
8303
8304        public void handleStartCopy() throws RemoteException {
8305            mRet = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
8306            // Check for storage space on target medium
8307            if (!targetArgs.checkFreeStorage(mContainerService)) {
8308                Log.w(TAG, "Insufficient storage to install");
8309                return;
8310            }
8311
8312            mRet = srcArgs.doPreCopy();
8313            if (mRet != PackageManager.INSTALL_SUCCEEDED) {
8314                return;
8315            }
8316
8317            mRet = targetArgs.copyApk(mContainerService, false);
8318            if (mRet != PackageManager.INSTALL_SUCCEEDED) {
8319                srcArgs.doPostCopy(uid);
8320                return;
8321            }
8322
8323            mRet = srcArgs.doPostCopy(uid);
8324            if (mRet != PackageManager.INSTALL_SUCCEEDED) {
8325                return;
8326            }
8327
8328            mRet = targetArgs.doPreInstall(mRet);
8329            if (mRet != PackageManager.INSTALL_SUCCEEDED) {
8330                return;
8331            }
8332
8333            if (DEBUG_SD_INSTALL) {
8334                StringBuilder builder = new StringBuilder();
8335                if (srcArgs != null) {
8336                    builder.append("src: ");
8337                    builder.append(srcArgs.getCodePath());
8338                }
8339                if (targetArgs != null) {
8340                    builder.append(" target : ");
8341                    builder.append(targetArgs.getCodePath());
8342                }
8343                Log.i(TAG, builder.toString());
8344            }
8345        }
8346
8347        @Override
8348        void handleReturnCode() {
8349            targetArgs.doPostInstall(mRet, uid);
8350            int currentStatus = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
8351            if (mRet == PackageManager.INSTALL_SUCCEEDED) {
8352                currentStatus = PackageManager.MOVE_SUCCEEDED;
8353            } else if (mRet == PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE){
8354                currentStatus = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
8355            }
8356            processPendingMove(this, currentStatus);
8357        }
8358
8359        @Override
8360        void handleServiceError() {
8361            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
8362        }
8363    }
8364
8365    /**
8366     * Used during creation of InstallArgs
8367     *
8368     * @param flags package installation flags
8369     * @return true if should be installed on external storage
8370     */
8371    private static boolean installOnSd(int flags) {
8372        if ((flags & PackageManager.INSTALL_INTERNAL) != 0) {
8373            return false;
8374        }
8375        if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) {
8376            return true;
8377        }
8378        return false;
8379    }
8380
8381    /**
8382     * Used during creation of InstallArgs
8383     *
8384     * @param flags package installation flags
8385     * @return true if should be installed as forward locked
8386     */
8387    private static boolean installForwardLocked(int flags) {
8388        return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
8389    }
8390
8391    private InstallArgs createInstallArgs(InstallParams params) {
8392        if (installOnSd(params.flags) || params.isForwardLocked()) {
8393            return new AsecInstallArgs(params);
8394        } else {
8395            return new FileInstallArgs(params);
8396        }
8397    }
8398
8399    private InstallArgs createInstallArgs(int flags, String fullCodePath, String fullResourcePath,
8400            String nativeLibraryPath) {
8401        final boolean isInAsec;
8402        if (installOnSd(flags)) {
8403            /* Apps on SD card are always in ASEC containers. */
8404            isInAsec = true;
8405        } else if (installForwardLocked(flags)
8406                && !fullCodePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
8407            /*
8408             * Forward-locked apps are only in ASEC containers if they're the
8409             * new style
8410             */
8411            isInAsec = true;
8412        } else {
8413            isInAsec = false;
8414        }
8415
8416        if (isInAsec) {
8417            return new AsecInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath,
8418                    installOnSd(flags), installForwardLocked(flags));
8419        } else {
8420            return new FileInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath);
8421        }
8422    }
8423
8424    // Used by package mover
8425    private InstallArgs createInstallArgs(Uri packageURI, int flags, String pkgName, String dataDir) {
8426        if (installOnSd(flags) || installForwardLocked(flags)) {
8427            String cid = getNextCodePath(packageURI.getPath(), pkgName, "/"
8428                    + AsecInstallArgs.RES_FILE_NAME);
8429            return new AsecInstallArgs(packageURI, cid, installOnSd(flags),
8430                    installForwardLocked(flags));
8431        } else {
8432            return new FileInstallArgs(packageURI, pkgName, dataDir);
8433        }
8434    }
8435
8436    static abstract class InstallArgs {
8437        final IPackageInstallObserver observer;
8438        final IPackageInstallObserver2 observer2;
8439        // Always refers to PackageManager flags only
8440        final int flags;
8441        final Uri packageURI;
8442        final String installerPackageName;
8443        final ManifestDigest manifestDigest;
8444        final UserHandle user;
8445
8446        InstallArgs(Uri packageURI,
8447                IPackageInstallObserver observer, IPackageInstallObserver2 observer2,
8448                int flags, String installerPackageName, ManifestDigest manifestDigest,
8449                UserHandle user) {
8450            this.packageURI = packageURI;
8451            this.flags = flags;
8452            this.observer = observer;
8453            this.observer2 = observer2;
8454            this.installerPackageName = installerPackageName;
8455            this.manifestDigest = manifestDigest;
8456            this.user = user;
8457        }
8458
8459        abstract void createCopyFile();
8460        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
8461        abstract int doPreInstall(int status);
8462        abstract boolean doRename(int status, String pkgName, String oldCodePath);
8463
8464        abstract int doPostInstall(int status, int uid);
8465        abstract String getCodePath();
8466        abstract String getResourcePath();
8467        abstract String getNativeLibraryPath();
8468        // Need installer lock especially for dex file removal.
8469        abstract void cleanUpResourcesLI();
8470        abstract boolean doPostDeleteLI(boolean delete);
8471        abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException;
8472
8473        /**
8474         * Called before the source arguments are copied. This is used mostly
8475         * for MoveParams when it needs to read the source file to put it in the
8476         * destination.
8477         */
8478        int doPreCopy() {
8479            return PackageManager.INSTALL_SUCCEEDED;
8480        }
8481
8482        /**
8483         * Called after the source arguments are copied. This is used mostly for
8484         * MoveParams when it needs to read the source file to put it in the
8485         * destination.
8486         *
8487         * @return
8488         */
8489        int doPostCopy(int uid) {
8490            return PackageManager.INSTALL_SUCCEEDED;
8491        }
8492
8493        protected boolean isFwdLocked() {
8494            return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
8495        }
8496
8497        UserHandle getUser() {
8498            return user;
8499        }
8500    }
8501
8502    class FileInstallArgs extends InstallArgs {
8503        File installDir;
8504        String codeFileName;
8505        String resourceFileName;
8506        String libraryPath;
8507        boolean created = false;
8508
8509        FileInstallArgs(InstallParams params) {
8510            super(params.getPackageUri(), params.observer, params.observer2, params.flags,
8511                    params.installerPackageName, params.getManifestDigest(),
8512                    params.getUser());
8513        }
8514
8515        FileInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath) {
8516            super(null, null, null, 0, null, null, null);
8517            File codeFile = new File(fullCodePath);
8518            installDir = codeFile.getParentFile();
8519            codeFileName = fullCodePath;
8520            resourceFileName = fullResourcePath;
8521            libraryPath = nativeLibraryPath;
8522        }
8523
8524        FileInstallArgs(Uri packageURI, String pkgName, String dataDir) {
8525            super(packageURI, null, null, 0, null, null, null);
8526            installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir;
8527            String apkName = getNextCodePath(null, pkgName, ".apk");
8528            codeFileName = new File(installDir, apkName + ".apk").getPath();
8529            resourceFileName = getResourcePathFromCodePath();
8530            libraryPath = new File(mAppLibInstallDir, pkgName).getPath();
8531        }
8532
8533        boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
8534            final long lowThreshold;
8535
8536            final DeviceStorageMonitorInternal
8537                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
8538            if (dsm == null) {
8539                Log.w(TAG, "Couldn't get low memory threshold; no free limit imposed");
8540                lowThreshold = 0L;
8541            } else {
8542                if (dsm.isMemoryLow()) {
8543                    Log.w(TAG, "Memory is reported as being too low; aborting package install");
8544                    return false;
8545                }
8546
8547                lowThreshold = dsm.getMemoryLowThreshold();
8548            }
8549
8550            try {
8551                mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
8552                        Intent.FLAG_GRANT_READ_URI_PERMISSION);
8553                return imcs.checkInternalFreeStorage(packageURI, isFwdLocked(), lowThreshold);
8554            } finally {
8555                mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
8556            }
8557        }
8558
8559        String getCodePath() {
8560            return codeFileName;
8561        }
8562
8563        void createCopyFile() {
8564            installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir;
8565            codeFileName = createTempPackageFile(installDir).getPath();
8566            resourceFileName = getResourcePathFromCodePath();
8567            libraryPath = getLibraryPathFromCodePath();
8568            created = true;
8569        }
8570
8571        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
8572            if (temp) {
8573                // Generate temp file name
8574                createCopyFile();
8575            }
8576            // Get a ParcelFileDescriptor to write to the output file
8577            File codeFile = new File(codeFileName);
8578            if (!created) {
8579                try {
8580                    codeFile.createNewFile();
8581                    // Set permissions
8582                    if (!setPermissions()) {
8583                        // Failed setting permissions.
8584                        return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
8585                    }
8586                } catch (IOException e) {
8587                   Slog.w(TAG, "Failed to create file " + codeFile);
8588                   return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
8589                }
8590            }
8591            ParcelFileDescriptor out = null;
8592            try {
8593                out = ParcelFileDescriptor.open(codeFile, ParcelFileDescriptor.MODE_READ_WRITE);
8594            } catch (FileNotFoundException e) {
8595                Slog.e(TAG, "Failed to create file descriptor for : " + codeFileName);
8596                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
8597            }
8598            // Copy the resource now
8599            int ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
8600            try {
8601                mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
8602                        Intent.FLAG_GRANT_READ_URI_PERMISSION);
8603                ret = imcs.copyResource(packageURI, null, out);
8604            } finally {
8605                IoUtils.closeQuietly(out);
8606                mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
8607            }
8608
8609            if (isFwdLocked()) {
8610                final File destResourceFile = new File(getResourcePath());
8611
8612                // Copy the public files
8613                try {
8614                    PackageHelper.extractPublicFiles(codeFileName, destResourceFile);
8615                } catch (IOException e) {
8616                    Slog.e(TAG, "Couldn't create a new zip file for the public parts of a"
8617                            + " forward-locked app.");
8618                    destResourceFile.delete();
8619                    return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
8620                }
8621            }
8622
8623            final File nativeLibraryFile = new File(getNativeLibraryPath());
8624            Slog.i(TAG, "Copying native libraries to " + nativeLibraryFile.getPath());
8625            if (nativeLibraryFile.exists()) {
8626                NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryFile);
8627                nativeLibraryFile.delete();
8628            }
8629            try {
8630                int copyRet = copyNativeLibrariesForInternalApp(codeFile, nativeLibraryFile);
8631                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
8632                    return copyRet;
8633                }
8634            } catch (IOException e) {
8635                Slog.e(TAG, "Copying native libraries failed", e);
8636                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
8637            }
8638
8639            return ret;
8640        }
8641
8642        int doPreInstall(int status) {
8643            if (status != PackageManager.INSTALL_SUCCEEDED) {
8644                cleanUp();
8645            }
8646            return status;
8647        }
8648
8649        boolean doRename(int status, final String pkgName, String oldCodePath) {
8650            if (status != PackageManager.INSTALL_SUCCEEDED) {
8651                cleanUp();
8652                return false;
8653            } else {
8654                final File oldCodeFile = new File(getCodePath());
8655                final File oldResourceFile = new File(getResourcePath());
8656                final File oldLibraryFile = new File(getNativeLibraryPath());
8657
8658                // Rename APK file based on packageName
8659                final String apkName = getNextCodePath(oldCodePath, pkgName, ".apk");
8660                final File newCodeFile = new File(installDir, apkName + ".apk");
8661                if (!oldCodeFile.renameTo(newCodeFile)) {
8662                    return false;
8663                }
8664                codeFileName = newCodeFile.getPath();
8665
8666                // Rename public resource file if it's forward-locked.
8667                final File newResFile = new File(getResourcePathFromCodePath());
8668                if (isFwdLocked() && !oldResourceFile.renameTo(newResFile)) {
8669                    return false;
8670                }
8671                resourceFileName = newResFile.getPath();
8672
8673                // Rename library path
8674                final File newLibraryFile = new File(getLibraryPathFromCodePath());
8675                if (newLibraryFile.exists()) {
8676                    NativeLibraryHelper.removeNativeBinariesFromDirLI(newLibraryFile);
8677                    newLibraryFile.delete();
8678                }
8679                if (!oldLibraryFile.renameTo(newLibraryFile)) {
8680                    Slog.e(TAG, "Cannot rename native library directory "
8681                            + oldLibraryFile.getPath() + " to " + newLibraryFile.getPath());
8682                    return false;
8683                }
8684                libraryPath = newLibraryFile.getPath();
8685
8686                // Attempt to set permissions
8687                if (!setPermissions()) {
8688                    return false;
8689                }
8690
8691                if (!SELinux.restorecon(newCodeFile)) {
8692                    return false;
8693                }
8694
8695                return true;
8696            }
8697        }
8698
8699        int doPostInstall(int status, int uid) {
8700            if (status != PackageManager.INSTALL_SUCCEEDED) {
8701                cleanUp();
8702            }
8703            return status;
8704        }
8705
8706        String getResourcePath() {
8707            return resourceFileName;
8708        }
8709
8710        private String getResourcePathFromCodePath() {
8711            final String codePath = getCodePath();
8712            if (isFwdLocked()) {
8713                final StringBuilder sb = new StringBuilder();
8714
8715                sb.append(mAppInstallDir.getPath());
8716                sb.append('/');
8717                sb.append(getApkName(codePath));
8718                sb.append(".zip");
8719
8720                /*
8721                 * If our APK is a temporary file, mark the resource as a
8722                 * temporary file as well so it can be cleaned up after
8723                 * catastrophic failure.
8724                 */
8725                if (codePath.endsWith(".tmp")) {
8726                    sb.append(".tmp");
8727                }
8728
8729                return sb.toString();
8730            } else {
8731                return codePath;
8732            }
8733        }
8734
8735        private String getLibraryPathFromCodePath() {
8736            return new File(mAppLibInstallDir, getApkName(getCodePath())).getPath();
8737        }
8738
8739        @Override
8740        String getNativeLibraryPath() {
8741            if (libraryPath == null) {
8742                libraryPath = getLibraryPathFromCodePath();
8743            }
8744            return libraryPath;
8745        }
8746
8747        private boolean cleanUp() {
8748            boolean ret = true;
8749            String sourceDir = getCodePath();
8750            String publicSourceDir = getResourcePath();
8751            if (sourceDir != null) {
8752                File sourceFile = new File(sourceDir);
8753                if (!sourceFile.exists()) {
8754                    Slog.w(TAG, "Package source " + sourceDir + " does not exist.");
8755                    ret = false;
8756                }
8757                // Delete application's code and resources
8758                sourceFile.delete();
8759            }
8760            if (publicSourceDir != null && !publicSourceDir.equals(sourceDir)) {
8761                final File publicSourceFile = new File(publicSourceDir);
8762                if (!publicSourceFile.exists()) {
8763                    Slog.w(TAG, "Package public source " + publicSourceFile + " does not exist.");
8764                }
8765                if (publicSourceFile.exists()) {
8766                    publicSourceFile.delete();
8767                }
8768            }
8769
8770            if (libraryPath != null) {
8771                File nativeLibraryFile = new File(libraryPath);
8772                NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryFile);
8773                if (!nativeLibraryFile.delete()) {
8774                    Slog.w(TAG, "Couldn't delete native library directory " + libraryPath);
8775                }
8776            }
8777
8778            return ret;
8779        }
8780
8781        void cleanUpResourcesLI() {
8782            String sourceDir = getCodePath();
8783            if (cleanUp()) {
8784                int retCode = mInstaller.rmdex(sourceDir);
8785                if (retCode < 0) {
8786                    Slog.w(TAG, "Couldn't remove dex file for package: "
8787                            +  " at location "
8788                            + sourceDir + ", retcode=" + retCode);
8789                    // we don't consider this to be a failure of the core package deletion
8790                }
8791            }
8792        }
8793
8794        private boolean setPermissions() {
8795            // TODO Do this in a more elegant way later on. for now just a hack
8796            if (!isFwdLocked()) {
8797                final int filePermissions =
8798                    FileUtils.S_IRUSR|FileUtils.S_IWUSR|FileUtils.S_IRGRP
8799                    |FileUtils.S_IROTH;
8800                int retCode = FileUtils.setPermissions(getCodePath(), filePermissions, -1, -1);
8801                if (retCode != 0) {
8802                    Slog.e(TAG, "Couldn't set new package file permissions for " +
8803                            getCodePath()
8804                            + ". The return code was: " + retCode);
8805                    // TODO Define new internal error
8806                    return false;
8807                }
8808                return true;
8809            }
8810            return true;
8811        }
8812
8813        boolean doPostDeleteLI(boolean delete) {
8814            // XXX err, shouldn't we respect the delete flag?
8815            cleanUpResourcesLI();
8816            return true;
8817        }
8818    }
8819
8820    private boolean isAsecExternal(String cid) {
8821        final String asecPath = PackageHelper.getSdFilesystem(cid);
8822        return !asecPath.startsWith(mAsecInternalPath);
8823    }
8824
8825    /**
8826     * Extract the MountService "container ID" from the full code path of an
8827     * .apk.
8828     */
8829    static String cidFromCodePath(String fullCodePath) {
8830        int eidx = fullCodePath.lastIndexOf("/");
8831        String subStr1 = fullCodePath.substring(0, eidx);
8832        int sidx = subStr1.lastIndexOf("/");
8833        return subStr1.substring(sidx+1, eidx);
8834    }
8835
8836    class AsecInstallArgs extends InstallArgs {
8837        static final String RES_FILE_NAME = "pkg.apk";
8838        static final String PUBLIC_RES_FILE_NAME = "res.zip";
8839
8840        String cid;
8841        String packagePath;
8842        String resourcePath;
8843        String libraryPath;
8844
8845        AsecInstallArgs(InstallParams params) {
8846            super(params.getPackageUri(), params.observer, params.observer2, params.flags,
8847                    params.installerPackageName, params.getManifestDigest(),
8848                    params.getUser());
8849        }
8850
8851        AsecInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath,
8852                boolean isExternal, boolean isForwardLocked) {
8853            super(null, null, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0)
8854                    | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
8855                    null, null, null);
8856            // Extract cid from fullCodePath
8857            int eidx = fullCodePath.lastIndexOf("/");
8858            String subStr1 = fullCodePath.substring(0, eidx);
8859            int sidx = subStr1.lastIndexOf("/");
8860            cid = subStr1.substring(sidx+1, eidx);
8861            setCachePath(subStr1);
8862        }
8863
8864        AsecInstallArgs(String cid, boolean isForwardLocked) {
8865            super(null, null, null, (isAsecExternal(cid) ? PackageManager.INSTALL_EXTERNAL : 0)
8866                    | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
8867                    null, null, null);
8868            this.cid = cid;
8869            setCachePath(PackageHelper.getSdDir(cid));
8870        }
8871
8872        AsecInstallArgs(Uri packageURI, String cid, boolean isExternal, boolean isForwardLocked) {
8873            super(packageURI, null, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0)
8874                    | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
8875                    null, null, null);
8876            this.cid = cid;
8877        }
8878
8879        void createCopyFile() {
8880            cid = getTempContainerId();
8881        }
8882
8883        boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
8884            try {
8885                mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
8886                        Intent.FLAG_GRANT_READ_URI_PERMISSION);
8887                return imcs.checkExternalFreeStorage(packageURI, isFwdLocked());
8888            } finally {
8889                mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
8890            }
8891        }
8892
8893        private final boolean isExternal() {
8894            return (flags & PackageManager.INSTALL_EXTERNAL) != 0;
8895        }
8896
8897        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
8898            if (temp) {
8899                createCopyFile();
8900            } else {
8901                /*
8902                 * Pre-emptively destroy the container since it's destroyed if
8903                 * copying fails due to it existing anyway.
8904                 */
8905                PackageHelper.destroySdDir(cid);
8906            }
8907
8908            final String newCachePath;
8909            try {
8910                mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
8911                        Intent.FLAG_GRANT_READ_URI_PERMISSION);
8912                newCachePath = imcs.copyResourceToContainer(packageURI, cid, getEncryptKey(),
8913                        RES_FILE_NAME, PUBLIC_RES_FILE_NAME, isExternal(), isFwdLocked());
8914            } finally {
8915                mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
8916            }
8917
8918            if (newCachePath != null) {
8919                setCachePath(newCachePath);
8920                return PackageManager.INSTALL_SUCCEEDED;
8921            } else {
8922                return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
8923            }
8924        }
8925
8926        @Override
8927        String getCodePath() {
8928            return packagePath;
8929        }
8930
8931        @Override
8932        String getResourcePath() {
8933            return resourcePath;
8934        }
8935
8936        @Override
8937        String getNativeLibraryPath() {
8938            return libraryPath;
8939        }
8940
8941        int doPreInstall(int status) {
8942            if (status != PackageManager.INSTALL_SUCCEEDED) {
8943                // Destroy container
8944                PackageHelper.destroySdDir(cid);
8945            } else {
8946                boolean mounted = PackageHelper.isContainerMounted(cid);
8947                if (!mounted) {
8948                    String newCachePath = PackageHelper.mountSdDir(cid, getEncryptKey(),
8949                            Process.SYSTEM_UID);
8950                    if (newCachePath != null) {
8951                        setCachePath(newCachePath);
8952                    } else {
8953                        return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
8954                    }
8955                }
8956            }
8957            return status;
8958        }
8959
8960        boolean doRename(int status, final String pkgName,
8961                String oldCodePath) {
8962            String newCacheId = getNextCodePath(oldCodePath, pkgName, "/" + RES_FILE_NAME);
8963            String newCachePath = null;
8964            if (PackageHelper.isContainerMounted(cid)) {
8965                // Unmount the container
8966                if (!PackageHelper.unMountSdDir(cid)) {
8967                    Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
8968                    return false;
8969                }
8970            }
8971            if (!PackageHelper.renameSdDir(cid, newCacheId)) {
8972                Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
8973                        " which might be stale. Will try to clean up.");
8974                // Clean up the stale container and proceed to recreate.
8975                if (!PackageHelper.destroySdDir(newCacheId)) {
8976                    Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
8977                    return false;
8978                }
8979                // Successfully cleaned up stale container. Try to rename again.
8980                if (!PackageHelper.renameSdDir(cid, newCacheId)) {
8981                    Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
8982                            + " inspite of cleaning it up.");
8983                    return false;
8984                }
8985            }
8986            if (!PackageHelper.isContainerMounted(newCacheId)) {
8987                Slog.w(TAG, "Mounting container " + newCacheId);
8988                newCachePath = PackageHelper.mountSdDir(newCacheId,
8989                        getEncryptKey(), Process.SYSTEM_UID);
8990            } else {
8991                newCachePath = PackageHelper.getSdDir(newCacheId);
8992            }
8993            if (newCachePath == null) {
8994                Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
8995                return false;
8996            }
8997            Log.i(TAG, "Succesfully renamed " + cid +
8998                    " to " + newCacheId +
8999                    " at new path: " + newCachePath);
9000            cid = newCacheId;
9001            setCachePath(newCachePath);
9002            return true;
9003        }
9004
9005        private void setCachePath(String newCachePath) {
9006            File cachePath = new File(newCachePath);
9007            libraryPath = new File(cachePath, LIB_DIR_NAME).getPath();
9008            packagePath = new File(cachePath, RES_FILE_NAME).getPath();
9009
9010            if (isFwdLocked()) {
9011                resourcePath = new File(cachePath, PUBLIC_RES_FILE_NAME).getPath();
9012            } else {
9013                resourcePath = packagePath;
9014            }
9015        }
9016
9017        int doPostInstall(int status, int uid) {
9018            if (status != PackageManager.INSTALL_SUCCEEDED) {
9019                cleanUp();
9020            } else {
9021                final int groupOwner;
9022                final String protectedFile;
9023                if (isFwdLocked()) {
9024                    groupOwner = UserHandle.getSharedAppGid(uid);
9025                    protectedFile = RES_FILE_NAME;
9026                } else {
9027                    groupOwner = -1;
9028                    protectedFile = null;
9029                }
9030
9031                if (uid < Process.FIRST_APPLICATION_UID
9032                        || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
9033                    Slog.e(TAG, "Failed to finalize " + cid);
9034                    PackageHelper.destroySdDir(cid);
9035                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
9036                }
9037
9038                boolean mounted = PackageHelper.isContainerMounted(cid);
9039                if (!mounted) {
9040                    PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
9041                }
9042            }
9043            return status;
9044        }
9045
9046        private void cleanUp() {
9047            if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
9048
9049            // Destroy secure container
9050            PackageHelper.destroySdDir(cid);
9051        }
9052
9053        void cleanUpResourcesLI() {
9054            String sourceFile = getCodePath();
9055            // Remove dex file
9056            int retCode = mInstaller.rmdex(sourceFile);
9057            if (retCode < 0) {
9058                Slog.w(TAG, "Couldn't remove dex file for package: "
9059                        + " at location "
9060                        + sourceFile.toString() + ", retcode=" + retCode);
9061                // we don't consider this to be a failure of the core package deletion
9062            }
9063            cleanUp();
9064        }
9065
9066        boolean matchContainer(String app) {
9067            if (cid.startsWith(app)) {
9068                return true;
9069            }
9070            return false;
9071        }
9072
9073        String getPackageName() {
9074            return getAsecPackageName(cid);
9075        }
9076
9077        boolean doPostDeleteLI(boolean delete) {
9078            boolean ret = false;
9079            boolean mounted = PackageHelper.isContainerMounted(cid);
9080            if (mounted) {
9081                // Unmount first
9082                ret = PackageHelper.unMountSdDir(cid);
9083            }
9084            if (ret && delete) {
9085                cleanUpResourcesLI();
9086            }
9087            return ret;
9088        }
9089
9090        @Override
9091        int doPreCopy() {
9092            if (isFwdLocked()) {
9093                if (!PackageHelper.fixSdPermissions(cid,
9094                        getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) {
9095                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
9096                }
9097            }
9098
9099            return PackageManager.INSTALL_SUCCEEDED;
9100        }
9101
9102        @Override
9103        int doPostCopy(int uid) {
9104            if (isFwdLocked()) {
9105                if (uid < Process.FIRST_APPLICATION_UID
9106                        || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
9107                                RES_FILE_NAME)) {
9108                    Slog.e(TAG, "Failed to finalize " + cid);
9109                    PackageHelper.destroySdDir(cid);
9110                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
9111                }
9112            }
9113
9114            return PackageManager.INSTALL_SUCCEEDED;
9115        }
9116    };
9117
9118    static String getAsecPackageName(String packageCid) {
9119        int idx = packageCid.lastIndexOf("-");
9120        if (idx == -1) {
9121            return packageCid;
9122        }
9123        return packageCid.substring(0, idx);
9124    }
9125
9126    // Utility method used to create code paths based on package name and available index.
9127    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
9128        String idxStr = "";
9129        int idx = 1;
9130        // Fall back to default value of idx=1 if prefix is not
9131        // part of oldCodePath
9132        if (oldCodePath != null) {
9133            String subStr = oldCodePath;
9134            // Drop the suffix right away
9135            if (subStr.endsWith(suffix)) {
9136                subStr = subStr.substring(0, subStr.length() - suffix.length());
9137            }
9138            // If oldCodePath already contains prefix find out the
9139            // ending index to either increment or decrement.
9140            int sidx = subStr.lastIndexOf(prefix);
9141            if (sidx != -1) {
9142                subStr = subStr.substring(sidx + prefix.length());
9143                if (subStr != null) {
9144                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
9145                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
9146                    }
9147                    try {
9148                        idx = Integer.parseInt(subStr);
9149                        if (idx <= 1) {
9150                            idx++;
9151                        } else {
9152                            idx--;
9153                        }
9154                    } catch(NumberFormatException e) {
9155                    }
9156                }
9157            }
9158        }
9159        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
9160        return prefix + idxStr;
9161    }
9162
9163    // Utility method used to ignore ADD/REMOVE events
9164    // by directory observer.
9165    private static boolean ignoreCodePath(String fullPathStr) {
9166        String apkName = getApkName(fullPathStr);
9167        int idx = apkName.lastIndexOf(INSTALL_PACKAGE_SUFFIX);
9168        if (idx != -1 && ((idx+1) < apkName.length())) {
9169            // Make sure the package ends with a numeral
9170            String version = apkName.substring(idx+1);
9171            try {
9172                Integer.parseInt(version);
9173                return true;
9174            } catch (NumberFormatException e) {}
9175        }
9176        return false;
9177    }
9178
9179    // Utility method that returns the relative package path with respect
9180    // to the installation directory. Like say for /data/data/com.test-1.apk
9181    // string com.test-1 is returned.
9182    static String getApkName(String codePath) {
9183        if (codePath == null) {
9184            return null;
9185        }
9186        int sidx = codePath.lastIndexOf("/");
9187        int eidx = codePath.lastIndexOf(".");
9188        if (eidx == -1) {
9189            eidx = codePath.length();
9190        } else if (eidx == 0) {
9191            Slog.w(TAG, " Invalid code path, "+ codePath + " Not a valid apk name");
9192            return null;
9193        }
9194        return codePath.substring(sidx+1, eidx);
9195    }
9196
9197    class PackageInstalledInfo {
9198        String name;
9199        int uid;
9200        // The set of users that originally had this package installed.
9201        int[] origUsers;
9202        // The set of users that now have this package installed.
9203        int[] newUsers;
9204        PackageParser.Package pkg;
9205        int returnCode;
9206        PackageRemovedInfo removedInfo;
9207
9208        // In some error cases we want to convey more info back to the observer
9209        String origPackage;
9210        String origPermission;
9211    }
9212
9213    /*
9214     * Install a non-existing package.
9215     */
9216    private void installNewPackageLI(PackageParser.Package pkg,
9217            int parseFlags, int scanMode, UserHandle user,
9218            String installerPackageName, PackageInstalledInfo res) {
9219        // Remember this for later, in case we need to rollback this install
9220        String pkgName = pkg.packageName;
9221
9222        if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
9223        boolean dataDirExists = getDataPathForPackage(pkg.packageName, 0).exists();
9224        synchronized(mPackages) {
9225            if (mSettings.mRenamedPackages.containsKey(pkgName)) {
9226                // A package with the same name is already installed, though
9227                // it has been renamed to an older name.  The package we
9228                // are trying to install should be installed as an update to
9229                // the existing one, but that has not been requested, so bail.
9230                Slog.w(TAG, "Attempt to re-install " + pkgName
9231                        + " without first uninstalling package running as "
9232                        + mSettings.mRenamedPackages.get(pkgName));
9233                res.returnCode = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
9234                return;
9235            }
9236            if (mPackages.containsKey(pkgName) || mAppDirs.containsKey(pkg.mPath)) {
9237                // Don't allow installation over an existing package with the same name.
9238                Slog.w(TAG, "Attempt to re-install " + pkgName
9239                        + " without first uninstalling.");
9240                res.returnCode = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
9241                return;
9242            }
9243        }
9244        mLastScanError = PackageManager.INSTALL_SUCCEEDED;
9245        PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanMode,
9246                System.currentTimeMillis(), user);
9247        if (newPackage == null) {
9248            Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath);
9249            if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
9250                res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK;
9251            }
9252        } else {
9253            updateSettingsLI(newPackage,
9254                    installerPackageName,
9255                    null, null,
9256                    res);
9257            // delete the partially installed application. the data directory will have to be
9258            // restored if it was already existing
9259            if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
9260                // remove package from internal structures.  Note that we want deletePackageX to
9261                // delete the package data and cache directories that it created in
9262                // scanPackageLocked, unless those directories existed before we even tried to
9263                // install.
9264                deletePackageLI(pkgName, UserHandle.ALL, false, null, null,
9265                        dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0,
9266                                res.removedInfo, true);
9267            }
9268        }
9269    }
9270
9271    private void replacePackageLI(PackageParser.Package pkg,
9272            int parseFlags, int scanMode, UserHandle user,
9273            String installerPackageName, PackageInstalledInfo res) {
9274
9275        PackageParser.Package oldPackage;
9276        String pkgName = pkg.packageName;
9277        int[] allUsers;
9278        boolean[] perUserInstalled;
9279
9280        // First find the old package info and check signatures
9281        synchronized(mPackages) {
9282            oldPackage = mPackages.get(pkgName);
9283            if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
9284            if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
9285                    != PackageManager.SIGNATURE_MATCH) {
9286                Slog.w(TAG, "New package has a different signature: " + pkgName);
9287                res.returnCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
9288                return;
9289            }
9290
9291            // In case of rollback, remember per-user/profile install state
9292            PackageSetting ps = mSettings.mPackages.get(pkgName);
9293            allUsers = sUserManager.getUserIds();
9294            perUserInstalled = new boolean[allUsers.length];
9295            for (int i = 0; i < allUsers.length; i++) {
9296                perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
9297            }
9298        }
9299        boolean sysPkg = (isSystemApp(oldPackage));
9300        if (sysPkg) {
9301            replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanMode,
9302                    user, allUsers, perUserInstalled, installerPackageName, res);
9303        } else {
9304            replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanMode,
9305                    user, allUsers, perUserInstalled, installerPackageName, res);
9306        }
9307    }
9308
9309    private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage,
9310            PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user,
9311            int[] allUsers, boolean[] perUserInstalled,
9312            String installerPackageName, PackageInstalledInfo res) {
9313        PackageParser.Package newPackage = null;
9314        String pkgName = deletedPackage.packageName;
9315        boolean deletedPkg = true;
9316        boolean updatedSettings = false;
9317
9318        if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
9319                + deletedPackage);
9320        long origUpdateTime;
9321        if (pkg.mExtras != null) {
9322            origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime;
9323        } else {
9324            origUpdateTime = 0;
9325        }
9326
9327        // First delete the existing package while retaining the data directory
9328        if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA,
9329                res.removedInfo, true)) {
9330            // If the existing package wasn't successfully deleted
9331            res.returnCode = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
9332            deletedPkg = false;
9333        } else {
9334            // Successfully deleted the old package. Now proceed with re-installation
9335            mLastScanError = PackageManager.INSTALL_SUCCEEDED;
9336            newPackage = scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_TIME,
9337                    System.currentTimeMillis(), user);
9338            if (newPackage == null) {
9339                Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath);
9340                if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
9341                    res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK;
9342                }
9343            } else {
9344                updateSettingsLI(newPackage,
9345                        installerPackageName,
9346                        allUsers, perUserInstalled,
9347                        res);
9348                updatedSettings = true;
9349            }
9350        }
9351
9352        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
9353            // remove package from internal structures.  Note that we want deletePackageX to
9354            // delete the package data and cache directories that it created in
9355            // scanPackageLocked, unless those directories existed before we even tried to
9356            // install.
9357            if(updatedSettings) {
9358                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
9359                deletePackageLI(
9360                        pkgName, null, true, allUsers, perUserInstalled,
9361                        PackageManager.DELETE_KEEP_DATA,
9362                                res.removedInfo, true);
9363            }
9364            // Since we failed to install the new package we need to restore the old
9365            // package that we deleted.
9366            if(deletedPkg) {
9367                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
9368                File restoreFile = new File(deletedPackage.mPath);
9369                // Parse old package
9370                boolean oldOnSd = isExternal(deletedPackage);
9371                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
9372                        (isForwardLocked(deletedPackage) ? PackageParser.PARSE_FORWARD_LOCK : 0) |
9373                        (oldOnSd ? PackageParser.PARSE_ON_SDCARD : 0);
9374                int oldScanMode = (oldOnSd ? 0 : SCAN_MONITOR) | SCAN_UPDATE_SIGNATURE
9375                        | SCAN_UPDATE_TIME;
9376                if (scanPackageLI(restoreFile, oldParseFlags, oldScanMode,
9377                        origUpdateTime, null) == null) {
9378                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade");
9379                    return;
9380                }
9381                // Restore of old package succeeded. Update permissions.
9382                // writer
9383                synchronized (mPackages) {
9384                    updatePermissionsLPw(deletedPackage.packageName, deletedPackage,
9385                            UPDATE_PERMISSIONS_ALL);
9386                    // can downgrade to reader
9387                    mSettings.writeLPr();
9388                }
9389                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
9390            }
9391        }
9392    }
9393
9394    private void replaceSystemPackageLI(PackageParser.Package deletedPackage,
9395            PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user,
9396            int[] allUsers, boolean[] perUserInstalled,
9397            String installerPackageName, PackageInstalledInfo res) {
9398        if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
9399                + ", old=" + deletedPackage);
9400        PackageParser.Package newPackage = null;
9401        boolean updatedSettings = false;
9402        parseFlags |= PackageManager.INSTALL_REPLACE_EXISTING |
9403                PackageParser.PARSE_IS_SYSTEM;
9404        if ((deletedPackage.applicationInfo.flags&ApplicationInfo.FLAG_PRIVILEGED) != 0) {
9405            parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
9406        }
9407        String packageName = deletedPackage.packageName;
9408        res.returnCode = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
9409        if (packageName == null) {
9410            Slog.w(TAG, "Attempt to delete null packageName.");
9411            return;
9412        }
9413        PackageParser.Package oldPkg;
9414        PackageSetting oldPkgSetting;
9415        // reader
9416        synchronized (mPackages) {
9417            oldPkg = mPackages.get(packageName);
9418            oldPkgSetting = mSettings.mPackages.get(packageName);
9419            if((oldPkg == null) || (oldPkg.applicationInfo == null) ||
9420                    (oldPkgSetting == null)) {
9421                Slog.w(TAG, "Couldn't find package:"+packageName+" information");
9422                return;
9423            }
9424        }
9425
9426        killApplication(packageName, oldPkg.applicationInfo.uid, "replace sys pkg");
9427
9428        res.removedInfo.uid = oldPkg.applicationInfo.uid;
9429        res.removedInfo.removedPackage = packageName;
9430        // Remove existing system package
9431        removePackageLI(oldPkgSetting, true);
9432        // writer
9433        synchronized (mPackages) {
9434            if (!mSettings.disableSystemPackageLPw(packageName) && deletedPackage != null) {
9435                // We didn't need to disable the .apk as a current system package,
9436                // which means we are replacing another update that is already
9437                // installed.  We need to make sure to delete the older one's .apk.
9438                res.removedInfo.args = createInstallArgs(0,
9439                        deletedPackage.applicationInfo.sourceDir,
9440                        deletedPackage.applicationInfo.publicSourceDir,
9441                        deletedPackage.applicationInfo.nativeLibraryDir);
9442            } else {
9443                res.removedInfo.args = null;
9444            }
9445        }
9446
9447        // Successfully disabled the old package. Now proceed with re-installation
9448        res.returnCode = mLastScanError = PackageManager.INSTALL_SUCCEEDED;
9449        pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
9450        newPackage = scanPackageLI(pkg, parseFlags, scanMode, 0, user);
9451        if (newPackage == null) {
9452            Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath);
9453            if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
9454                res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK;
9455            }
9456        } else {
9457            if (newPackage.mExtras != null) {
9458                final PackageSetting newPkgSetting = (PackageSetting)newPackage.mExtras;
9459                newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime;
9460                newPkgSetting.lastUpdateTime = System.currentTimeMillis();
9461
9462                // is the update attempting to change shared user? that isn't going to work...
9463                if (oldPkgSetting.sharedUser != newPkgSetting.sharedUser) {
9464                    Slog.w(TAG, "Forbidding shared user change from " + oldPkgSetting.sharedUser
9465                            + " to " + newPkgSetting.sharedUser);
9466                    res.returnCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
9467                    updatedSettings = true;
9468                }
9469            }
9470
9471            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
9472                updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res);
9473                updatedSettings = true;
9474            }
9475        }
9476
9477        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
9478            // Re installation failed. Restore old information
9479            // Remove new pkg information
9480            if (newPackage != null) {
9481                removeInstalledPackageLI(newPackage, true);
9482            }
9483            // Add back the old system package
9484            scanPackageLI(oldPkg, parseFlags, SCAN_MONITOR | SCAN_UPDATE_SIGNATURE, 0, user);
9485            // Restore the old system information in Settings
9486            synchronized(mPackages) {
9487                if (updatedSettings) {
9488                    mSettings.enableSystemPackageLPw(packageName);
9489                    mSettings.setInstallerPackageName(packageName,
9490                            oldPkgSetting.installerPackageName);
9491                }
9492                mSettings.writeLPr();
9493            }
9494        }
9495    }
9496
9497    // Utility method used to move dex files during install.
9498    private int moveDexFilesLI(PackageParser.Package newPackage) {
9499        int retCode;
9500        if ((newPackage.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
9501            retCode = mInstaller.movedex(newPackage.mScanPath, newPackage.mPath);
9502            if (retCode != 0) {
9503                if (mNoDexOpt) {
9504                    /*
9505                     * If we're in an engineering build, programs are lazily run
9506                     * through dexopt. If the .dex file doesn't exist yet, it
9507                     * will be created when the program is run next.
9508                     */
9509                    Slog.i(TAG, "dex file doesn't exist, skipping move: " + newPackage.mPath);
9510                } else {
9511                    Slog.e(TAG, "Couldn't rename dex file: " + newPackage.mPath);
9512                    return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
9513                }
9514            }
9515        }
9516        return PackageManager.INSTALL_SUCCEEDED;
9517    }
9518
9519    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
9520            int[] allUsers, boolean[] perUserInstalled,
9521            PackageInstalledInfo res) {
9522        String pkgName = newPackage.packageName;
9523        synchronized (mPackages) {
9524            //write settings. the installStatus will be incomplete at this stage.
9525            //note that the new package setting would have already been
9526            //added to mPackages. It hasn't been persisted yet.
9527            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
9528            mSettings.writeLPr();
9529        }
9530
9531        if ((res.returnCode = moveDexFilesLI(newPackage))
9532                != PackageManager.INSTALL_SUCCEEDED) {
9533            // Discontinue if moving dex files failed.
9534            return;
9535        }
9536
9537        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.mPath);
9538
9539        synchronized (mPackages) {
9540            updatePermissionsLPw(newPackage.packageName, newPackage,
9541                    UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
9542                            ? UPDATE_PERMISSIONS_ALL : 0));
9543            // For system-bundled packages, we assume that installing an upgraded version
9544            // of the package implies that the user actually wants to run that new code,
9545            // so we enable the package.
9546            if (isSystemApp(newPackage)) {
9547                // NB: implicit assumption that system package upgrades apply to all users
9548                if (DEBUG_INSTALL) {
9549                    Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
9550                }
9551                PackageSetting ps = mSettings.mPackages.get(pkgName);
9552                if (ps != null) {
9553                    if (res.origUsers != null) {
9554                        for (int userHandle : res.origUsers) {
9555                            ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
9556                                    userHandle, installerPackageName);
9557                        }
9558                    }
9559                    // Also convey the prior install/uninstall state
9560                    if (allUsers != null && perUserInstalled != null) {
9561                        for (int i = 0; i < allUsers.length; i++) {
9562                            if (DEBUG_INSTALL) {
9563                                Slog.d(TAG, "    user " + allUsers[i]
9564                                        + " => " + perUserInstalled[i]);
9565                            }
9566                            ps.setInstalled(perUserInstalled[i], allUsers[i]);
9567                        }
9568                        // these install state changes will be persisted in the
9569                        // upcoming call to mSettings.writeLPr().
9570                    }
9571                }
9572            }
9573            res.name = pkgName;
9574            res.uid = newPackage.applicationInfo.uid;
9575            res.pkg = newPackage;
9576            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
9577            mSettings.setInstallerPackageName(pkgName, installerPackageName);
9578            res.returnCode = PackageManager.INSTALL_SUCCEEDED;
9579            //to update install status
9580            mSettings.writeLPr();
9581        }
9582    }
9583
9584    private void installPackageLI(InstallArgs args,
9585            boolean newInstall, PackageInstalledInfo res) {
9586        int pFlags = args.flags;
9587        String installerPackageName = args.installerPackageName;
9588        File tmpPackageFile = new File(args.getCodePath());
9589        boolean forwardLocked = ((pFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
9590        boolean onSd = ((pFlags & PackageManager.INSTALL_EXTERNAL) != 0);
9591        boolean replace = false;
9592        int scanMode = (onSd ? 0 : SCAN_MONITOR) | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE
9593                | (newInstall ? SCAN_NEW_INSTALL : 0);
9594        // Result object to be returned
9595        res.returnCode = PackageManager.INSTALL_SUCCEEDED;
9596
9597        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
9598        // Retrieve PackageSettings and parse package
9599        int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
9600                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
9601                | (onSd ? PackageParser.PARSE_ON_SDCARD : 0);
9602        PackageParser pp = new PackageParser(tmpPackageFile.getPath());
9603        pp.setSeparateProcesses(mSeparateProcesses);
9604        final PackageParser.Package pkg = pp.parsePackage(tmpPackageFile,
9605                null, mMetrics, parseFlags);
9606        if (pkg == null) {
9607            res.returnCode = pp.getParseError();
9608            return;
9609        }
9610        String pkgName = res.name = pkg.packageName;
9611        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
9612            if ((pFlags&PackageManager.INSTALL_ALLOW_TEST) == 0) {
9613                res.returnCode = PackageManager.INSTALL_FAILED_TEST_ONLY;
9614                return;
9615            }
9616        }
9617        if (!pp.collectCertificates(pkg, parseFlags)) {
9618            res.returnCode = pp.getParseError();
9619            return;
9620        }
9621
9622        /* If the installer passed in a manifest digest, compare it now. */
9623        if (args.manifestDigest != null) {
9624            if (DEBUG_INSTALL) {
9625                final String parsedManifest = pkg.manifestDigest == null ? "null"
9626                        : pkg.manifestDigest.toString();
9627                Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. "
9628                        + parsedManifest);
9629            }
9630
9631            if (!args.manifestDigest.equals(pkg.manifestDigest)) {
9632                res.returnCode = PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
9633                return;
9634            }
9635        } else if (DEBUG_INSTALL) {
9636            final String parsedManifest = pkg.manifestDigest == null
9637                    ? "null" : pkg.manifestDigest.toString();
9638            Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest);
9639        }
9640
9641        // Get rid of all references to package scan path via parser.
9642        pp = null;
9643        String oldCodePath = null;
9644        boolean systemApp = false;
9645        synchronized (mPackages) {
9646            // Check whether the newly-scanned package wants to define an already-defined perm
9647            int N = pkg.permissions.size();
9648            for (int i = 0; i < N; i++) {
9649                PackageParser.Permission perm = pkg.permissions.get(i);
9650                BasePermission bp = mSettings.mPermissions.get(perm.info.name);
9651                if (bp != null) {
9652                    // If the defining package is signed with our cert, it's okay.  This
9653                    // also includes the "updating the same package" case, of course.
9654                    if (compareSignatures(bp.packageSetting.signatures.mSignatures,
9655                            pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
9656                        Slog.w(TAG, "Package " + pkg.packageName
9657                                + " attempting to redeclare permission " + perm.info.name
9658                                + " already owned by " + bp.sourcePackage);
9659                        res.returnCode = PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
9660                        res.origPermission = perm.info.name;
9661                        res.origPackage = bp.sourcePackage;
9662                        return;
9663                    }
9664                }
9665            }
9666
9667            // Check if installing already existing package
9668            if ((pFlags&PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
9669                String oldName = mSettings.mRenamedPackages.get(pkgName);
9670                if (pkg.mOriginalPackages != null
9671                        && pkg.mOriginalPackages.contains(oldName)
9672                        && mPackages.containsKey(oldName)) {
9673                    // This package is derived from an original package,
9674                    // and this device has been updating from that original
9675                    // name.  We must continue using the original name, so
9676                    // rename the new package here.
9677                    pkg.setPackageName(oldName);
9678                    pkgName = pkg.packageName;
9679                    replace = true;
9680                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
9681                            + oldName + " pkgName=" + pkgName);
9682                } else if (mPackages.containsKey(pkgName)) {
9683                    // This package, under its official name, already exists
9684                    // on the device; we should replace it.
9685                    replace = true;
9686                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
9687                }
9688            }
9689            PackageSetting ps = mSettings.mPackages.get(pkgName);
9690            if (ps != null) {
9691                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
9692                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
9693                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
9694                    systemApp = (ps.pkg.applicationInfo.flags &
9695                            ApplicationInfo.FLAG_SYSTEM) != 0;
9696                }
9697                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
9698            }
9699        }
9700
9701        if (systemApp && onSd) {
9702            // Disable updates to system apps on sdcard
9703            Slog.w(TAG, "Cannot install updates to system apps on sdcard");
9704            res.returnCode = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
9705            return;
9706        }
9707
9708        if (!args.doRename(res.returnCode, pkgName, oldCodePath)) {
9709            res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
9710            return;
9711        }
9712        // Set application objects path explicitly after the rename
9713        setApplicationInfoPaths(pkg, args.getCodePath(), args.getResourcePath());
9714        pkg.applicationInfo.nativeLibraryDir = args.getNativeLibraryPath();
9715        if (replace) {
9716            replacePackageLI(pkg, parseFlags, scanMode, args.user,
9717                    installerPackageName, res);
9718        } else {
9719            installNewPackageLI(pkg, parseFlags, scanMode | SCAN_DELETE_DATA_ON_FAILURES, args.user,
9720                    installerPackageName, res);
9721        }
9722        synchronized (mPackages) {
9723            final PackageSetting ps = mSettings.mPackages.get(pkgName);
9724            if (ps != null) {
9725                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
9726            }
9727        }
9728    }
9729
9730    private static boolean isForwardLocked(PackageParser.Package pkg) {
9731        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
9732    }
9733
9734
9735    private boolean isForwardLocked(PackageSetting ps) {
9736        return (ps.pkgFlags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
9737    }
9738
9739    private static boolean isExternal(PackageParser.Package pkg) {
9740        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
9741    }
9742
9743    private static boolean isExternal(PackageSetting ps) {
9744        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
9745    }
9746
9747    private static boolean isSystemApp(PackageParser.Package pkg) {
9748        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
9749    }
9750
9751    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
9752        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_PRIVILEGED) != 0;
9753    }
9754
9755    private static boolean isSystemApp(ApplicationInfo info) {
9756        return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
9757    }
9758
9759    private static boolean isSystemApp(PackageSetting ps) {
9760        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
9761    }
9762
9763    private static boolean isUpdatedSystemApp(PackageSetting ps) {
9764        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
9765    }
9766
9767    private static boolean isUpdatedSystemApp(PackageParser.Package pkg) {
9768        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
9769    }
9770
9771    private int packageFlagsToInstallFlags(PackageSetting ps) {
9772        int installFlags = 0;
9773        if (isExternal(ps)) {
9774            installFlags |= PackageManager.INSTALL_EXTERNAL;
9775        }
9776        if (isForwardLocked(ps)) {
9777            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
9778        }
9779        return installFlags;
9780    }
9781
9782    private void deleteTempPackageFiles() {
9783        final FilenameFilter filter = new FilenameFilter() {
9784            public boolean accept(File dir, String name) {
9785                return name.startsWith("vmdl") && name.endsWith(".tmp");
9786            }
9787        };
9788        deleteTempPackageFilesInDirectory(mAppInstallDir, filter);
9789        deleteTempPackageFilesInDirectory(mDrmAppPrivateInstallDir, filter);
9790    }
9791
9792    private static final void deleteTempPackageFilesInDirectory(File directory,
9793            FilenameFilter filter) {
9794        final String[] tmpFilesList = directory.list(filter);
9795        if (tmpFilesList == null) {
9796            return;
9797        }
9798        for (int i = 0; i < tmpFilesList.length; i++) {
9799            final File tmpFile = new File(directory, tmpFilesList[i]);
9800            tmpFile.delete();
9801        }
9802    }
9803
9804    private File createTempPackageFile(File installDir) {
9805        File tmpPackageFile;
9806        try {
9807            tmpPackageFile = File.createTempFile("vmdl", ".tmp", installDir);
9808        } catch (IOException e) {
9809            Slog.e(TAG, "Couldn't create temp file for downloaded package file.");
9810            return null;
9811        }
9812        try {
9813            FileUtils.setPermissions(
9814                    tmpPackageFile.getCanonicalPath(), FileUtils.S_IRUSR|FileUtils.S_IWUSR,
9815                    -1, -1);
9816            if (!SELinux.restorecon(tmpPackageFile)) {
9817                return null;
9818            }
9819        } catch (IOException e) {
9820            Slog.e(TAG, "Trouble getting the canoncical path for a temp file.");
9821            return null;
9822        }
9823        return tmpPackageFile;
9824    }
9825
9826    @Override
9827    public void deletePackageAsUser(final String packageName,
9828                                    final IPackageDeleteObserver observer,
9829                                    final int userId, final int flags) {
9830        mContext.enforceCallingOrSelfPermission(
9831                android.Manifest.permission.DELETE_PACKAGES, null);
9832        final int uid = Binder.getCallingUid();
9833        if (UserHandle.getUserId(uid) != userId) {
9834            mContext.enforceCallingPermission(
9835                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9836                    "deletePackage for user " + userId);
9837        }
9838        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
9839            try {
9840                observer.packageDeleted(packageName, PackageManager.DELETE_FAILED_USER_RESTRICTED);
9841            } catch (RemoteException re) {
9842            }
9843            return;
9844        }
9845
9846        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId);
9847        // Queue up an async operation since the package deletion may take a little while.
9848        mHandler.post(new Runnable() {
9849            public void run() {
9850                mHandler.removeCallbacks(this);
9851                final int returnCode = deletePackageX(packageName, userId, flags);
9852                if (observer != null) {
9853                    try {
9854                        observer.packageDeleted(packageName, returnCode);
9855                    } catch (RemoteException e) {
9856                        Log.i(TAG, "Observer no longer exists.");
9857                    } //end catch
9858                } //end if
9859            } //end run
9860        });
9861    }
9862
9863    private boolean isPackageDeviceAdmin(String packageName, int userId) {
9864        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
9865                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
9866        try {
9867            if (dpm != null && (dpm.packageHasActiveAdmins(packageName, userId)
9868                    || dpm.isDeviceOwner(packageName))) {
9869                return true;
9870            }
9871        } catch (RemoteException e) {
9872        }
9873        return false;
9874    }
9875
9876    /**
9877     *  This method is an internal method that could be get invoked either
9878     *  to delete an installed package or to clean up a failed installation.
9879     *  After deleting an installed package, a broadcast is sent to notify any
9880     *  listeners that the package has been installed. For cleaning up a failed
9881     *  installation, the broadcast is not necessary since the package's
9882     *  installation wouldn't have sent the initial broadcast either
9883     *  The key steps in deleting a package are
9884     *  deleting the package information in internal structures like mPackages,
9885     *  deleting the packages base directories through installd
9886     *  updating mSettings to reflect current status
9887     *  persisting settings for later use
9888     *  sending a broadcast if necessary
9889     */
9890    private int deletePackageX(String packageName, int userId, int flags) {
9891        final PackageRemovedInfo info = new PackageRemovedInfo();
9892        final boolean res;
9893
9894        if (isPackageDeviceAdmin(packageName, userId)) {
9895            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
9896            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
9897        }
9898
9899        boolean removedForAllUsers = false;
9900        boolean systemUpdate = false;
9901
9902        // for the uninstall-updates case and restricted profiles, remember the per-
9903        // userhandle installed state
9904        int[] allUsers;
9905        boolean[] perUserInstalled;
9906        synchronized (mPackages) {
9907            PackageSetting ps = mSettings.mPackages.get(packageName);
9908            allUsers = sUserManager.getUserIds();
9909            perUserInstalled = new boolean[allUsers.length];
9910            for (int i = 0; i < allUsers.length; i++) {
9911                perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
9912            }
9913        }
9914
9915        synchronized (mInstallLock) {
9916            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
9917            res = deletePackageLI(packageName,
9918                    (flags & PackageManager.DELETE_ALL_USERS) != 0
9919                            ? UserHandle.ALL : new UserHandle(userId),
9920                    true, allUsers, perUserInstalled,
9921                    flags | REMOVE_CHATTY, info, true);
9922            systemUpdate = info.isRemovedPackageSystemUpdate;
9923            if (res && !systemUpdate && mPackages.get(packageName) == null) {
9924                removedForAllUsers = true;
9925            }
9926            if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate
9927                    + " removedForAllUsers=" + removedForAllUsers);
9928        }
9929
9930        if (res) {
9931            info.sendBroadcast(true, systemUpdate, removedForAllUsers);
9932
9933            // If the removed package was a system update, the old system package
9934            // was re-enabled; we need to broadcast this information
9935            if (systemUpdate) {
9936                Bundle extras = new Bundle(1);
9937                extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0
9938                        ? info.removedAppId : info.uid);
9939                extras.putBoolean(Intent.EXTRA_REPLACING, true);
9940
9941                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
9942                        extras, null, null, null);
9943                sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
9944                        extras, null, null, null);
9945                sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
9946                        null, packageName, null, null);
9947            }
9948        }
9949        // Force a gc here.
9950        Runtime.getRuntime().gc();
9951        // Delete the resources here after sending the broadcast to let
9952        // other processes clean up before deleting resources.
9953        if (info.args != null) {
9954            synchronized (mInstallLock) {
9955                info.args.doPostDeleteLI(true);
9956            }
9957        }
9958
9959        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
9960    }
9961
9962    static class PackageRemovedInfo {
9963        String removedPackage;
9964        int uid = -1;
9965        int removedAppId = -1;
9966        int[] removedUsers = null;
9967        boolean isRemovedPackageSystemUpdate = false;
9968        // Clean up resources deleted packages.
9969        InstallArgs args = null;
9970
9971        void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) {
9972            Bundle extras = new Bundle(1);
9973            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
9974            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove);
9975            if (replacing) {
9976                extras.putBoolean(Intent.EXTRA_REPLACING, true);
9977            }
9978            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
9979            if (removedPackage != null) {
9980                sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
9981                        extras, null, null, removedUsers);
9982                if (fullRemove && !replacing) {
9983                    sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage,
9984                            extras, null, null, removedUsers);
9985                }
9986            }
9987            if (removedAppId >= 0) {
9988                sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null,
9989                        removedUsers);
9990            }
9991        }
9992    }
9993
9994    /*
9995     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
9996     * flag is not set, the data directory is removed as well.
9997     * make sure this flag is set for partially installed apps. If not its meaningless to
9998     * delete a partially installed application.
9999     */
10000    private void removePackageDataLI(PackageSetting ps,
10001            int[] allUserHandles, boolean[] perUserInstalled,
10002            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
10003        String packageName = ps.name;
10004        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
10005        removePackageLI(ps, (flags&REMOVE_CHATTY) != 0);
10006        // Retrieve object to delete permissions for shared user later on
10007        final PackageSetting deletedPs;
10008        // reader
10009        synchronized (mPackages) {
10010            deletedPs = mSettings.mPackages.get(packageName);
10011            if (outInfo != null) {
10012                outInfo.removedPackage = packageName;
10013                outInfo.removedUsers = deletedPs != null
10014                        ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
10015                        : null;
10016            }
10017        }
10018        if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
10019            removeDataDirsLI(packageName);
10020            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
10021        }
10022        // writer
10023        synchronized (mPackages) {
10024            if (deletedPs != null) {
10025                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
10026                    if (outInfo != null) {
10027                        outInfo.removedAppId = mSettings.removePackageLPw(packageName);
10028                    }
10029                    if (deletedPs != null) {
10030                        updatePermissionsLPw(deletedPs.name, null, 0);
10031                        if (deletedPs.sharedUser != null) {
10032                            // remove permissions associated with package
10033                            mSettings.updateSharedUserPermsLPw(deletedPs, mGlobalGids);
10034                        }
10035                    }
10036                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
10037                }
10038                // make sure to preserve per-user disabled state if this removal was just
10039                // a downgrade of a system app to the factory package
10040                if (allUserHandles != null && perUserInstalled != null) {
10041                    if (DEBUG_REMOVE) {
10042                        Slog.d(TAG, "Propagating install state across downgrade");
10043                    }
10044                    for (int i = 0; i < allUserHandles.length; i++) {
10045                        if (DEBUG_REMOVE) {
10046                            Slog.d(TAG, "    user " + allUserHandles[i]
10047                                    + " => " + perUserInstalled[i]);
10048                        }
10049                        ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
10050                    }
10051                }
10052            }
10053            // can downgrade to reader
10054            if (writeSettings) {
10055                // Save settings now
10056                mSettings.writeLPr();
10057            }
10058        }
10059        if (outInfo != null) {
10060            // A user ID was deleted here. Go through all users and remove it
10061            // from KeyStore.
10062            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId);
10063        }
10064    }
10065
10066    static boolean locationIsPrivileged(File path) {
10067        try {
10068            final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
10069                    .getCanonicalPath();
10070            return path.getCanonicalPath().startsWith(privilegedAppDir);
10071        } catch (IOException e) {
10072            Slog.e(TAG, "Unable to access code path " + path);
10073        }
10074        return false;
10075    }
10076
10077    /*
10078     * Tries to delete system package.
10079     */
10080    private boolean deleteSystemPackageLI(PackageSetting newPs,
10081            int[] allUserHandles, boolean[] perUserInstalled,
10082            int flags, PackageRemovedInfo outInfo, boolean writeSettings) {
10083        final boolean applyUserRestrictions
10084                = (allUserHandles != null) && (perUserInstalled != null);
10085        PackageSetting disabledPs = null;
10086        // Confirm if the system package has been updated
10087        // An updated system app can be deleted. This will also have to restore
10088        // the system pkg from system partition
10089        // reader
10090        synchronized (mPackages) {
10091            disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name);
10092        }
10093        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs
10094                + " disabledPs=" + disabledPs);
10095        if (disabledPs == null) {
10096            Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name);
10097            return false;
10098        } else if (DEBUG_REMOVE) {
10099            Slog.d(TAG, "Deleting system pkg from data partition");
10100        }
10101        if (DEBUG_REMOVE) {
10102            if (applyUserRestrictions) {
10103                Slog.d(TAG, "Remembering install states:");
10104                for (int i = 0; i < allUserHandles.length; i++) {
10105                    Slog.d(TAG, "   u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]);
10106                }
10107            }
10108        }
10109        // Delete the updated package
10110        outInfo.isRemovedPackageSystemUpdate = true;
10111        if (disabledPs.versionCode < newPs.versionCode) {
10112            // Delete data for downgrades
10113            flags &= ~PackageManager.DELETE_KEEP_DATA;
10114        } else {
10115            // Preserve data by setting flag
10116            flags |= PackageManager.DELETE_KEEP_DATA;
10117        }
10118        boolean ret = deleteInstalledPackageLI(newPs, true, flags,
10119                allUserHandles, perUserInstalled, outInfo, writeSettings);
10120        if (!ret) {
10121            return false;
10122        }
10123        // writer
10124        synchronized (mPackages) {
10125            // Reinstate the old system package
10126            mSettings.enableSystemPackageLPw(newPs.name);
10127            // Remove any native libraries from the upgraded package.
10128            NativeLibraryHelper.removeNativeBinariesLI(newPs.nativeLibraryPathString);
10129        }
10130        // Install the system package
10131        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
10132        int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM;
10133        if (locationIsPrivileged(disabledPs.codePath)) {
10134            parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
10135        }
10136        PackageParser.Package newPkg = scanPackageLI(disabledPs.codePath,
10137                parseFlags, SCAN_MONITOR | SCAN_NO_PATHS, 0, null);
10138
10139        if (newPkg == null) {
10140            Slog.w(TAG, "Failed to restore system package:" + newPs.name
10141                    + " with error:" + mLastScanError);
10142            return false;
10143        }
10144        // writer
10145        synchronized (mPackages) {
10146            PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
10147            setInternalAppNativeLibraryPath(newPkg, ps);
10148            updatePermissionsLPw(newPkg.packageName, newPkg,
10149                    UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
10150            if (applyUserRestrictions) {
10151                if (DEBUG_REMOVE) {
10152                    Slog.d(TAG, "Propagating install state across reinstall");
10153                }
10154                for (int i = 0; i < allUserHandles.length; i++) {
10155                    if (DEBUG_REMOVE) {
10156                        Slog.d(TAG, "    user " + allUserHandles[i]
10157                                + " => " + perUserInstalled[i]);
10158                    }
10159                    ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
10160                }
10161                // Regardless of writeSettings we need to ensure that this restriction
10162                // state propagation is persisted
10163                mSettings.writeAllUsersPackageRestrictionsLPr();
10164            }
10165            // can downgrade to reader here
10166            if (writeSettings) {
10167                mSettings.writeLPr();
10168            }
10169        }
10170        return true;
10171    }
10172
10173    private boolean deleteInstalledPackageLI(PackageSetting ps,
10174            boolean deleteCodeAndResources, int flags,
10175            int[] allUserHandles, boolean[] perUserInstalled,
10176            PackageRemovedInfo outInfo, boolean writeSettings) {
10177        if (outInfo != null) {
10178            outInfo.uid = ps.appId;
10179        }
10180
10181        // Delete package data from internal structures and also remove data if flag is set
10182        removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings);
10183
10184        // Delete application code and resources
10185        if (deleteCodeAndResources && (outInfo != null)) {
10186            outInfo.args = createInstallArgs(packageFlagsToInstallFlags(ps), ps.codePathString,
10187                    ps.resourcePathString, ps.nativeLibraryPathString);
10188        }
10189        return true;
10190    }
10191
10192    /*
10193     * This method handles package deletion in general
10194     */
10195    private boolean deletePackageLI(String packageName, UserHandle user,
10196            boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled,
10197            int flags, PackageRemovedInfo outInfo,
10198            boolean writeSettings) {
10199        if (packageName == null) {
10200            Slog.w(TAG, "Attempt to delete null packageName.");
10201            return false;
10202        }
10203        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
10204        PackageSetting ps;
10205        boolean dataOnly = false;
10206        int removeUser = -1;
10207        int appId = -1;
10208        synchronized (mPackages) {
10209            ps = mSettings.mPackages.get(packageName);
10210            if (ps == null) {
10211                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
10212                return false;
10213            }
10214            if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
10215                    && user.getIdentifier() != UserHandle.USER_ALL) {
10216                // The caller is asking that the package only be deleted for a single
10217                // user.  To do this, we just mark its uninstalled state and delete
10218                // its data.  If this is a system app, we only allow this to happen if
10219                // they have set the special DELETE_SYSTEM_APP which requests different
10220                // semantics than normal for uninstalling system apps.
10221                if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user");
10222                ps.setUserState(user.getIdentifier(),
10223                        COMPONENT_ENABLED_STATE_DEFAULT,
10224                        false, //installed
10225                        true,  //stopped
10226                        true,  //notLaunched
10227                        false, //blocked
10228                        null, null, null);
10229                if (!isSystemApp(ps)) {
10230                    if (ps.isAnyInstalled(sUserManager.getUserIds())) {
10231                        // Other user still have this package installed, so all
10232                        // we need to do is clear this user's data and save that
10233                        // it is uninstalled.
10234                        if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
10235                        removeUser = user.getIdentifier();
10236                        appId = ps.appId;
10237                        mSettings.writePackageRestrictionsLPr(removeUser);
10238                    } else {
10239                        // We need to set it back to 'installed' so the uninstall
10240                        // broadcasts will be sent correctly.
10241                        if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
10242                        ps.setInstalled(true, user.getIdentifier());
10243                    }
10244                } else {
10245                    // This is a system app, so we assume that the
10246                    // other users still have this package installed, so all
10247                    // we need to do is clear this user's data and save that
10248                    // it is uninstalled.
10249                    if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
10250                    removeUser = user.getIdentifier();
10251                    appId = ps.appId;
10252                    mSettings.writePackageRestrictionsLPr(removeUser);
10253                }
10254            }
10255        }
10256
10257        if (removeUser >= 0) {
10258            // From above, we determined that we are deleting this only
10259            // for a single user.  Continue the work here.
10260            if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser);
10261            if (outInfo != null) {
10262                outInfo.removedPackage = packageName;
10263                outInfo.removedAppId = appId;
10264                outInfo.removedUsers = new int[] {removeUser};
10265            }
10266            mInstaller.clearUserData(packageName, removeUser);
10267            removeKeystoreDataIfNeeded(removeUser, appId);
10268            schedulePackageCleaning(packageName, removeUser, false);
10269            return true;
10270        }
10271
10272        if (dataOnly) {
10273            // Delete application data first
10274            if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only");
10275            removePackageDataLI(ps, null, null, outInfo, flags, writeSettings);
10276            return true;
10277        }
10278
10279        boolean ret = false;
10280        mSettings.mKeySetManager.removeAppKeySetData(packageName);
10281        if (isSystemApp(ps)) {
10282            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package:" + ps.name);
10283            // When an updated system application is deleted we delete the existing resources as well and
10284            // fall back to existing code in system partition
10285            ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled,
10286                    flags, outInfo, writeSettings);
10287        } else {
10288            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package:" + ps.name);
10289            // Kill application pre-emptively especially for apps on sd.
10290            killApplication(packageName, ps.appId, "uninstall pkg");
10291            ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags,
10292                    allUserHandles, perUserInstalled,
10293                    outInfo, writeSettings);
10294        }
10295
10296        return ret;
10297    }
10298
10299    private final class ClearStorageConnection implements ServiceConnection {
10300        IMediaContainerService mContainerService;
10301
10302        @Override
10303        public void onServiceConnected(ComponentName name, IBinder service) {
10304            synchronized (this) {
10305                mContainerService = IMediaContainerService.Stub.asInterface(service);
10306                notifyAll();
10307            }
10308        }
10309
10310        @Override
10311        public void onServiceDisconnected(ComponentName name) {
10312        }
10313    }
10314
10315    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
10316        final boolean mounted;
10317        if (Environment.isExternalStorageEmulated()) {
10318            mounted = true;
10319        } else {
10320            final String status = Environment.getExternalStorageState();
10321
10322            mounted = status.equals(Environment.MEDIA_MOUNTED)
10323                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
10324        }
10325
10326        if (!mounted) {
10327            return;
10328        }
10329
10330        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
10331        int[] users;
10332        if (userId == UserHandle.USER_ALL) {
10333            users = sUserManager.getUserIds();
10334        } else {
10335            users = new int[] { userId };
10336        }
10337        final ClearStorageConnection conn = new ClearStorageConnection();
10338        if (mContext.bindServiceAsUser(
10339                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
10340            try {
10341                for (int curUser : users) {
10342                    long timeout = SystemClock.uptimeMillis() + 5000;
10343                    synchronized (conn) {
10344                        long now = SystemClock.uptimeMillis();
10345                        while (conn.mContainerService == null && now < timeout) {
10346                            try {
10347                                conn.wait(timeout - now);
10348                            } catch (InterruptedException e) {
10349                            }
10350                        }
10351                    }
10352                    if (conn.mContainerService == null) {
10353                        return;
10354                    }
10355
10356                    final UserEnvironment userEnv = new UserEnvironment(curUser);
10357                    clearDirectory(conn.mContainerService,
10358                            userEnv.buildExternalStorageAppCacheDirs(packageName));
10359                    if (allData) {
10360                        clearDirectory(conn.mContainerService,
10361                                userEnv.buildExternalStorageAppDataDirs(packageName));
10362                        clearDirectory(conn.mContainerService,
10363                                userEnv.buildExternalStorageAppMediaDirs(packageName));
10364                    }
10365                }
10366            } finally {
10367                mContext.unbindService(conn);
10368            }
10369        }
10370    }
10371
10372    @Override
10373    public void clearApplicationUserData(final String packageName,
10374            final IPackageDataObserver observer, final int userId) {
10375        mContext.enforceCallingOrSelfPermission(
10376                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
10377        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "clear application data");
10378        // Queue up an async operation since the package deletion may take a little while.
10379        mHandler.post(new Runnable() {
10380            public void run() {
10381                mHandler.removeCallbacks(this);
10382                final boolean succeeded;
10383                synchronized (mInstallLock) {
10384                    succeeded = clearApplicationUserDataLI(packageName, userId);
10385                }
10386                clearExternalStorageDataSync(packageName, userId, true);
10387                if (succeeded) {
10388                    // invoke DeviceStorageMonitor's update method to clear any notifications
10389                    DeviceStorageMonitorInternal
10390                            dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
10391                    if (dsm != null) {
10392                        dsm.checkMemory();
10393                    }
10394                }
10395                if(observer != null) {
10396                    try {
10397                        observer.onRemoveCompleted(packageName, succeeded);
10398                    } catch (RemoteException e) {
10399                        Log.i(TAG, "Observer no longer exists.");
10400                    }
10401                } //end if observer
10402            } //end run
10403        });
10404    }
10405
10406    private boolean clearApplicationUserDataLI(String packageName, int userId) {
10407        if (packageName == null) {
10408            Slog.w(TAG, "Attempt to delete null packageName.");
10409            return false;
10410        }
10411        PackageParser.Package p;
10412        boolean dataOnly = false;
10413        final int appId;
10414        synchronized (mPackages) {
10415            p = mPackages.get(packageName);
10416            if (p == null) {
10417                dataOnly = true;
10418                PackageSetting ps = mSettings.mPackages.get(packageName);
10419                if ((ps == null) || (ps.pkg == null)) {
10420                    Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
10421                    return false;
10422                }
10423                p = ps.pkg;
10424            }
10425            if (!dataOnly) {
10426                // need to check this only for fully installed applications
10427                if (p == null) {
10428                    Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
10429                    return false;
10430                }
10431                final ApplicationInfo applicationInfo = p.applicationInfo;
10432                if (applicationInfo == null) {
10433                    Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
10434                    return false;
10435                }
10436            }
10437            if (p != null && p.applicationInfo != null) {
10438                appId = p.applicationInfo.uid;
10439            } else {
10440                appId = -1;
10441            }
10442        }
10443        int retCode = mInstaller.clearUserData(packageName, userId);
10444        if (retCode < 0) {
10445            Slog.w(TAG, "Couldn't remove cache files for package: "
10446                    + packageName);
10447            return false;
10448        }
10449        removeKeystoreDataIfNeeded(userId, appId);
10450        return true;
10451    }
10452
10453    /**
10454     * Remove entries from the keystore daemon. Will only remove it if the
10455     * {@code appId} is valid.
10456     */
10457    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
10458        if (appId < 0) {
10459            return;
10460        }
10461
10462        final KeyStore keyStore = KeyStore.getInstance();
10463        if (keyStore != null) {
10464            if (userId == UserHandle.USER_ALL) {
10465                for (final int individual : sUserManager.getUserIds()) {
10466                    keyStore.clearUid(UserHandle.getUid(individual, appId));
10467                }
10468            } else {
10469                keyStore.clearUid(UserHandle.getUid(userId, appId));
10470            }
10471        } else {
10472            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
10473        }
10474    }
10475
10476    public void deleteApplicationCacheFiles(final String packageName,
10477            final IPackageDataObserver observer) {
10478        mContext.enforceCallingOrSelfPermission(
10479                android.Manifest.permission.DELETE_CACHE_FILES, null);
10480        // Queue up an async operation since the package deletion may take a little while.
10481        final int userId = UserHandle.getCallingUserId();
10482        mHandler.post(new Runnable() {
10483            public void run() {
10484                mHandler.removeCallbacks(this);
10485                final boolean succeded;
10486                synchronized (mInstallLock) {
10487                    succeded = deleteApplicationCacheFilesLI(packageName, userId);
10488                }
10489                clearExternalStorageDataSync(packageName, userId, false);
10490                if(observer != null) {
10491                    try {
10492                        observer.onRemoveCompleted(packageName, succeded);
10493                    } catch (RemoteException e) {
10494                        Log.i(TAG, "Observer no longer exists.");
10495                    }
10496                } //end if observer
10497            } //end run
10498        });
10499    }
10500
10501    private boolean deleteApplicationCacheFilesLI(String packageName, int userId) {
10502        if (packageName == null) {
10503            Slog.w(TAG, "Attempt to delete null packageName.");
10504            return false;
10505        }
10506        PackageParser.Package p;
10507        synchronized (mPackages) {
10508            p = mPackages.get(packageName);
10509        }
10510        if (p == null) {
10511            Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
10512            return false;
10513        }
10514        final ApplicationInfo applicationInfo = p.applicationInfo;
10515        if (applicationInfo == null) {
10516            Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
10517            return false;
10518        }
10519        int retCode = mInstaller.deleteCacheFiles(packageName, userId);
10520        if (retCode < 0) {
10521            Slog.w(TAG, "Couldn't remove cache files for package: "
10522                       + packageName + " u" + userId);
10523            return false;
10524        }
10525        return true;
10526    }
10527
10528    public void getPackageSizeInfo(final String packageName, int userHandle,
10529            final IPackageStatsObserver observer) {
10530        mContext.enforceCallingOrSelfPermission(
10531                android.Manifest.permission.GET_PACKAGE_SIZE, null);
10532        if (packageName == null) {
10533            throw new IllegalArgumentException("Attempt to get size of null packageName");
10534        }
10535
10536        PackageStats stats = new PackageStats(packageName, userHandle);
10537
10538        /*
10539         * Queue up an async operation since the package measurement may take a
10540         * little while.
10541         */
10542        Message msg = mHandler.obtainMessage(INIT_COPY);
10543        msg.obj = new MeasureParams(stats, observer);
10544        mHandler.sendMessage(msg);
10545    }
10546
10547    private boolean getPackageSizeInfoLI(String packageName, int userHandle,
10548            PackageStats pStats) {
10549        if (packageName == null) {
10550            Slog.w(TAG, "Attempt to get size of null packageName.");
10551            return false;
10552        }
10553        PackageParser.Package p;
10554        boolean dataOnly = false;
10555        String libDirPath = null;
10556        String asecPath = null;
10557        synchronized (mPackages) {
10558            p = mPackages.get(packageName);
10559            PackageSetting ps = mSettings.mPackages.get(packageName);
10560            if(p == null) {
10561                dataOnly = true;
10562                if((ps == null) || (ps.pkg == null)) {
10563                    Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
10564                    return false;
10565                }
10566                p = ps.pkg;
10567            }
10568            if (ps != null) {
10569                libDirPath = ps.nativeLibraryPathString;
10570            }
10571            if (p != null && (isExternal(p) || isForwardLocked(p))) {
10572                String secureContainerId = cidFromCodePath(p.applicationInfo.sourceDir);
10573                if (secureContainerId != null) {
10574                    asecPath = PackageHelper.getSdFilesystem(secureContainerId);
10575                }
10576            }
10577        }
10578        String publicSrcDir = null;
10579        if(!dataOnly) {
10580            final ApplicationInfo applicationInfo = p.applicationInfo;
10581            if (applicationInfo == null) {
10582                Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
10583                return false;
10584            }
10585            if (isForwardLocked(p)) {
10586                publicSrcDir = applicationInfo.publicSourceDir;
10587            }
10588        }
10589        int res = mInstaller.getSizeInfo(packageName, userHandle, p.mPath, libDirPath,
10590                publicSrcDir, asecPath, pStats);
10591        if (res < 0) {
10592            return false;
10593        }
10594
10595        // Fix-up for forward-locked applications in ASEC containers.
10596        if (!isExternal(p)) {
10597            pStats.codeSize += pStats.externalCodeSize;
10598            pStats.externalCodeSize = 0L;
10599        }
10600
10601        return true;
10602    }
10603
10604
10605    public void addPackageToPreferred(String packageName) {
10606        Slog.w(TAG, "addPackageToPreferred: this is now a no-op");
10607    }
10608
10609    public void removePackageFromPreferred(String packageName) {
10610        Slog.w(TAG, "removePackageFromPreferred: this is now a no-op");
10611    }
10612
10613    public List<PackageInfo> getPreferredPackages(int flags) {
10614        return new ArrayList<PackageInfo>();
10615    }
10616
10617    private int getUidTargetSdkVersionLockedLPr(int uid) {
10618        Object obj = mSettings.getUserIdLPr(uid);
10619        if (obj instanceof SharedUserSetting) {
10620            final SharedUserSetting sus = (SharedUserSetting) obj;
10621            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
10622            final Iterator<PackageSetting> it = sus.packages.iterator();
10623            while (it.hasNext()) {
10624                final PackageSetting ps = it.next();
10625                if (ps.pkg != null) {
10626                    int v = ps.pkg.applicationInfo.targetSdkVersion;
10627                    if (v < vers) vers = v;
10628                }
10629            }
10630            return vers;
10631        } else if (obj instanceof PackageSetting) {
10632            final PackageSetting ps = (PackageSetting) obj;
10633            if (ps.pkg != null) {
10634                return ps.pkg.applicationInfo.targetSdkVersion;
10635            }
10636        }
10637        return Build.VERSION_CODES.CUR_DEVELOPMENT;
10638    }
10639
10640    public void addPreferredActivity(IntentFilter filter, int match,
10641            ComponentName[] set, ComponentName activity, int userId) {
10642        addPreferredActivityInternal(filter, match, set, activity, true, userId);
10643    }
10644
10645    private void addPreferredActivityInternal(IntentFilter filter, int match,
10646            ComponentName[] set, ComponentName activity, boolean always, int userId) {
10647        // writer
10648        int callingUid = Binder.getCallingUid();
10649        enforceCrossUserPermission(callingUid, userId, true, "add preferred activity");
10650        if (filter.countActions() == 0) {
10651            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
10652            return;
10653        }
10654        synchronized (mPackages) {
10655            if (mContext.checkCallingOrSelfPermission(
10656                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
10657                    != PackageManager.PERMISSION_GRANTED) {
10658                if (getUidTargetSdkVersionLockedLPr(callingUid)
10659                        < Build.VERSION_CODES.FROYO) {
10660                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
10661                            + callingUid);
10662                    return;
10663                }
10664                mContext.enforceCallingOrSelfPermission(
10665                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
10666            }
10667
10668            Slog.i(TAG, "Adding preferred activity " + activity + " for user " + userId + " :");
10669            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
10670            mSettings.editPreferredActivitiesLPw(userId).addFilter(
10671                    new PreferredActivity(filter, match, set, activity, always));
10672            mSettings.writePackageRestrictionsLPr(userId);
10673        }
10674    }
10675
10676    public void replacePreferredActivity(IntentFilter filter, int match,
10677            ComponentName[] set, ComponentName activity) {
10678        if (filter.countActions() != 1) {
10679            throw new IllegalArgumentException(
10680                    "replacePreferredActivity expects filter to have only 1 action.");
10681        }
10682        if (filter.countDataAuthorities() != 0
10683                || filter.countDataPaths() != 0
10684                || filter.countDataSchemes() > 1
10685                || filter.countDataTypes() != 0) {
10686            throw new IllegalArgumentException(
10687                    "replacePreferredActivity expects filter to have no data authorities, " +
10688                    "paths, or types; and at most one scheme.");
10689        }
10690        synchronized (mPackages) {
10691            if (mContext.checkCallingOrSelfPermission(
10692                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
10693                    != PackageManager.PERMISSION_GRANTED) {
10694                if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
10695                        < Build.VERSION_CODES.FROYO) {
10696                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
10697                            + Binder.getCallingUid());
10698                    return;
10699                }
10700                mContext.enforceCallingOrSelfPermission(
10701                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
10702            }
10703
10704            final int callingUserId = UserHandle.getCallingUserId();
10705            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(callingUserId);
10706            if (pir != null) {
10707                Intent intent = new Intent(filter.getAction(0)).addCategory(filter.getCategory(0));
10708                if (filter.countDataSchemes() == 1) {
10709                    Uri.Builder builder = new Uri.Builder();
10710                    builder.scheme(filter.getDataScheme(0));
10711                    intent.setData(builder.build());
10712                }
10713                List<PreferredActivity> matches = pir.queryIntent(
10714                        intent, null, true, callingUserId);
10715                if (DEBUG_PREFERRED) {
10716                    Slog.i(TAG, matches.size() + " preferred matches for " + intent);
10717                }
10718                for (int i = 0; i < matches.size(); i++) {
10719                    PreferredActivity pa = matches.get(i);
10720                    if (DEBUG_PREFERRED) {
10721                        Slog.i(TAG, "Removing preferred activity "
10722                                + pa.mPref.mComponent + ":");
10723                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
10724                    }
10725                    pir.removeFilter(pa);
10726                }
10727            }
10728            addPreferredActivityInternal(filter, match, set, activity, true, callingUserId);
10729        }
10730    }
10731
10732    public void clearPackagePreferredActivities(String packageName) {
10733        final int uid = Binder.getCallingUid();
10734        // writer
10735        synchronized (mPackages) {
10736            PackageParser.Package pkg = mPackages.get(packageName);
10737            if (pkg == null || pkg.applicationInfo.uid != uid) {
10738                if (mContext.checkCallingOrSelfPermission(
10739                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
10740                        != PackageManager.PERMISSION_GRANTED) {
10741                    if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
10742                            < Build.VERSION_CODES.FROYO) {
10743                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
10744                                + Binder.getCallingUid());
10745                        return;
10746                    }
10747                    mContext.enforceCallingOrSelfPermission(
10748                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
10749                }
10750            }
10751
10752            int user = UserHandle.getCallingUserId();
10753            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
10754                mSettings.writePackageRestrictionsLPr(user);
10755                scheduleWriteSettingsLocked();
10756            }
10757        }
10758    }
10759
10760    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
10761    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
10762        ArrayList<PreferredActivity> removed = null;
10763        boolean changed = false;
10764        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
10765            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
10766            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
10767            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
10768                continue;
10769            }
10770            Iterator<PreferredActivity> it = pir.filterIterator();
10771            while (it.hasNext()) {
10772                PreferredActivity pa = it.next();
10773                // Mark entry for removal only if it matches the package name
10774                // and the entry is of type "always".
10775                if (packageName == null ||
10776                        (pa.mPref.mComponent.getPackageName().equals(packageName)
10777                                && pa.mPref.mAlways)) {
10778                    if (removed == null) {
10779                        removed = new ArrayList<PreferredActivity>();
10780                    }
10781                    removed.add(pa);
10782                }
10783            }
10784            if (removed != null) {
10785                for (int j=0; j<removed.size(); j++) {
10786                    PreferredActivity pa = removed.get(j);
10787                    pir.removeFilter(pa);
10788                }
10789                changed = true;
10790            }
10791        }
10792        return changed;
10793    }
10794
10795    public void resetPreferredActivities(int userId) {
10796        mContext.enforceCallingOrSelfPermission(
10797                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
10798        // writer
10799        synchronized (mPackages) {
10800            int user = UserHandle.getCallingUserId();
10801            clearPackagePreferredActivitiesLPw(null, user);
10802            mSettings.readDefaultPreferredAppsLPw(this, user);
10803            mSettings.writePackageRestrictionsLPr(user);
10804            scheduleWriteSettingsLocked();
10805        }
10806    }
10807
10808    public int getPreferredActivities(List<IntentFilter> outFilters,
10809            List<ComponentName> outActivities, String packageName) {
10810
10811        int num = 0;
10812        final int userId = UserHandle.getCallingUserId();
10813        // reader
10814        synchronized (mPackages) {
10815            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
10816            if (pir != null) {
10817                final Iterator<PreferredActivity> it = pir.filterIterator();
10818                while (it.hasNext()) {
10819                    final PreferredActivity pa = it.next();
10820                    if (packageName == null
10821                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
10822                                    && pa.mPref.mAlways)) {
10823                        if (outFilters != null) {
10824                            outFilters.add(new IntentFilter(pa));
10825                        }
10826                        if (outActivities != null) {
10827                            outActivities.add(pa.mPref.mComponent);
10828                        }
10829                    }
10830                }
10831            }
10832        }
10833
10834        return num;
10835    }
10836
10837    @Override
10838    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
10839            int userId) {
10840        int callingUid = Binder.getCallingUid();
10841        if (callingUid != Process.SYSTEM_UID) {
10842            throw new SecurityException(
10843                    "addPersistentPreferredActivity can only be run by the system");
10844        }
10845        if (filter.countActions() == 0) {
10846            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
10847            return;
10848        }
10849        synchronized (mPackages) {
10850            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
10851                    " :");
10852            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
10853            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
10854                    new PersistentPreferredActivity(filter, activity));
10855            mSettings.writePackageRestrictionsLPr(userId);
10856        }
10857    }
10858
10859    @Override
10860    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
10861        int callingUid = Binder.getCallingUid();
10862        if (callingUid != Process.SYSTEM_UID) {
10863            throw new SecurityException(
10864                    "clearPackagePersistentPreferredActivities can only be run by the system");
10865        }
10866        ArrayList<PersistentPreferredActivity> removed = null;
10867        boolean changed = false;
10868        synchronized (mPackages) {
10869            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
10870                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
10871                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
10872                        .valueAt(i);
10873                if (userId != thisUserId) {
10874                    continue;
10875                }
10876                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
10877                while (it.hasNext()) {
10878                    PersistentPreferredActivity ppa = it.next();
10879                    // Mark entry for removal only if it matches the package name.
10880                    if (ppa.mComponent.getPackageName().equals(packageName)) {
10881                        if (removed == null) {
10882                            removed = new ArrayList<PersistentPreferredActivity>();
10883                        }
10884                        removed.add(ppa);
10885                    }
10886                }
10887                if (removed != null) {
10888                    for (int j=0; j<removed.size(); j++) {
10889                        PersistentPreferredActivity ppa = removed.get(j);
10890                        ppir.removeFilter(ppa);
10891                    }
10892                    changed = true;
10893                }
10894            }
10895
10896            if (changed) {
10897                mSettings.writePackageRestrictionsLPr(userId);
10898            }
10899        }
10900    }
10901
10902    /*
10903     * For filters that are added with this method:
10904     * if an intent for the user whose id is userIdOrig matches the filter, then this intent can
10905     * also be resolved in the user whose id is userIdDest.
10906     */
10907    @Override
10908    public void addForwardingIntentFilter(IntentFilter filter, int userIdOrig, int userIdDest) {
10909        int callingUid = Binder.getCallingUid();
10910        if (callingUid != Process.SYSTEM_UID) {
10911            throw new SecurityException(
10912                    "addForwardingIntentFilter can only be run by the system");
10913        }
10914        if (filter.countActions() == 0) {
10915            Slog.w(TAG, "Cannot set a forwarding intent filter with no filter actions");
10916            return;
10917        }
10918        synchronized (mPackages) {
10919            mSettings.editForwardingIntentResolverLPw(userIdOrig).addFilter(
10920                    new ForwardingIntentFilter(filter, userIdDest));
10921            mSettings.writePackageRestrictionsLPr(userIdOrig);
10922        }
10923    }
10924
10925    @Override
10926    public void clearForwardingIntentFilters(int userIdOrig) {
10927        int callingUid = Binder.getCallingUid();
10928        if (callingUid != Process.SYSTEM_UID) {
10929            throw new SecurityException(
10930                    "clearForwardingIntentFilter can only be run by the system");
10931        }
10932        synchronized (mPackages) {
10933            ForwardingIntentResolver fir = mSettings.editForwardingIntentResolverLPw(userIdOrig);
10934            HashSet<ForwardingIntentFilter> set =
10935                    new HashSet<ForwardingIntentFilter>(fir.filterSet());
10936            for (ForwardingIntentFilter fif : set) {
10937                fir.removeFilter(fif);
10938            }
10939            mSettings.writePackageRestrictionsLPr(userIdOrig);
10940        }
10941    }
10942
10943    @Override
10944    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
10945        Intent intent = new Intent(Intent.ACTION_MAIN);
10946        intent.addCategory(Intent.CATEGORY_HOME);
10947
10948        final int callingUserId = UserHandle.getCallingUserId();
10949        List<ResolveInfo> list = queryIntentActivities(intent, null,
10950                PackageManager.GET_META_DATA, callingUserId);
10951        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
10952                true, false, false, callingUserId);
10953
10954        allHomeCandidates.clear();
10955        if (list != null) {
10956            for (ResolveInfo ri : list) {
10957                allHomeCandidates.add(ri);
10958            }
10959        }
10960        return (preferred == null || preferred.activityInfo == null)
10961                ? null
10962                : new ComponentName(preferred.activityInfo.packageName,
10963                        preferred.activityInfo.name);
10964    }
10965
10966    @Override
10967    public void setApplicationEnabledSetting(String appPackageName,
10968            int newState, int flags, int userId, String callingPackage) {
10969        if (!sUserManager.exists(userId)) return;
10970        if (callingPackage == null) {
10971            callingPackage = Integer.toString(Binder.getCallingUid());
10972        }
10973        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
10974    }
10975
10976    @Override
10977    public void setComponentEnabledSetting(ComponentName componentName,
10978            int newState, int flags, int userId) {
10979        if (!sUserManager.exists(userId)) return;
10980        setEnabledSetting(componentName.getPackageName(),
10981                componentName.getClassName(), newState, flags, userId, null);
10982    }
10983
10984    private void setEnabledSetting(final String packageName, String className, int newState,
10985            final int flags, int userId, String callingPackage) {
10986        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
10987              || newState == COMPONENT_ENABLED_STATE_ENABLED
10988              || newState == COMPONENT_ENABLED_STATE_DISABLED
10989              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
10990              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
10991            throw new IllegalArgumentException("Invalid new component state: "
10992                    + newState);
10993        }
10994        PackageSetting pkgSetting;
10995        final int uid = Binder.getCallingUid();
10996        final int permission = mContext.checkCallingOrSelfPermission(
10997                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
10998        enforceCrossUserPermission(uid, userId, false, "set enabled");
10999        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
11000        boolean sendNow = false;
11001        boolean isApp = (className == null);
11002        String componentName = isApp ? packageName : className;
11003        int packageUid = -1;
11004        ArrayList<String> components;
11005
11006        // writer
11007        synchronized (mPackages) {
11008            pkgSetting = mSettings.mPackages.get(packageName);
11009            if (pkgSetting == null) {
11010                if (className == null) {
11011                    throw new IllegalArgumentException(
11012                            "Unknown package: " + packageName);
11013                }
11014                throw new IllegalArgumentException(
11015                        "Unknown component: " + packageName
11016                        + "/" + className);
11017            }
11018            // Allow root and verify that userId is not being specified by a different user
11019            if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) {
11020                throw new SecurityException(
11021                        "Permission Denial: attempt to change component state from pid="
11022                        + Binder.getCallingPid()
11023                        + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
11024            }
11025            if (className == null) {
11026                // We're dealing with an application/package level state change
11027                if (pkgSetting.getEnabled(userId) == newState) {
11028                    // Nothing to do
11029                    return;
11030                }
11031                if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
11032                    || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
11033                    // Don't care about who enables an app.
11034                    callingPackage = null;
11035                }
11036                pkgSetting.setEnabled(newState, userId, callingPackage);
11037                // pkgSetting.pkg.mSetEnabled = newState;
11038            } else {
11039                // We're dealing with a component level state change
11040                // First, verify that this is a valid class name.
11041                PackageParser.Package pkg = pkgSetting.pkg;
11042                if (pkg == null || !pkg.hasComponentClassName(className)) {
11043                    if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) {
11044                        throw new IllegalArgumentException("Component class " + className
11045                                + " does not exist in " + packageName);
11046                    } else {
11047                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
11048                                + className + " does not exist in " + packageName);
11049                    }
11050                }
11051                switch (newState) {
11052                case COMPONENT_ENABLED_STATE_ENABLED:
11053                    if (!pkgSetting.enableComponentLPw(className, userId)) {
11054                        return;
11055                    }
11056                    break;
11057                case COMPONENT_ENABLED_STATE_DISABLED:
11058                    if (!pkgSetting.disableComponentLPw(className, userId)) {
11059                        return;
11060                    }
11061                    break;
11062                case COMPONENT_ENABLED_STATE_DEFAULT:
11063                    if (!pkgSetting.restoreComponentLPw(className, userId)) {
11064                        return;
11065                    }
11066                    break;
11067                default:
11068                    Slog.e(TAG, "Invalid new component state: " + newState);
11069                    return;
11070                }
11071            }
11072            mSettings.writePackageRestrictionsLPr(userId);
11073            components = mPendingBroadcasts.get(userId, packageName);
11074            final boolean newPackage = components == null;
11075            if (newPackage) {
11076                components = new ArrayList<String>();
11077            }
11078            if (!components.contains(componentName)) {
11079                components.add(componentName);
11080            }
11081            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
11082                sendNow = true;
11083                // Purge entry from pending broadcast list if another one exists already
11084                // since we are sending one right away.
11085                mPendingBroadcasts.remove(userId, packageName);
11086            } else {
11087                if (newPackage) {
11088                    mPendingBroadcasts.put(userId, packageName, components);
11089                }
11090                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
11091                    // Schedule a message
11092                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
11093                }
11094            }
11095        }
11096
11097        long callingId = Binder.clearCallingIdentity();
11098        try {
11099            if (sendNow) {
11100                packageUid = UserHandle.getUid(userId, pkgSetting.appId);
11101                sendPackageChangedBroadcast(packageName,
11102                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
11103            }
11104        } finally {
11105            Binder.restoreCallingIdentity(callingId);
11106        }
11107    }
11108
11109    private void sendPackageChangedBroadcast(String packageName,
11110            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
11111        if (DEBUG_INSTALL)
11112            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
11113                    + componentNames);
11114        Bundle extras = new Bundle(4);
11115        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
11116        String nameList[] = new String[componentNames.size()];
11117        componentNames.toArray(nameList);
11118        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
11119        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
11120        extras.putInt(Intent.EXTRA_UID, packageUid);
11121        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, null, null,
11122                new int[] {UserHandle.getUserId(packageUid)});
11123    }
11124
11125    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
11126        if (!sUserManager.exists(userId)) return;
11127        final int uid = Binder.getCallingUid();
11128        final int permission = mContext.checkCallingOrSelfPermission(
11129                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
11130        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
11131        enforceCrossUserPermission(uid, userId, true, "stop package");
11132        // writer
11133        synchronized (mPackages) {
11134            if (mSettings.setPackageStoppedStateLPw(packageName, stopped, allowedByPermission,
11135                    uid, userId)) {
11136                scheduleWritePackageRestrictionsLocked(userId);
11137            }
11138        }
11139    }
11140
11141    public String getInstallerPackageName(String packageName) {
11142        // reader
11143        synchronized (mPackages) {
11144            return mSettings.getInstallerPackageNameLPr(packageName);
11145        }
11146    }
11147
11148    @Override
11149    public int getApplicationEnabledSetting(String packageName, int userId) {
11150        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
11151        int uid = Binder.getCallingUid();
11152        enforceCrossUserPermission(uid, userId, false, "get enabled");
11153        // reader
11154        synchronized (mPackages) {
11155            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
11156        }
11157    }
11158
11159    @Override
11160    public int getComponentEnabledSetting(ComponentName componentName, int userId) {
11161        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
11162        int uid = Binder.getCallingUid();
11163        enforceCrossUserPermission(uid, userId, false, "get component enabled");
11164        // reader
11165        synchronized (mPackages) {
11166            return mSettings.getComponentEnabledSettingLPr(componentName, userId);
11167        }
11168    }
11169
11170    public void enterSafeMode() {
11171        enforceSystemOrRoot("Only the system can request entering safe mode");
11172
11173        if (!mSystemReady) {
11174            mSafeMode = true;
11175        }
11176    }
11177
11178    public void systemReady() {
11179        mSystemReady = true;
11180
11181        // Read the compatibilty setting when the system is ready.
11182        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
11183                mContext.getContentResolver(),
11184                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
11185        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
11186        if (DEBUG_SETTINGS) {
11187            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
11188        }
11189
11190        synchronized (mPackages) {
11191            // Verify that all of the preferred activity components actually
11192            // exist.  It is possible for applications to be updated and at
11193            // that point remove a previously declared activity component that
11194            // had been set as a preferred activity.  We try to clean this up
11195            // the next time we encounter that preferred activity, but it is
11196            // possible for the user flow to never be able to return to that
11197            // situation so here we do a sanity check to make sure we haven't
11198            // left any junk around.
11199            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
11200            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
11201                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
11202                removed.clear();
11203                for (PreferredActivity pa : pir.filterSet()) {
11204                    if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
11205                        removed.add(pa);
11206                    }
11207                }
11208                if (removed.size() > 0) {
11209                    for (int j=0; j<removed.size(); j++) {
11210                        PreferredActivity pa = removed.get(i);
11211                        Slog.w(TAG, "Removing dangling preferred activity: "
11212                                + pa.mPref.mComponent);
11213                        pir.removeFilter(pa);
11214                    }
11215                    mSettings.writePackageRestrictionsLPr(
11216                            mSettings.mPreferredActivities.keyAt(i));
11217                }
11218            }
11219        }
11220        sUserManager.systemReady();
11221    }
11222
11223    public boolean isSafeMode() {
11224        return mSafeMode;
11225    }
11226
11227    public boolean hasSystemUidErrors() {
11228        return mHasSystemUidErrors;
11229    }
11230
11231    static String arrayToString(int[] array) {
11232        StringBuffer buf = new StringBuffer(128);
11233        buf.append('[');
11234        if (array != null) {
11235            for (int i=0; i<array.length; i++) {
11236                if (i > 0) buf.append(", ");
11237                buf.append(array[i]);
11238            }
11239        }
11240        buf.append(']');
11241        return buf.toString();
11242    }
11243
11244    static class DumpState {
11245        public static final int DUMP_LIBS = 1 << 0;
11246
11247        public static final int DUMP_FEATURES = 1 << 1;
11248
11249        public static final int DUMP_RESOLVERS = 1 << 2;
11250
11251        public static final int DUMP_PERMISSIONS = 1 << 3;
11252
11253        public static final int DUMP_PACKAGES = 1 << 4;
11254
11255        public static final int DUMP_SHARED_USERS = 1 << 5;
11256
11257        public static final int DUMP_MESSAGES = 1 << 6;
11258
11259        public static final int DUMP_PROVIDERS = 1 << 7;
11260
11261        public static final int DUMP_VERIFIERS = 1 << 8;
11262
11263        public static final int DUMP_PREFERRED = 1 << 9;
11264
11265        public static final int DUMP_PREFERRED_XML = 1 << 10;
11266
11267        public static final int DUMP_KEYSETS = 1 << 11;
11268
11269        public static final int DUMP_VERSION = 1 << 12;
11270
11271        public static final int OPTION_SHOW_FILTERS = 1 << 0;
11272
11273        private int mTypes;
11274
11275        private int mOptions;
11276
11277        private boolean mTitlePrinted;
11278
11279        private SharedUserSetting mSharedUser;
11280
11281        public boolean isDumping(int type) {
11282            if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
11283                return true;
11284            }
11285
11286            return (mTypes & type) != 0;
11287        }
11288
11289        public void setDump(int type) {
11290            mTypes |= type;
11291        }
11292
11293        public boolean isOptionEnabled(int option) {
11294            return (mOptions & option) != 0;
11295        }
11296
11297        public void setOptionEnabled(int option) {
11298            mOptions |= option;
11299        }
11300
11301        public boolean onTitlePrinted() {
11302            final boolean printed = mTitlePrinted;
11303            mTitlePrinted = true;
11304            return printed;
11305        }
11306
11307        public boolean getTitlePrinted() {
11308            return mTitlePrinted;
11309        }
11310
11311        public void setTitlePrinted(boolean enabled) {
11312            mTitlePrinted = enabled;
11313        }
11314
11315        public SharedUserSetting getSharedUser() {
11316            return mSharedUser;
11317        }
11318
11319        public void setSharedUser(SharedUserSetting user) {
11320            mSharedUser = user;
11321        }
11322    }
11323
11324    @Override
11325    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11326        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
11327                != PackageManager.PERMISSION_GRANTED) {
11328            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11329                    + Binder.getCallingPid()
11330                    + ", uid=" + Binder.getCallingUid()
11331                    + " without permission "
11332                    + android.Manifest.permission.DUMP);
11333            return;
11334        }
11335
11336        DumpState dumpState = new DumpState();
11337        boolean fullPreferred = false;
11338        boolean checkin = false;
11339
11340        String packageName = null;
11341
11342        int opti = 0;
11343        while (opti < args.length) {
11344            String opt = args[opti];
11345            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11346                break;
11347            }
11348            opti++;
11349            if ("-a".equals(opt)) {
11350                // Right now we only know how to print all.
11351            } else if ("-h".equals(opt)) {
11352                pw.println("Package manager dump options:");
11353                pw.println("  [-h] [-f] [--checkin] [cmd] ...");
11354                pw.println("    --checkin: dump for a checkin");
11355                pw.println("    -f: print details of intent filters");
11356                pw.println("    -h: print this help");
11357                pw.println("  cmd may be one of:");
11358                pw.println("    l[ibraries]: list known shared libraries");
11359                pw.println("    f[ibraries]: list device features");
11360                pw.println("    r[esolvers]: dump intent resolvers");
11361                pw.println("    perm[issions]: dump permissions");
11362                pw.println("    pref[erred]: print preferred package settings");
11363                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
11364                pw.println("    prov[iders]: dump content providers");
11365                pw.println("    p[ackages]: dump installed packages");
11366                pw.println("    s[hared-users]: dump shared user IDs");
11367                pw.println("    m[essages]: print collected runtime messages");
11368                pw.println("    v[erifiers]: print package verifier info");
11369                pw.println("    version: print database version info");
11370                pw.println("    <package.name>: info about given package");
11371                pw.println("    k[eysets]: print known keysets");
11372                return;
11373            } else if ("--checkin".equals(opt)) {
11374                checkin = true;
11375            } else if ("-f".equals(opt)) {
11376                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
11377            } else {
11378                pw.println("Unknown argument: " + opt + "; use -h for help");
11379            }
11380        }
11381
11382        // Is the caller requesting to dump a particular piece of data?
11383        if (opti < args.length) {
11384            String cmd = args[opti];
11385            opti++;
11386            // Is this a package name?
11387            if ("android".equals(cmd) || cmd.contains(".")) {
11388                packageName = cmd;
11389                // When dumping a single package, we always dump all of its
11390                // filter information since the amount of data will be reasonable.
11391                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
11392            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
11393                dumpState.setDump(DumpState.DUMP_LIBS);
11394            } else if ("f".equals(cmd) || "features".equals(cmd)) {
11395                dumpState.setDump(DumpState.DUMP_FEATURES);
11396            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
11397                dumpState.setDump(DumpState.DUMP_RESOLVERS);
11398            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
11399                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
11400            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
11401                dumpState.setDump(DumpState.DUMP_PREFERRED);
11402            } else if ("preferred-xml".equals(cmd)) {
11403                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
11404                if (opti < args.length && "--full".equals(args[opti])) {
11405                    fullPreferred = true;
11406                    opti++;
11407                }
11408            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
11409                dumpState.setDump(DumpState.DUMP_PACKAGES);
11410            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
11411                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
11412            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
11413                dumpState.setDump(DumpState.DUMP_PROVIDERS);
11414            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
11415                dumpState.setDump(DumpState.DUMP_MESSAGES);
11416            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
11417                dumpState.setDump(DumpState.DUMP_VERIFIERS);
11418            } else if ("version".equals(cmd)) {
11419                dumpState.setDump(DumpState.DUMP_VERSION);
11420            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
11421                dumpState.setDump(DumpState.DUMP_KEYSETS);
11422            }
11423        }
11424
11425        if (checkin) {
11426            pw.println("vers,1");
11427        }
11428
11429        // reader
11430        synchronized (mPackages) {
11431            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
11432                if (!checkin) {
11433                    if (dumpState.onTitlePrinted())
11434                        pw.println();
11435                    pw.println("Database versions:");
11436                    pw.print("  SDK Version:");
11437                    pw.print(" internal=");
11438                    pw.print(mSettings.mInternalSdkPlatform);
11439                    pw.print(" external=");
11440                    pw.println(mSettings.mExternalSdkPlatform);
11441                    pw.print("  DB Version:");
11442                    pw.print(" internal=");
11443                    pw.print(mSettings.mInternalDatabaseVersion);
11444                    pw.print(" external=");
11445                    pw.println(mSettings.mExternalDatabaseVersion);
11446                }
11447            }
11448
11449            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
11450                if (!checkin) {
11451                    if (dumpState.onTitlePrinted())
11452                        pw.println();
11453                    pw.println("Verifiers:");
11454                    pw.print("  Required: ");
11455                    pw.print(mRequiredVerifierPackage);
11456                    pw.print(" (uid=");
11457                    pw.print(getPackageUid(mRequiredVerifierPackage, 0));
11458                    pw.println(")");
11459                } else if (mRequiredVerifierPackage != null) {
11460                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
11461                    pw.print(","); pw.println(getPackageUid(mRequiredVerifierPackage, 0));
11462                }
11463            }
11464
11465            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
11466                boolean printedHeader = false;
11467                final Iterator<String> it = mSharedLibraries.keySet().iterator();
11468                while (it.hasNext()) {
11469                    String name = it.next();
11470                    SharedLibraryEntry ent = mSharedLibraries.get(name);
11471                    if (!checkin) {
11472                        if (!printedHeader) {
11473                            if (dumpState.onTitlePrinted())
11474                                pw.println();
11475                            pw.println("Libraries:");
11476                            printedHeader = true;
11477                        }
11478                        pw.print("  ");
11479                    } else {
11480                        pw.print("lib,");
11481                    }
11482                    pw.print(name);
11483                    if (!checkin) {
11484                        pw.print(" -> ");
11485                    }
11486                    if (ent.path != null) {
11487                        if (!checkin) {
11488                            pw.print("(jar) ");
11489                            pw.print(ent.path);
11490                        } else {
11491                            pw.print(",jar,");
11492                            pw.print(ent.path);
11493                        }
11494                    } else {
11495                        if (!checkin) {
11496                            pw.print("(apk) ");
11497                            pw.print(ent.apk);
11498                        } else {
11499                            pw.print(",apk,");
11500                            pw.print(ent.apk);
11501                        }
11502                    }
11503                    pw.println();
11504                }
11505            }
11506
11507            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
11508                if (dumpState.onTitlePrinted())
11509                    pw.println();
11510                if (!checkin) {
11511                    pw.println("Features:");
11512                }
11513                Iterator<String> it = mAvailableFeatures.keySet().iterator();
11514                while (it.hasNext()) {
11515                    String name = it.next();
11516                    if (!checkin) {
11517                        pw.print("  ");
11518                    } else {
11519                        pw.print("feat,");
11520                    }
11521                    pw.println(name);
11522                }
11523            }
11524
11525            if (!checkin && dumpState.isDumping(DumpState.DUMP_RESOLVERS)) {
11526                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
11527                        : "Activity Resolver Table:", "  ", packageName,
11528                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
11529                    dumpState.setTitlePrinted(true);
11530                }
11531                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
11532                        : "Receiver Resolver Table:", "  ", packageName,
11533                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
11534                    dumpState.setTitlePrinted(true);
11535                }
11536                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
11537                        : "Service Resolver Table:", "  ", packageName,
11538                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
11539                    dumpState.setTitlePrinted(true);
11540                }
11541                if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
11542                        : "Provider Resolver Table:", "  ", packageName,
11543                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
11544                    dumpState.setTitlePrinted(true);
11545                }
11546            }
11547
11548            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
11549                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
11550                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
11551                    int user = mSettings.mPreferredActivities.keyAt(i);
11552                    if (pir.dump(pw,
11553                            dumpState.getTitlePrinted()
11554                                ? "\nPreferred Activities User " + user + ":"
11555                                : "Preferred Activities User " + user + ":", "  ",
11556                            packageName, true)) {
11557                        dumpState.setTitlePrinted(true);
11558                    }
11559                }
11560            }
11561
11562            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
11563                pw.flush();
11564                FileOutputStream fout = new FileOutputStream(fd);
11565                BufferedOutputStream str = new BufferedOutputStream(fout);
11566                XmlSerializer serializer = new FastXmlSerializer();
11567                try {
11568                    serializer.setOutput(str, "utf-8");
11569                    serializer.startDocument(null, true);
11570                    serializer.setFeature(
11571                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
11572                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
11573                    serializer.endDocument();
11574                    serializer.flush();
11575                } catch (IllegalArgumentException e) {
11576                    pw.println("Failed writing: " + e);
11577                } catch (IllegalStateException e) {
11578                    pw.println("Failed writing: " + e);
11579                } catch (IOException e) {
11580                    pw.println("Failed writing: " + e);
11581                }
11582            }
11583
11584            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
11585                mSettings.dumpPermissionsLPr(pw, packageName, dumpState);
11586            }
11587
11588            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
11589                boolean printedSomething = false;
11590                for (PackageParser.Provider p : mProviders.mProviders.values()) {
11591                    if (packageName != null && !packageName.equals(p.info.packageName)) {
11592                        continue;
11593                    }
11594                    if (!printedSomething) {
11595                        if (dumpState.onTitlePrinted())
11596                            pw.println();
11597                        pw.println("Registered ContentProviders:");
11598                        printedSomething = true;
11599                    }
11600                    pw.print("  "); p.printComponentShortName(pw); pw.println(":");
11601                    pw.print("    "); pw.println(p.toString());
11602                }
11603                printedSomething = false;
11604                for (Map.Entry<String, PackageParser.Provider> entry :
11605                        mProvidersByAuthority.entrySet()) {
11606                    PackageParser.Provider p = entry.getValue();
11607                    if (packageName != null && !packageName.equals(p.info.packageName)) {
11608                        continue;
11609                    }
11610                    if (!printedSomething) {
11611                        if (dumpState.onTitlePrinted())
11612                            pw.println();
11613                        pw.println("ContentProvider Authorities:");
11614                        printedSomething = true;
11615                    }
11616                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
11617                    pw.print("    "); pw.println(p.toString());
11618                    if (p.info != null && p.info.applicationInfo != null) {
11619                        final String appInfo = p.info.applicationInfo.toString();
11620                        pw.print("      applicationInfo="); pw.println(appInfo);
11621                    }
11622                }
11623            }
11624
11625            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
11626                mSettings.mKeySetManager.dump(pw, packageName, dumpState);
11627            }
11628
11629            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
11630                mSettings.dumpPackagesLPr(pw, packageName, dumpState, checkin);
11631            }
11632
11633            if (!checkin && dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
11634                mSettings.dumpSharedUsersLPr(pw, packageName, dumpState);
11635            }
11636
11637            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
11638                if (dumpState.onTitlePrinted())
11639                    pw.println();
11640                mSettings.dumpReadMessagesLPr(pw, dumpState);
11641
11642                pw.println();
11643                pw.println("Package warning messages:");
11644                final File fname = getSettingsProblemFile();
11645                FileInputStream in = null;
11646                try {
11647                    in = new FileInputStream(fname);
11648                    final int avail = in.available();
11649                    final byte[] data = new byte[avail];
11650                    in.read(data);
11651                    pw.print(new String(data));
11652                } catch (FileNotFoundException e) {
11653                } catch (IOException e) {
11654                } finally {
11655                    if (in != null) {
11656                        try {
11657                            in.close();
11658                        } catch (IOException e) {
11659                        }
11660                    }
11661                }
11662            }
11663        }
11664    }
11665
11666    // ------- apps on sdcard specific code -------
11667    static final boolean DEBUG_SD_INSTALL = false;
11668
11669    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
11670
11671    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
11672
11673    private boolean mMediaMounted = false;
11674
11675    private String getEncryptKey() {
11676        try {
11677            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
11678                    SD_ENCRYPTION_KEYSTORE_NAME);
11679            if (sdEncKey == null) {
11680                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
11681                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
11682                if (sdEncKey == null) {
11683                    Slog.e(TAG, "Failed to create encryption keys");
11684                    return null;
11685                }
11686            }
11687            return sdEncKey;
11688        } catch (NoSuchAlgorithmException nsae) {
11689            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
11690            return null;
11691        } catch (IOException ioe) {
11692            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
11693            return null;
11694        }
11695
11696    }
11697
11698    /* package */static String getTempContainerId() {
11699        int tmpIdx = 1;
11700        String list[] = PackageHelper.getSecureContainerList();
11701        if (list != null) {
11702            for (final String name : list) {
11703                // Ignore null and non-temporary container entries
11704                if (name == null || !name.startsWith(mTempContainerPrefix)) {
11705                    continue;
11706                }
11707
11708                String subStr = name.substring(mTempContainerPrefix.length());
11709                try {
11710                    int cid = Integer.parseInt(subStr);
11711                    if (cid >= tmpIdx) {
11712                        tmpIdx = cid + 1;
11713                    }
11714                } catch (NumberFormatException e) {
11715                }
11716            }
11717        }
11718        return mTempContainerPrefix + tmpIdx;
11719    }
11720
11721    /*
11722     * Update media status on PackageManager.
11723     */
11724    public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
11725        int callingUid = Binder.getCallingUid();
11726        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
11727            throw new SecurityException("Media status can only be updated by the system");
11728        }
11729        // reader; this apparently protects mMediaMounted, but should probably
11730        // be a different lock in that case.
11731        synchronized (mPackages) {
11732            Log.i(TAG, "Updating external media status from "
11733                    + (mMediaMounted ? "mounted" : "unmounted") + " to "
11734                    + (mediaStatus ? "mounted" : "unmounted"));
11735            if (DEBUG_SD_INSTALL)
11736                Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
11737                        + ", mMediaMounted=" + mMediaMounted);
11738            if (mediaStatus == mMediaMounted) {
11739                final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
11740                        : 0, -1);
11741                mHandler.sendMessage(msg);
11742                return;
11743            }
11744            mMediaMounted = mediaStatus;
11745        }
11746        // Queue up an async operation since the package installation may take a
11747        // little while.
11748        mHandler.post(new Runnable() {
11749            public void run() {
11750                updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
11751            }
11752        });
11753    }
11754
11755    /**
11756     * Called by MountService when the initial ASECs to scan are available.
11757     * Should block until all the ASEC containers are finished being scanned.
11758     */
11759    public void scanAvailableAsecs() {
11760        updateExternalMediaStatusInner(true, false, false);
11761        if (mShouldRestoreconData) {
11762            SELinuxMMAC.setRestoreconDone();
11763            mShouldRestoreconData = false;
11764        }
11765    }
11766
11767    /*
11768     * Collect information of applications on external media, map them against
11769     * existing containers and update information based on current mount status.
11770     * Please note that we always have to report status if reportStatus has been
11771     * set to true especially when unloading packages.
11772     */
11773    private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
11774            boolean externalStorage) {
11775        // Collection of uids
11776        int uidArr[] = null;
11777        // Collection of stale containers
11778        HashSet<String> removeCids = new HashSet<String>();
11779        // Collection of packages on external media with valid containers.
11780        HashMap<AsecInstallArgs, String> processCids = new HashMap<AsecInstallArgs, String>();
11781        // Get list of secure containers.
11782        final String list[] = PackageHelper.getSecureContainerList();
11783        if (list == null || list.length == 0) {
11784            Log.i(TAG, "No secure containers on sdcard");
11785        } else {
11786            // Process list of secure containers and categorize them
11787            // as active or stale based on their package internal state.
11788            int uidList[] = new int[list.length];
11789            int num = 0;
11790            // reader
11791            synchronized (mPackages) {
11792                for (String cid : list) {
11793                    if (DEBUG_SD_INSTALL)
11794                        Log.i(TAG, "Processing container " + cid);
11795                    String pkgName = getAsecPackageName(cid);
11796                    if (pkgName == null) {
11797                        if (DEBUG_SD_INSTALL)
11798                            Log.i(TAG, "Container : " + cid + " stale");
11799                        removeCids.add(cid);
11800                        continue;
11801                    }
11802                    if (DEBUG_SD_INSTALL)
11803                        Log.i(TAG, "Looking for pkg : " + pkgName);
11804
11805                    final PackageSetting ps = mSettings.mPackages.get(pkgName);
11806                    if (ps == null) {
11807                        Log.i(TAG, "Deleting container with no matching settings " + cid);
11808                        removeCids.add(cid);
11809                        continue;
11810                    }
11811
11812                    /*
11813                     * Skip packages that are not external if we're unmounting
11814                     * external storage.
11815                     */
11816                    if (externalStorage && !isMounted && !isExternal(ps)) {
11817                        continue;
11818                    }
11819
11820                    final AsecInstallArgs args = new AsecInstallArgs(cid, isForwardLocked(ps));
11821                    // The package status is changed only if the code path
11822                    // matches between settings and the container id.
11823                    if (ps.codePathString != null && ps.codePathString.equals(args.getCodePath())) {
11824                        if (DEBUG_SD_INSTALL) {
11825                            Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
11826                                    + " at code path: " + ps.codePathString);
11827                        }
11828
11829                        // We do have a valid package installed on sdcard
11830                        processCids.put(args, ps.codePathString);
11831                        final int uid = ps.appId;
11832                        if (uid != -1) {
11833                            uidList[num++] = uid;
11834                        }
11835                    } else {
11836                        Log.i(TAG, "Deleting stale container for " + cid);
11837                        removeCids.add(cid);
11838                    }
11839                }
11840            }
11841
11842            if (num > 0) {
11843                // Sort uid list
11844                Arrays.sort(uidList, 0, num);
11845                // Throw away duplicates
11846                uidArr = new int[num];
11847                uidArr[0] = uidList[0];
11848                int di = 0;
11849                for (int i = 1; i < num; i++) {
11850                    if (uidList[i - 1] != uidList[i]) {
11851                        uidArr[di++] = uidList[i];
11852                    }
11853                }
11854            }
11855        }
11856        // Process packages with valid entries.
11857        if (isMounted) {
11858            if (DEBUG_SD_INSTALL)
11859                Log.i(TAG, "Loading packages");
11860            loadMediaPackages(processCids, uidArr, removeCids);
11861            startCleaningPackages();
11862        } else {
11863            if (DEBUG_SD_INSTALL)
11864                Log.i(TAG, "Unloading packages");
11865            unloadMediaPackages(processCids, uidArr, reportStatus);
11866        }
11867    }
11868
11869   private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
11870           ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
11871        int size = pkgList.size();
11872        if (size > 0) {
11873            // Send broadcasts here
11874            Bundle extras = new Bundle();
11875            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList
11876                    .toArray(new String[size]));
11877            if (uidArr != null) {
11878                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
11879            }
11880            if (replacing) {
11881                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
11882            }
11883            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
11884                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
11885            sendPackageBroadcast(action, null, extras, null, finishedReceiver, null);
11886        }
11887    }
11888
11889   /*
11890     * Look at potentially valid container ids from processCids If package
11891     * information doesn't match the one on record or package scanning fails,
11892     * the cid is added to list of removeCids. We currently don't delete stale
11893     * containers.
11894     */
11895   private void loadMediaPackages(HashMap<AsecInstallArgs, String> processCids, int uidArr[],
11896            HashSet<String> removeCids) {
11897        ArrayList<String> pkgList = new ArrayList<String>();
11898        Set<AsecInstallArgs> keys = processCids.keySet();
11899        boolean doGc = false;
11900        for (AsecInstallArgs args : keys) {
11901            String codePath = processCids.get(args);
11902            if (DEBUG_SD_INSTALL)
11903                Log.i(TAG, "Loading container : " + args.cid);
11904            int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
11905            try {
11906                // Make sure there are no container errors first.
11907                if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
11908                    Slog.e(TAG, "Failed to mount cid : " + args.cid
11909                            + " when installing from sdcard");
11910                    continue;
11911                }
11912                // Check code path here.
11913                if (codePath == null || !codePath.equals(args.getCodePath())) {
11914                    Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
11915                            + " does not match one in settings " + codePath);
11916                    continue;
11917                }
11918                // Parse package
11919                int parseFlags = mDefParseFlags;
11920                if (args.isExternal()) {
11921                    parseFlags |= PackageParser.PARSE_ON_SDCARD;
11922                }
11923                if (args.isFwdLocked()) {
11924                    parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
11925                }
11926
11927                doGc = true;
11928                synchronized (mInstallLock) {
11929                    final PackageParser.Package pkg = scanPackageLI(new File(codePath), parseFlags,
11930                            0, 0, null);
11931                    // Scan the package
11932                    if (pkg != null) {
11933                        /*
11934                         * TODO why is the lock being held? doPostInstall is
11935                         * called in other places without the lock. This needs
11936                         * to be straightened out.
11937                         */
11938                        // writer
11939                        synchronized (mPackages) {
11940                            retCode = PackageManager.INSTALL_SUCCEEDED;
11941                            pkgList.add(pkg.packageName);
11942                            // Post process args
11943                            args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
11944                                    pkg.applicationInfo.uid);
11945                        }
11946                    } else {
11947                        Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
11948                    }
11949                }
11950
11951            } finally {
11952                if (retCode != PackageManager.INSTALL_SUCCEEDED) {
11953                    // Don't destroy container here. Wait till gc clears things
11954                    // up.
11955                    removeCids.add(args.cid);
11956                }
11957            }
11958        }
11959        // writer
11960        synchronized (mPackages) {
11961            // If the platform SDK has changed since the last time we booted,
11962            // we need to re-grant app permission to catch any new ones that
11963            // appear. This is really a hack, and means that apps can in some
11964            // cases get permissions that the user didn't initially explicitly
11965            // allow... it would be nice to have some better way to handle
11966            // this situation.
11967            final boolean regrantPermissions = mSettings.mExternalSdkPlatform != mSdkVersion;
11968            if (regrantPermissions)
11969                Slog.i(TAG, "Platform changed from " + mSettings.mExternalSdkPlatform + " to "
11970                        + mSdkVersion + "; regranting permissions for external storage");
11971            mSettings.mExternalSdkPlatform = mSdkVersion;
11972
11973            // Make sure group IDs have been assigned, and any permission
11974            // changes in other apps are accounted for
11975            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
11976                    | (regrantPermissions
11977                            ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
11978                            : 0));
11979
11980            mSettings.updateExternalDatabaseVersion();
11981
11982            // can downgrade to reader
11983            // Persist settings
11984            mSettings.writeLPr();
11985        }
11986        // Send a broadcast to let everyone know we are done processing
11987        if (pkgList.size() > 0) {
11988            sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
11989        }
11990        // Force gc to avoid any stale parser references that we might have.
11991        if (doGc) {
11992            Runtime.getRuntime().gc();
11993        }
11994        // List stale containers and destroy stale temporary containers.
11995        if (removeCids != null) {
11996            for (String cid : removeCids) {
11997                if (cid.startsWith(mTempContainerPrefix)) {
11998                    Log.i(TAG, "Destroying stale temporary container " + cid);
11999                    PackageHelper.destroySdDir(cid);
12000                } else {
12001                    Log.w(TAG, "Container " + cid + " is stale");
12002               }
12003           }
12004        }
12005    }
12006
12007   /*
12008     * Utility method to unload a list of specified containers
12009     */
12010    private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
12011        // Just unmount all valid containers.
12012        for (AsecInstallArgs arg : cidArgs) {
12013            synchronized (mInstallLock) {
12014                arg.doPostDeleteLI(false);
12015           }
12016       }
12017   }
12018
12019    /*
12020     * Unload packages mounted on external media. This involves deleting package
12021     * data from internal structures, sending broadcasts about diabled packages,
12022     * gc'ing to free up references, unmounting all secure containers
12023     * corresponding to packages on external media, and posting a
12024     * UPDATED_MEDIA_STATUS message if status has been requested. Please note
12025     * that we always have to post this message if status has been requested no
12026     * matter what.
12027     */
12028    private void unloadMediaPackages(HashMap<AsecInstallArgs, String> processCids, int uidArr[],
12029            final boolean reportStatus) {
12030        if (DEBUG_SD_INSTALL)
12031            Log.i(TAG, "unloading media packages");
12032        ArrayList<String> pkgList = new ArrayList<String>();
12033        ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
12034        final Set<AsecInstallArgs> keys = processCids.keySet();
12035        for (AsecInstallArgs args : keys) {
12036            String pkgName = args.getPackageName();
12037            if (DEBUG_SD_INSTALL)
12038                Log.i(TAG, "Trying to unload pkg : " + pkgName);
12039            // Delete package internally
12040            PackageRemovedInfo outInfo = new PackageRemovedInfo();
12041            synchronized (mInstallLock) {
12042                boolean res = deletePackageLI(pkgName, null, false, null, null,
12043                        PackageManager.DELETE_KEEP_DATA, outInfo, false);
12044                if (res) {
12045                    pkgList.add(pkgName);
12046                } else {
12047                    Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
12048                    failedList.add(args);
12049                }
12050            }
12051        }
12052
12053        // reader
12054        synchronized (mPackages) {
12055            // We didn't update the settings after removing each package;
12056            // write them now for all packages.
12057            mSettings.writeLPr();
12058        }
12059
12060        // We have to absolutely send UPDATED_MEDIA_STATUS only
12061        // after confirming that all the receivers processed the ordered
12062        // broadcast when packages get disabled, force a gc to clean things up.
12063        // and unload all the containers.
12064        if (pkgList.size() > 0) {
12065            sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
12066                    new IIntentReceiver.Stub() {
12067                public void performReceive(Intent intent, int resultCode, String data,
12068                        Bundle extras, boolean ordered, boolean sticky,
12069                        int sendingUser) throws RemoteException {
12070                    Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
12071                            reportStatus ? 1 : 0, 1, keys);
12072                    mHandler.sendMessage(msg);
12073                }
12074            });
12075        } else {
12076            Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
12077                    keys);
12078            mHandler.sendMessage(msg);
12079        }
12080    }
12081
12082    /** Binder call */
12083    @Override
12084    public void movePackage(final String packageName, final IPackageMoveObserver observer,
12085            final int flags) {
12086        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
12087        UserHandle user = new UserHandle(UserHandle.getCallingUserId());
12088        int returnCode = PackageManager.MOVE_SUCCEEDED;
12089        int currFlags = 0;
12090        int newFlags = 0;
12091        // reader
12092        synchronized (mPackages) {
12093            PackageParser.Package pkg = mPackages.get(packageName);
12094            if (pkg == null) {
12095                returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
12096            } else {
12097                // Disable moving fwd locked apps and system packages
12098                if (pkg.applicationInfo != null && isSystemApp(pkg)) {
12099                    Slog.w(TAG, "Cannot move system application");
12100                    returnCode = PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
12101                } else if (pkg.mOperationPending) {
12102                    Slog.w(TAG, "Attempt to move package which has pending operations");
12103                    returnCode = PackageManager.MOVE_FAILED_OPERATION_PENDING;
12104                } else {
12105                    // Find install location first
12106                    if ((flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0
12107                            && (flags & PackageManager.MOVE_INTERNAL) != 0) {
12108                        Slog.w(TAG, "Ambigous flags specified for move location.");
12109                        returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
12110                    } else {
12111                        newFlags = (flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 ? PackageManager.INSTALL_EXTERNAL
12112                                : PackageManager.INSTALL_INTERNAL;
12113                        currFlags = isExternal(pkg) ? PackageManager.INSTALL_EXTERNAL
12114                                : PackageManager.INSTALL_INTERNAL;
12115
12116                        if (newFlags == currFlags) {
12117                            Slog.w(TAG, "No move required. Trying to move to same location");
12118                            returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
12119                        } else {
12120                            if (isForwardLocked(pkg)) {
12121                                currFlags |= PackageManager.INSTALL_FORWARD_LOCK;
12122                                newFlags |= PackageManager.INSTALL_FORWARD_LOCK;
12123                            }
12124                        }
12125                    }
12126                    if (returnCode == PackageManager.MOVE_SUCCEEDED) {
12127                        pkg.mOperationPending = true;
12128                    }
12129                }
12130            }
12131
12132            /*
12133             * TODO this next block probably shouldn't be inside the lock. We
12134             * can't guarantee these won't change after this is fired off
12135             * anyway.
12136             */
12137            if (returnCode != PackageManager.MOVE_SUCCEEDED) {
12138                processPendingMove(new MoveParams(null, observer, 0, packageName,
12139                        null, -1, user),
12140                        returnCode);
12141            } else {
12142                Message msg = mHandler.obtainMessage(INIT_COPY);
12143                InstallArgs srcArgs = createInstallArgs(currFlags, pkg.applicationInfo.sourceDir,
12144                        pkg.applicationInfo.publicSourceDir, pkg.applicationInfo.nativeLibraryDir);
12145                MoveParams mp = new MoveParams(srcArgs, observer, newFlags, packageName,
12146                        pkg.applicationInfo.dataDir, pkg.applicationInfo.uid, user);
12147                msg.obj = mp;
12148                mHandler.sendMessage(msg);
12149            }
12150        }
12151    }
12152
12153    private void processPendingMove(final MoveParams mp, final int currentStatus) {
12154        // Queue up an async operation since the package deletion may take a
12155        // little while.
12156        mHandler.post(new Runnable() {
12157            public void run() {
12158                // TODO fix this; this does nothing.
12159                mHandler.removeCallbacks(this);
12160                int returnCode = currentStatus;
12161                if (currentStatus == PackageManager.MOVE_SUCCEEDED) {
12162                    int uidArr[] = null;
12163                    ArrayList<String> pkgList = null;
12164                    synchronized (mPackages) {
12165                        PackageParser.Package pkg = mPackages.get(mp.packageName);
12166                        if (pkg == null) {
12167                            Slog.w(TAG, " Package " + mp.packageName
12168                                    + " doesn't exist. Aborting move");
12169                            returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
12170                        } else if (!mp.srcArgs.getCodePath().equals(pkg.applicationInfo.sourceDir)) {
12171                            Slog.w(TAG, "Package " + mp.packageName + " code path changed from "
12172                                    + mp.srcArgs.getCodePath() + " to "
12173                                    + pkg.applicationInfo.sourceDir
12174                                    + " Aborting move and returning error");
12175                            returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
12176                        } else {
12177                            uidArr = new int[] {
12178                                pkg.applicationInfo.uid
12179                            };
12180                            pkgList = new ArrayList<String>();
12181                            pkgList.add(mp.packageName);
12182                        }
12183                    }
12184                    if (returnCode == PackageManager.MOVE_SUCCEEDED) {
12185                        // Send resources unavailable broadcast
12186                        sendResourcesChangedBroadcast(false, true, pkgList, uidArr, null);
12187                        // Update package code and resource paths
12188                        synchronized (mInstallLock) {
12189                            synchronized (mPackages) {
12190                                PackageParser.Package pkg = mPackages.get(mp.packageName);
12191                                // Recheck for package again.
12192                                if (pkg == null) {
12193                                    Slog.w(TAG, " Package " + mp.packageName
12194                                            + " doesn't exist. Aborting move");
12195                                    returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
12196                                } else if (!mp.srcArgs.getCodePath().equals(
12197                                        pkg.applicationInfo.sourceDir)) {
12198                                    Slog.w(TAG, "Package " + mp.packageName
12199                                            + " code path changed from " + mp.srcArgs.getCodePath()
12200                                            + " to " + pkg.applicationInfo.sourceDir
12201                                            + " Aborting move and returning error");
12202                                    returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
12203                                } else {
12204                                    final String oldCodePath = pkg.mPath;
12205                                    final String newCodePath = mp.targetArgs.getCodePath();
12206                                    final String newResPath = mp.targetArgs.getResourcePath();
12207                                    final String newNativePath = mp.targetArgs
12208                                            .getNativeLibraryPath();
12209
12210                                    final File newNativeDir = new File(newNativePath);
12211
12212                                    if (!isForwardLocked(pkg) && !isExternal(pkg)) {
12213                                        // NOTE: We do not report any errors from the APK scan and library
12214                                        // copy at this point.
12215                                        NativeLibraryHelper.ApkHandle handle =
12216                                                new NativeLibraryHelper.ApkHandle(newCodePath);
12217                                        final int abi = NativeLibraryHelper.findSupportedAbi(
12218                                                handle, Build.SUPPORTED_ABIS);
12219                                        if (abi >= 0) {
12220                                            NativeLibraryHelper.copyNativeBinariesIfNeededLI(
12221                                                    handle, newNativeDir, Build.SUPPORTED_ABIS[abi]);
12222                                        }
12223                                        handle.close();
12224                                    }
12225                                    final int[] users = sUserManager.getUserIds();
12226                                    for (int user : users) {
12227                                        if (mInstaller.linkNativeLibraryDirectory(pkg.packageName,
12228                                                newNativePath, user) < 0) {
12229                                            returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
12230                                        }
12231                                    }
12232
12233                                    if (returnCode == PackageManager.MOVE_SUCCEEDED) {
12234                                        pkg.mPath = newCodePath;
12235                                        // Move dex files around
12236                                        if (moveDexFilesLI(pkg) != PackageManager.INSTALL_SUCCEEDED) {
12237                                            // Moving of dex files failed. Set
12238                                            // error code and abort move.
12239                                            pkg.mPath = pkg.mScanPath;
12240                                            returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
12241                                        }
12242                                    }
12243
12244                                    if (returnCode == PackageManager.MOVE_SUCCEEDED) {
12245                                        pkg.mScanPath = newCodePath;
12246                                        pkg.applicationInfo.sourceDir = newCodePath;
12247                                        pkg.applicationInfo.publicSourceDir = newResPath;
12248                                        pkg.applicationInfo.nativeLibraryDir = newNativePath;
12249                                        PackageSetting ps = (PackageSetting) pkg.mExtras;
12250                                        ps.codePath = new File(pkg.applicationInfo.sourceDir);
12251                                        ps.codePathString = ps.codePath.getPath();
12252                                        ps.resourcePath = new File(
12253                                                pkg.applicationInfo.publicSourceDir);
12254                                        ps.resourcePathString = ps.resourcePath.getPath();
12255                                        ps.nativeLibraryPathString = newNativePath;
12256                                        // Set the application info flag
12257                                        // correctly.
12258                                        if ((mp.flags & PackageManager.INSTALL_EXTERNAL) != 0) {
12259                                            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE;
12260                                        } else {
12261                                            pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_EXTERNAL_STORAGE;
12262                                        }
12263                                        ps.setFlags(pkg.applicationInfo.flags);
12264                                        mAppDirs.remove(oldCodePath);
12265                                        mAppDirs.put(newCodePath, pkg);
12266                                        // Persist settings
12267                                        mSettings.writeLPr();
12268                                    }
12269                                }
12270                            }
12271                        }
12272                        // Send resources available broadcast
12273                        sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
12274                    }
12275                }
12276                if (returnCode != PackageManager.MOVE_SUCCEEDED) {
12277                    // Clean up failed installation
12278                    if (mp.targetArgs != null) {
12279                        mp.targetArgs.doPostInstall(PackageManager.INSTALL_FAILED_INTERNAL_ERROR,
12280                                -1);
12281                    }
12282                } else {
12283                    // Force a gc to clear things up.
12284                    Runtime.getRuntime().gc();
12285                    // Delete older code
12286                    synchronized (mInstallLock) {
12287                        mp.srcArgs.doPostDeleteLI(true);
12288                    }
12289                }
12290
12291                // Allow more operations on this file if we didn't fail because
12292                // an operation was already pending for this package.
12293                if (returnCode != PackageManager.MOVE_FAILED_OPERATION_PENDING) {
12294                    synchronized (mPackages) {
12295                        PackageParser.Package pkg = mPackages.get(mp.packageName);
12296                        if (pkg != null) {
12297                            pkg.mOperationPending = false;
12298                       }
12299                   }
12300                }
12301
12302                IPackageMoveObserver observer = mp.observer;
12303                if (observer != null) {
12304                    try {
12305                        observer.packageMoved(mp.packageName, returnCode);
12306                    } catch (RemoteException e) {
12307                        Log.i(TAG, "Observer no longer exists.");
12308                    }
12309                }
12310            }
12311        });
12312    }
12313
12314    public boolean setInstallLocation(int loc) {
12315        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
12316                null);
12317        if (getInstallLocation() == loc) {
12318            return true;
12319        }
12320        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
12321                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
12322            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
12323                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
12324            return true;
12325        }
12326        return false;
12327   }
12328
12329    public int getInstallLocation() {
12330        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
12331                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
12332                PackageHelper.APP_INSTALL_AUTO);
12333    }
12334
12335    /** Called by UserManagerService */
12336    void cleanUpUserLILPw(int userHandle) {
12337        mDirtyUsers.remove(userHandle);
12338        mSettings.removeUserLPr(userHandle);
12339        mPendingBroadcasts.remove(userHandle);
12340        if (mInstaller != null) {
12341            // Technically, we shouldn't be doing this with the package lock
12342            // held.  However, this is very rare, and there is already so much
12343            // other disk I/O going on, that we'll let it slide for now.
12344            mInstaller.removeUserDataDirs(userHandle);
12345        }
12346    }
12347
12348    /** Called by UserManagerService */
12349    void createNewUserLILPw(int userHandle, File path) {
12350        if (mInstaller != null) {
12351            mSettings.createNewUserLILPw(this, mInstaller, userHandle, path);
12352        }
12353    }
12354
12355    @Override
12356    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
12357        mContext.enforceCallingOrSelfPermission(
12358                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
12359                "Only package verification agents can read the verifier device identity");
12360
12361        synchronized (mPackages) {
12362            return mSettings.getVerifierDeviceIdentityLPw();
12363        }
12364    }
12365
12366    @Override
12367    public void setPermissionEnforced(String permission, boolean enforced) {
12368        mContext.enforceCallingOrSelfPermission(GRANT_REVOKE_PERMISSIONS, null);
12369        if (READ_EXTERNAL_STORAGE.equals(permission)) {
12370            synchronized (mPackages) {
12371                if (mSettings.mReadExternalStorageEnforced == null
12372                        || mSettings.mReadExternalStorageEnforced != enforced) {
12373                    mSettings.mReadExternalStorageEnforced = enforced;
12374                    mSettings.writeLPr();
12375                }
12376            }
12377            // kill any non-foreground processes so we restart them and
12378            // grant/revoke the GID.
12379            final IActivityManager am = ActivityManagerNative.getDefault();
12380            if (am != null) {
12381                final long token = Binder.clearCallingIdentity();
12382                try {
12383                    am.killProcessesBelowForeground("setPermissionEnforcement");
12384                } catch (RemoteException e) {
12385                } finally {
12386                    Binder.restoreCallingIdentity(token);
12387                }
12388            }
12389        } else {
12390            throw new IllegalArgumentException("No selective enforcement for " + permission);
12391        }
12392    }
12393
12394    @Override
12395    @Deprecated
12396    public boolean isPermissionEnforced(String permission) {
12397        return true;
12398    }
12399
12400    @Override
12401    public boolean isStorageLow() {
12402        final long token = Binder.clearCallingIdentity();
12403        try {
12404            final DeviceStorageMonitorInternal
12405                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
12406            if (dsm != null) {
12407                return dsm.isMemoryLow();
12408            } else {
12409                return false;
12410            }
12411        } finally {
12412            Binder.restoreCallingIdentity(token);
12413        }
12414    }
12415}
12416