PackageManagerService.java revision 2b9146523347d4458d17d99824afdac29e312176
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_USER;
24import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
25import static com.android.internal.util.ArrayUtils.appendInt;
26import static com.android.internal.util.ArrayUtils.removeInt;
27import static libcore.io.OsConstants.S_ISLNK;
28
29import com.android.internal.app.IMediaContainerService;
30import com.android.internal.app.ResolverActivity;
31import com.android.internal.content.NativeLibraryHelper;
32import com.android.internal.content.PackageHelper;
33import com.android.internal.util.FastXmlSerializer;
34import com.android.internal.util.XmlUtils;
35import com.android.server.DeviceStorageMonitorService;
36import com.android.server.EventLogTags;
37import com.android.server.IntentResolver;
38
39import org.xmlpull.v1.XmlPullParser;
40import org.xmlpull.v1.XmlPullParserException;
41import org.xmlpull.v1.XmlSerializer;
42
43import android.app.ActivityManagerNative;
44import android.app.IActivityManager;
45import android.app.admin.IDevicePolicyManager;
46import android.app.backup.IBackupManager;
47import android.content.BroadcastReceiver;
48import android.content.ComponentName;
49import android.content.Context;
50import android.content.IIntentReceiver;
51import android.content.Intent;
52import android.content.IntentFilter;
53import android.content.IntentSender;
54import android.content.ServiceConnection;
55import android.content.IntentSender.SendIntentException;
56import android.content.pm.ActivityInfo;
57import android.content.pm.ApplicationInfo;
58import android.content.pm.ContainerEncryptionParams;
59import android.content.pm.FeatureInfo;
60import android.content.pm.IPackageDataObserver;
61import android.content.pm.IPackageDeleteObserver;
62import android.content.pm.IPackageInstallObserver;
63import android.content.pm.IPackageManager;
64import android.content.pm.IPackageMoveObserver;
65import android.content.pm.IPackageStatsObserver;
66import android.content.pm.InstrumentationInfo;
67import android.content.pm.PackageCleanItem;
68import android.content.pm.PackageInfo;
69import android.content.pm.PackageInfoLite;
70import android.content.pm.PackageManager;
71import android.content.pm.PackageParser;
72import android.content.pm.PackageUserState;
73import android.content.pm.PackageParser.ActivityIntentInfo;
74import android.content.pm.PackageStats;
75import android.content.pm.ParceledListSlice;
76import android.content.pm.PermissionGroupInfo;
77import android.content.pm.PermissionInfo;
78import android.content.pm.ProviderInfo;
79import android.content.pm.ResolveInfo;
80import android.content.pm.ServiceInfo;
81import android.content.pm.Signature;
82import android.content.pm.ManifestDigest;
83import android.content.pm.VerificationParams;
84import android.content.pm.VerifierDeviceIdentity;
85import android.content.pm.VerifierInfo;
86import android.net.Uri;
87import android.os.Binder;
88import android.os.Build;
89import android.os.Bundle;
90import android.os.Environment;
91import android.os.FileObserver;
92import android.os.FileUtils;
93import android.os.Handler;
94import android.os.HandlerThread;
95import android.os.IBinder;
96import android.os.Looper;
97import android.os.Message;
98import android.os.Parcel;
99import android.os.ParcelFileDescriptor;
100import android.os.Process;
101import android.os.RemoteException;
102import android.os.SELinux;
103import android.os.ServiceManager;
104import android.os.SystemClock;
105import android.os.SystemProperties;
106import android.os.UserHandle;
107import android.provider.Settings.Secure;
108import android.security.SystemKeyStore;
109import android.util.DisplayMetrics;
110import android.util.EventLog;
111import android.util.Log;
112import android.util.LogPrinter;
113import android.util.Slog;
114import android.util.SparseArray;
115import android.util.Xml;
116import android.view.Display;
117import android.view.WindowManager;
118
119import java.io.BufferedOutputStream;
120import java.io.File;
121import java.io.FileDescriptor;
122import java.io.FileInputStream;
123import java.io.FileNotFoundException;
124import java.io.FileOutputStream;
125import java.io.FileReader;
126import java.io.FilenameFilter;
127import java.io.IOException;
128import java.io.PrintWriter;
129import java.security.NoSuchAlgorithmException;
130import java.security.PublicKey;
131import java.security.cert.CertificateException;
132import java.text.SimpleDateFormat;
133import java.util.ArrayList;
134import java.util.Arrays;
135import java.util.Collection;
136import java.util.Collections;
137import java.util.Comparator;
138import java.util.Date;
139import java.util.HashMap;
140import java.util.HashSet;
141import java.util.Iterator;
142import java.util.List;
143import java.util.Map;
144import java.util.Map.Entry;
145import java.util.Set;
146
147import libcore.io.ErrnoException;
148import libcore.io.IoUtils;
149import libcore.io.Libcore;
150import libcore.io.StructStat;
151
152/**
153 * Keep track of all those .apks everywhere.
154 *
155 * This is very central to the platform's security; please run the unit
156 * tests whenever making modifications here:
157 *
158mmm frameworks/base/tests/AndroidTests
159adb install -r -f out/target/product/passion/data/app/AndroidTests.apk
160adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner
161 *
162 * {@hide}
163 */
164public class PackageManagerService extends IPackageManager.Stub {
165    static final String TAG = "PackageManager";
166    static final boolean DEBUG_SETTINGS = false;
167    private static final boolean DEBUG_PREFERRED = false;
168    static final boolean DEBUG_UPGRADE = false;
169    private static final boolean DEBUG_INSTALL = false;
170    private static final boolean DEBUG_REMOVE = false;
171    private static final boolean DEBUG_BROADCASTS = false;
172    private static final boolean DEBUG_SHOW_INFO = false;
173    private static final boolean DEBUG_PACKAGE_INFO = false;
174    private static final boolean DEBUG_INTENT_MATCHING = false;
175    private static final boolean DEBUG_PACKAGE_SCANNING = false;
176    private static final boolean DEBUG_APP_DIR_OBSERVER = false;
177    private static final boolean DEBUG_VERIFY = false;
178
179    private static final int RADIO_UID = Process.PHONE_UID;
180    private static final int LOG_UID = Process.LOG_UID;
181    private static final int NFC_UID = Process.NFC_UID;
182    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
183
184    private static final boolean GET_CERTIFICATES = true;
185
186    private static final int REMOVE_EVENTS =
187        FileObserver.CLOSE_WRITE | FileObserver.DELETE | FileObserver.MOVED_FROM;
188    private static final int ADD_EVENTS =
189        FileObserver.CLOSE_WRITE /*| FileObserver.CREATE*/ | FileObserver.MOVED_TO;
190
191    private static final int OBSERVER_EVENTS = REMOVE_EVENTS | ADD_EVENTS;
192    // Suffix used during package installation when copying/moving
193    // package apks to install directory.
194    private static final String INSTALL_PACKAGE_SUFFIX = "-";
195
196    static final int SCAN_MONITOR = 1<<0;
197    static final int SCAN_NO_DEX = 1<<1;
198    static final int SCAN_FORCE_DEX = 1<<2;
199    static final int SCAN_UPDATE_SIGNATURE = 1<<3;
200    static final int SCAN_NEW_INSTALL = 1<<4;
201    static final int SCAN_NO_PATHS = 1<<5;
202    static final int SCAN_UPDATE_TIME = 1<<6;
203    static final int SCAN_DEFER_DEX = 1<<7;
204    static final int SCAN_BOOTING = 1<<8;
205
206    static final int REMOVE_CHATTY = 1<<16;
207
208    /**
209     * Whether verification is enabled by default.
210     */
211    // STOPSHIP: change this to true
212    private static final boolean DEFAULT_VERIFY_ENABLE = false;
213
214    /**
215     * The default maximum time to wait for the verification agent to return in
216     * milliseconds.
217     */
218    private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
219
220    /**
221     * The default response for package verification timeout.
222     *
223     * This can be either PackageManager.VERIFICATION_ALLOW or
224     * PackageManager.VERIFICATION_REJECT.
225     */
226    private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
227
228    static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
229
230    static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
231            DEFAULT_CONTAINER_PACKAGE,
232            "com.android.defcontainer.DefaultContainerService");
233
234    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
235
236    private static final String LIB_DIR_NAME = "lib";
237
238    static final String mTempContainerPrefix = "smdl2tmp";
239
240    final HandlerThread mHandlerThread = new HandlerThread("PackageManager",
241            Process.THREAD_PRIORITY_BACKGROUND);
242    final PackageHandler mHandler;
243
244    final int mSdkVersion = Build.VERSION.SDK_INT;
245    final String mSdkCodename = "REL".equals(Build.VERSION.CODENAME)
246            ? null : Build.VERSION.CODENAME;
247
248    final Context mContext;
249    final boolean mFactoryTest;
250    final boolean mOnlyCore;
251    final boolean mNoDexOpt;
252    final DisplayMetrics mMetrics;
253    final int mDefParseFlags;
254    final String[] mSeparateProcesses;
255
256    // This is where all application persistent data goes.
257    final File mAppDataDir;
258
259    // This is where all application persistent data goes for secondary users.
260    final File mUserAppDataDir;
261
262    /** The location for ASEC container files on internal storage. */
263    final String mAsecInternalPath;
264
265    // This is the object monitoring the framework dir.
266    final FileObserver mFrameworkInstallObserver;
267
268    // This is the object monitoring the system app dir.
269    final FileObserver mSystemInstallObserver;
270
271    // This is the object monitoring the system app dir.
272    final FileObserver mVendorInstallObserver;
273
274    // This is the object monitoring mAppInstallDir.
275    final FileObserver mAppInstallObserver;
276
277    // This is the object monitoring mDrmAppPrivateInstallDir.
278    final FileObserver mDrmAppInstallObserver;
279
280    // Used for priviledge escalation.  MUST NOT BE CALLED WITH mPackages
281    // LOCK HELD.  Can be called with mInstallLock held.
282    final Installer mInstaller;
283
284    final File mFrameworkDir;
285    final File mSystemAppDir;
286    final File mVendorAppDir;
287    final File mAppInstallDir;
288    final File mDalvikCacheDir;
289
290    // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
291    // apps.
292    final File mDrmAppPrivateInstallDir;
293
294    // ----------------------------------------------------------------
295
296    // Lock for state used when installing and doing other long running
297    // operations.  Methods that must be called with this lock held have
298    // the prefix "LI".
299    final Object mInstallLock = new Object();
300
301    // These are the directories in the 3rd party applications installed dir
302    // that we have currently loaded packages from.  Keys are the application's
303    // installed zip file (absolute codePath), and values are Package.
304    final HashMap<String, PackageParser.Package> mAppDirs =
305            new HashMap<String, PackageParser.Package>();
306
307    // Information for the parser to write more useful error messages.
308    File mScanningPath;
309    int mLastScanError;
310
311    // ----------------------------------------------------------------
312
313    // Keys are String (package name), values are Package.  This also serves
314    // as the lock for the global state.  Methods that must be called with
315    // this lock held have the prefix "LP".
316    final HashMap<String, PackageParser.Package> mPackages =
317            new HashMap<String, PackageParser.Package>();
318
319    final Settings mSettings;
320    boolean mRestoredSettings;
321
322    // Group-ids that are given to all packages as read from etc/permissions/*.xml.
323    int[] mGlobalGids;
324
325    // These are the built-in uid -> permission mappings that were read from the
326    // etc/permissions.xml file.
327    final SparseArray<HashSet<String>> mSystemPermissions =
328            new SparseArray<HashSet<String>>();
329
330    // These are the built-in shared libraries that were read from the
331    // etc/permissions.xml file.
332    final HashMap<String, String> mSharedLibraries = new HashMap<String, String>();
333
334    // Temporary for building the final shared libraries for an .apk.
335    String[] mTmpSharedLibraries = null;
336
337    // These are the features this devices supports that were read from the
338    // etc/permissions.xml file.
339    final HashMap<String, FeatureInfo> mAvailableFeatures =
340            new HashMap<String, FeatureInfo>();
341
342    // All available activities, for your resolving pleasure.
343    final ActivityIntentResolver mActivities =
344            new ActivityIntentResolver();
345
346    // All available receivers, for your resolving pleasure.
347    final ActivityIntentResolver mReceivers =
348            new ActivityIntentResolver();
349
350    // All available services, for your resolving pleasure.
351    final ServiceIntentResolver mServices = new ServiceIntentResolver();
352
353    // Keys are String (provider class name), values are Provider.
354    final HashMap<ComponentName, PackageParser.Provider> mProvidersByComponent =
355            new HashMap<ComponentName, PackageParser.Provider>();
356
357    // Mapping from provider base names (first directory in content URI codePath)
358    // to the provider information.
359    final HashMap<String, PackageParser.Provider> mProviders =
360            new HashMap<String, PackageParser.Provider>();
361
362    // Mapping from instrumentation class names to info about them.
363    final HashMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
364            new HashMap<ComponentName, PackageParser.Instrumentation>();
365
366    // Mapping from permission names to info about them.
367    final HashMap<String, PackageParser.PermissionGroup> mPermissionGroups =
368            new HashMap<String, PackageParser.PermissionGroup>();
369
370    // Packages whose data we have transfered into another package, thus
371    // should no longer exist.
372    final HashSet<String> mTransferedPackages = new HashSet<String>();
373
374    // Broadcast actions that are only available to the system.
375    final HashSet<String> mProtectedBroadcasts = new HashSet<String>();
376
377    /** List of packages waiting for verification. */
378    final SparseArray<PackageVerificationState> mPendingVerification
379            = new SparseArray<PackageVerificationState>();
380
381    final ArrayList<PackageParser.Package> mDeferredDexOpt =
382            new ArrayList<PackageParser.Package>();
383
384    /** Token for keys in mPendingVerification. */
385    private int mPendingVerificationToken = 0;
386
387    boolean mSystemReady;
388    boolean mSafeMode;
389    boolean mHasSystemUidErrors;
390
391    ApplicationInfo mAndroidApplication;
392    final ActivityInfo mResolveActivity = new ActivityInfo();
393    final ResolveInfo mResolveInfo = new ResolveInfo();
394    ComponentName mResolveComponentName;
395    PackageParser.Package mPlatformPackage;
396
397    // Set of pending broadcasts for aggregating enable/disable of components.
398    final HashMap<String, ArrayList<String>> mPendingBroadcasts
399            = new HashMap<String, ArrayList<String>>();
400    // Service Connection to remote media container service to copy
401    // package uri's from external media onto secure containers
402    // or internal storage.
403    private IMediaContainerService mContainerService = null;
404    private int mContainerServiceUserId;
405
406    static final int SEND_PENDING_BROADCAST = 1;
407    static final int MCS_BOUND = 3;
408    static final int END_COPY = 4;
409    static final int INIT_COPY = 5;
410    static final int MCS_UNBIND = 6;
411    static final int START_CLEANING_PACKAGE = 7;
412    static final int FIND_INSTALL_LOC = 8;
413    static final int POST_INSTALL = 9;
414    static final int MCS_RECONNECT = 10;
415    static final int MCS_GIVE_UP = 11;
416    static final int UPDATED_MEDIA_STATUS = 12;
417    static final int WRITE_SETTINGS = 13;
418    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
419    static final int PACKAGE_VERIFIED = 15;
420    static final int CHECK_PENDING_VERIFICATION = 16;
421
422    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
423
424    // Delay time in millisecs
425    static final int BROADCAST_DELAY = 10 * 1000;
426
427    static UserManagerService sUserManager;
428
429    // Stores a list of users whose package restrictions file needs to be updated
430    private HashSet<Integer> mDirtyUsers = new HashSet<Integer>();
431
432    final private DefaultContainerConnection mDefContainerConn =
433            new DefaultContainerConnection();
434    class DefaultContainerConnection implements ServiceConnection {
435        public void onServiceConnected(ComponentName name, IBinder service) {
436            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
437            IMediaContainerService imcs =
438                IMediaContainerService.Stub.asInterface(service);
439            mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
440        }
441
442        public void onServiceDisconnected(ComponentName name) {
443            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
444        }
445    };
446
447    // Recordkeeping of restore-after-install operations that are currently in flight
448    // between the Package Manager and the Backup Manager
449    class PostInstallData {
450        public InstallArgs args;
451        public PackageInstalledInfo res;
452
453        PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
454            args = _a;
455            res = _r;
456        }
457    };
458    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
459    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
460
461    private final String mRequiredVerifierPackage;
462
463    class PackageHandler extends Handler {
464        private boolean mBound = false;
465        final ArrayList<HandlerParams> mPendingInstalls =
466            new ArrayList<HandlerParams>();
467
468        private boolean connectToService() {
469            if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
470                    " DefaultContainerService");
471            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
472            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
473            mContainerServiceUserId = 0;
474            if (mPendingInstalls.size() > 0) {
475                mContainerServiceUserId = mPendingInstalls.get(0).getUser().getIdentifier();
476                if (mContainerServiceUserId == UserHandle.USER_ALL) {
477                    mContainerServiceUserId = 0;
478                }
479            }
480            if (mContext.bindService(service, mDefContainerConn,
481                    Context.BIND_AUTO_CREATE, mContainerServiceUserId)) {
482                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
483                mBound = true;
484                return true;
485            }
486            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
487            return false;
488        }
489
490        private void disconnectService() {
491            mContainerService = null;
492            mBound = false;
493            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
494            mContext.unbindService(mDefContainerConn);
495            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
496        }
497
498        PackageHandler(Looper looper) {
499            super(looper);
500        }
501
502        public void handleMessage(Message msg) {
503            try {
504                doHandleMessage(msg);
505            } finally {
506                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
507            }
508        }
509
510        void doHandleMessage(Message msg) {
511            switch (msg.what) {
512                case INIT_COPY: {
513                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy");
514                    HandlerParams params = (HandlerParams) msg.obj;
515                    int idx = mPendingInstalls.size();
516                    if (DEBUG_INSTALL) Slog.i(TAG, "idx=" + idx);
517                    // If a bind was already initiated we dont really
518                    // need to do anything. The pending install
519                    // will be processed later on.
520                    if (!mBound) {
521                        // If this is the only one pending we might
522                        // have to bind to the service again.
523                        if (!connectToService()) {
524                            Slog.e(TAG, "Failed to bind to media container service");
525                            params.serviceError();
526                            return;
527                        } else {
528                            // Once we bind to the service, the first
529                            // pending request will be processed.
530                            mPendingInstalls.add(idx, params);
531                        }
532                    } else {
533                        mPendingInstalls.add(idx, params);
534                        // Already bound to the service. Just make
535                        // sure we trigger off processing the first request.
536                        if (idx == 0) {
537                            mHandler.sendEmptyMessage(MCS_BOUND);
538                        }
539                    }
540                    break;
541                }
542                case MCS_BOUND: {
543                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
544                    if (msg.obj != null) {
545                        mContainerService = (IMediaContainerService) msg.obj;
546                    }
547                    if (mContainerService == null) {
548                        // Something seriously wrong. Bail out
549                        Slog.e(TAG, "Cannot bind to media container service");
550                        for (HandlerParams params : mPendingInstalls) {
551                            // Indicate service bind error
552                            params.serviceError();
553                        }
554                        mPendingInstalls.clear();
555                    } else if (mPendingInstalls.size() > 0) {
556                        HandlerParams params = mPendingInstalls.get(0);
557                        if (params != null) {
558                            // Check if we're connected to the correct service, if it's an install
559                            // request.
560                            final int installFor = params.getUser().getIdentifier();
561                            if (installFor != mContainerServiceUserId
562                                    && (installFor == UserHandle.USER_ALL
563                                            && mContainerServiceUserId != 0)) {
564                                mHandler.sendEmptyMessage(MCS_RECONNECT);
565                                return;
566                            }
567                            if (params.startCopy()) {
568                                // We are done...  look for more work or to
569                                // go idle.
570                                if (DEBUG_SD_INSTALL) Log.i(TAG,
571                                        "Checking for more work or unbind...");
572                                // Delete pending install
573                                if (mPendingInstalls.size() > 0) {
574                                    mPendingInstalls.remove(0);
575                                }
576                                if (mPendingInstalls.size() == 0) {
577                                    if (mBound) {
578                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
579                                                "Posting delayed MCS_UNBIND");
580                                        removeMessages(MCS_UNBIND);
581                                        Message ubmsg = obtainMessage(MCS_UNBIND);
582                                        // Unbind after a little delay, to avoid
583                                        // continual thrashing.
584                                        sendMessageDelayed(ubmsg, 10000);
585                                    }
586                                } else {
587                                    // There are more pending requests in queue.
588                                    // Just post MCS_BOUND message to trigger processing
589                                    // of next pending install.
590                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
591                                            "Posting MCS_BOUND for next woek");
592                                    mHandler.sendEmptyMessage(MCS_BOUND);
593                                }
594                            }
595                        }
596                    } else {
597                        // Should never happen ideally.
598                        Slog.w(TAG, "Empty queue");
599                    }
600                    break;
601                }
602                case MCS_RECONNECT: {
603                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
604                    if (mPendingInstalls.size() > 0) {
605                        if (mBound) {
606                            disconnectService();
607                        }
608                        if (!connectToService()) {
609                            Slog.e(TAG, "Failed to bind to media container service");
610                            for (HandlerParams params : mPendingInstalls) {
611                                // Indicate service bind error
612                                params.serviceError();
613                            }
614                            mPendingInstalls.clear();
615                        }
616                    }
617                    break;
618                }
619                case MCS_UNBIND: {
620                    // If there is no actual work left, then time to unbind.
621                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
622
623                    if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
624                        if (mBound) {
625                            if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
626
627                            disconnectService();
628                        }
629                    } else if (mPendingInstalls.size() > 0) {
630                        // There are more pending requests in queue.
631                        // Just post MCS_BOUND message to trigger processing
632                        // of next pending install.
633                        mHandler.sendEmptyMessage(MCS_BOUND);
634                    }
635
636                    break;
637                }
638                case MCS_GIVE_UP: {
639                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
640                    mPendingInstalls.remove(0);
641                    break;
642                }
643                case SEND_PENDING_BROADCAST: {
644                    String packages[];
645                    ArrayList<String> components[];
646                    int size = 0;
647                    int uids[];
648                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
649                    synchronized (mPackages) {
650                        if (mPendingBroadcasts == null) {
651                            return;
652                        }
653                        size = mPendingBroadcasts.size();
654                        if (size <= 0) {
655                            // Nothing to be done. Just return
656                            return;
657                        }
658                        packages = new String[size];
659                        components = new ArrayList[size];
660                        uids = new int[size];
661                        Iterator<Map.Entry<String, ArrayList<String>>>
662                                it = mPendingBroadcasts.entrySet().iterator();
663                        int i = 0;
664                        while (it.hasNext() && i < size) {
665                            Map.Entry<String, ArrayList<String>> ent = it.next();
666                            packages[i] = ent.getKey();
667                            components[i] = ent.getValue();
668                            PackageSetting ps = mSettings.mPackages.get(ent.getKey());
669                            uids[i] = (ps != null) ? ps.appId : -1;
670                            i++;
671                        }
672                        size = i;
673                        mPendingBroadcasts.clear();
674                    }
675                    // Send broadcasts
676                    for (int i = 0; i < size; i++) {
677                        sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
678                    }
679                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
680                    break;
681                }
682                case START_CLEANING_PACKAGE: {
683                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
684                    PackageCleanItem item = new PackageCleanItem((String)msg.obj,
685                            msg.arg2 != 0);
686                    synchronized (mPackages) {
687                        if (msg.arg1 == UserHandle.USER_ALL) {
688                            int[] users = sUserManager.getUserIds();
689                            for (int user : users) {
690                                mSettings.addPackageToCleanLPw(user, item);
691                            }
692                        } else {
693                            mSettings.addPackageToCleanLPw(msg.arg1, item);
694                        }
695                    }
696                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
697                    startCleaningPackages(-1);
698                } break;
699                case POST_INSTALL: {
700                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
701                    PostInstallData data = mRunningInstalls.get(msg.arg1);
702                    mRunningInstalls.delete(msg.arg1);
703                    boolean deleteOld = false;
704
705                    if (data != null) {
706                        InstallArgs args = data.args;
707                        PackageInstalledInfo res = data.res;
708
709                        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
710                            res.removedInfo.sendBroadcast(false, true);
711                            Bundle extras = new Bundle(1);
712                            extras.putInt(Intent.EXTRA_UID, res.uid);
713                            final boolean update = res.removedInfo.removedPackage != null;
714                            if (update) {
715                                extras.putBoolean(Intent.EXTRA_REPLACING, true);
716                            }
717                            sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
718                                    res.pkg.applicationInfo.packageName,
719                                    extras, null, null, res.users);
720                            if (update) {
721                                sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
722                                        res.pkg.applicationInfo.packageName,
723                                        extras, null, null, res.users);
724                                sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
725                                        null, null,
726                                        res.pkg.applicationInfo.packageName, null, res.users);
727                            }
728                            if (res.removedInfo.args != null) {
729                                // Remove the replaced package's older resources safely now
730                                deleteOld = true;
731                            }
732
733                            // Log current value of "unknown sources" setting
734                            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
735                                getUnknownSourcesSettings());
736                        }
737                        // Force a gc to clear up things
738                        Runtime.getRuntime().gc();
739                        // We delete after a gc for applications  on sdcard.
740                        if (deleteOld) {
741                            synchronized (mInstallLock) {
742                                res.removedInfo.args.doPostDeleteLI(true);
743                            }
744                        }
745                        if (args.observer != null) {
746                            try {
747                                args.observer.packageInstalled(res.name, res.returnCode);
748                            } catch (RemoteException e) {
749                                Slog.i(TAG, "Observer no longer exists.");
750                            }
751                        }
752                    } else {
753                        Slog.e(TAG, "Bogus post-install token " + msg.arg1);
754                    }
755                } break;
756                case UPDATED_MEDIA_STATUS: {
757                    if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
758                    boolean reportStatus = msg.arg1 == 1;
759                    boolean doGc = msg.arg2 == 1;
760                    if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
761                    if (doGc) {
762                        // Force a gc to clear up stale containers.
763                        Runtime.getRuntime().gc();
764                    }
765                    if (msg.obj != null) {
766                        @SuppressWarnings("unchecked")
767                        Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
768                        if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
769                        // Unload containers
770                        unloadAllContainers(args);
771                    }
772                    if (reportStatus) {
773                        try {
774                            if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back");
775                            PackageHelper.getMountService().finishMediaUpdate();
776                        } catch (RemoteException e) {
777                            Log.e(TAG, "MountService not running?");
778                        }
779                    }
780                } break;
781                case WRITE_SETTINGS: {
782                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
783                    synchronized (mPackages) {
784                        removeMessages(WRITE_SETTINGS);
785                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
786                        mSettings.writeLPr();
787                        mDirtyUsers.clear();
788                    }
789                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
790                } break;
791                case WRITE_PACKAGE_RESTRICTIONS: {
792                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
793                    synchronized (mPackages) {
794                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
795                        for (int userId : mDirtyUsers) {
796                            mSettings.writePackageRestrictionsLPr(userId);
797                        }
798                        mDirtyUsers.clear();
799                    }
800                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
801                } break;
802                case CHECK_PENDING_VERIFICATION: {
803                    final int verificationId = msg.arg1;
804                    final PackageVerificationState state = mPendingVerification.get(verificationId);
805
806                    if ((state != null) && !state.timeoutExtended()) {
807                        final InstallArgs args = state.getInstallArgs();
808                        Slog.i(TAG, "Verification timed out for " + args.packageURI.toString());
809                        mPendingVerification.remove(verificationId);
810
811                        int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
812
813                        if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
814                            Slog.i(TAG, "Continuing with installation of "
815                                    + args.packageURI.toString());
816                            state.setVerifierResponse(Binder.getCallingUid(),
817                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
818                            try {
819                                ret = args.copyApk(mContainerService, true);
820                            } catch (RemoteException e) {
821                                Slog.e(TAG, "Could not contact the ContainerService");
822                            }
823                        }
824
825                        processPendingInstall(args, ret);
826                        mHandler.sendEmptyMessage(MCS_UNBIND);
827                    }
828                    break;
829                }
830                case PACKAGE_VERIFIED: {
831                    final int verificationId = msg.arg1;
832
833                    final PackageVerificationState state = mPendingVerification.get(verificationId);
834                    if (state == null) {
835                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
836                        break;
837                    }
838
839                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
840
841                    state.setVerifierResponse(response.callerUid, response.code);
842
843                    if (state.isVerificationComplete()) {
844                        mPendingVerification.remove(verificationId);
845
846                        final InstallArgs args = state.getInstallArgs();
847
848                        int ret;
849                        if (state.isInstallAllowed()) {
850                            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
851                            try {
852                                ret = args.copyApk(mContainerService, true);
853                            } catch (RemoteException e) {
854                                Slog.e(TAG, "Could not contact the ContainerService");
855                            }
856                        } else {
857                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
858                        }
859
860                        processPendingInstall(args, ret);
861
862                        mHandler.sendEmptyMessage(MCS_UNBIND);
863                    }
864
865                    break;
866                }
867            }
868        }
869    }
870
871    void scheduleWriteSettingsLocked() {
872        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
873            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
874        }
875    }
876
877    void scheduleWritePackageRestrictionsLocked(int userId) {
878        if (!sUserManager.exists(userId)) return;
879        mDirtyUsers.add(userId);
880        if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
881            mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
882        }
883    }
884
885    public static final IPackageManager main(Context context, boolean factoryTest,
886            boolean onlyCore) {
887        PackageManagerService m = new PackageManagerService(context, factoryTest, onlyCore);
888        ServiceManager.addService("package", m);
889        return m;
890    }
891
892    static String[] splitString(String str, char sep) {
893        int count = 1;
894        int i = 0;
895        while ((i=str.indexOf(sep, i)) >= 0) {
896            count++;
897            i++;
898        }
899
900        String[] res = new String[count];
901        i=0;
902        count = 0;
903        int lastI=0;
904        while ((i=str.indexOf(sep, i)) >= 0) {
905            res[count] = str.substring(lastI, i);
906            count++;
907            i++;
908            lastI = i;
909        }
910        res[count] = str.substring(lastI, str.length());
911        return res;
912    }
913
914    public PackageManagerService(Context context, boolean factoryTest, boolean onlyCore) {
915        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
916                SystemClock.uptimeMillis());
917
918        if (mSdkVersion <= 0) {
919            Slog.w(TAG, "**** ro.build.version.sdk not set!");
920        }
921
922        mContext = context;
923        mFactoryTest = factoryTest;
924        mOnlyCore = onlyCore;
925        mNoDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));
926        mMetrics = new DisplayMetrics();
927        mSettings = new Settings(context);
928        mSettings.addSharedUserLPw("android.uid.system",
929                Process.SYSTEM_UID, ApplicationInfo.FLAG_SYSTEM);
930        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, ApplicationInfo.FLAG_SYSTEM);
931        mSettings.addSharedUserLPw("android.uid.log", LOG_UID, ApplicationInfo.FLAG_SYSTEM);
932        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, ApplicationInfo.FLAG_SYSTEM);
933        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, ApplicationInfo.FLAG_SYSTEM);
934
935        String separateProcesses = SystemProperties.get("debug.separate_processes");
936        if (separateProcesses != null && separateProcesses.length() > 0) {
937            if ("*".equals(separateProcesses)) {
938                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
939                mSeparateProcesses = null;
940                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
941            } else {
942                mDefParseFlags = 0;
943                mSeparateProcesses = separateProcesses.split(",");
944                Slog.w(TAG, "Running with debug.separate_processes: "
945                        + separateProcesses);
946            }
947        } else {
948            mDefParseFlags = 0;
949            mSeparateProcesses = null;
950        }
951
952        mInstaller = new Installer();
953
954        WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
955        Display d = wm.getDefaultDisplay();
956        d.getMetrics(mMetrics);
957
958        synchronized (mInstallLock) {
959        // writer
960        synchronized (mPackages) {
961            mHandlerThread.start();
962            mHandler = new PackageHandler(mHandlerThread.getLooper());
963
964            File dataDir = Environment.getDataDirectory();
965            mAppDataDir = new File(dataDir, "data");
966            mAsecInternalPath = new File(dataDir, "app-asec").getPath();
967            mUserAppDataDir = new File(dataDir, "user");
968            mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
969
970            sUserManager = new UserManagerService(context, this,
971                    mInstallLock, mPackages);
972
973            readPermissions();
974
975            mRestoredSettings = mSettings.readLPw(sUserManager.getUsers());
976            long startTime = SystemClock.uptimeMillis();
977
978            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
979                    startTime);
980
981            // Set flag to monitor and not change apk file paths when
982            // scanning install directories.
983            int scanMode = SCAN_MONITOR | SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING;
984            if (mNoDexOpt) {
985                Slog.w(TAG, "Running ENG build: no pre-dexopt!");
986                scanMode |= SCAN_NO_DEX;
987            }
988
989            final HashSet<String> libFiles = new HashSet<String>();
990
991            mFrameworkDir = new File(Environment.getRootDirectory(), "framework");
992            mDalvikCacheDir = new File(dataDir, "dalvik-cache");
993
994            boolean didDexOpt = false;
995
996            /**
997             * Out of paranoia, ensure that everything in the boot class
998             * path has been dexed.
999             */
1000            String bootClassPath = System.getProperty("java.boot.class.path");
1001            if (bootClassPath != null) {
1002                String[] paths = splitString(bootClassPath, ':');
1003                for (int i=0; i<paths.length; i++) {
1004                    try {
1005                        if (dalvik.system.DexFile.isDexOptNeeded(paths[i])) {
1006                            libFiles.add(paths[i]);
1007                            mInstaller.dexopt(paths[i], Process.SYSTEM_UID, true);
1008                            didDexOpt = true;
1009                        }
1010                    } catch (FileNotFoundException e) {
1011                        Slog.w(TAG, "Boot class path not found: " + paths[i]);
1012                    } catch (IOException e) {
1013                        Slog.w(TAG, "Cannot dexopt " + paths[i] + "; is it an APK or JAR? "
1014                                + e.getMessage());
1015                    }
1016                }
1017            } else {
1018                Slog.w(TAG, "No BOOTCLASSPATH found!");
1019            }
1020
1021            /**
1022             * Also ensure all external libraries have had dexopt run on them.
1023             */
1024            if (mSharedLibraries.size() > 0) {
1025                Iterator<String> libs = mSharedLibraries.values().iterator();
1026                while (libs.hasNext()) {
1027                    String lib = libs.next();
1028                    try {
1029                        if (dalvik.system.DexFile.isDexOptNeeded(lib)) {
1030                            libFiles.add(lib);
1031                            mInstaller.dexopt(lib, Process.SYSTEM_UID, true);
1032                            didDexOpt = true;
1033                        }
1034                    } catch (FileNotFoundException e) {
1035                        Slog.w(TAG, "Library not found: " + lib);
1036                    } catch (IOException e) {
1037                        Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
1038                                + e.getMessage());
1039                    }
1040                }
1041            }
1042
1043            // Gross hack for now: we know this file doesn't contain any
1044            // code, so don't dexopt it to avoid the resulting log spew.
1045            libFiles.add(mFrameworkDir.getPath() + "/framework-res.apk");
1046
1047            /**
1048             * And there are a number of commands implemented in Java, which
1049             * we currently need to do the dexopt on so that they can be
1050             * run from a non-root shell.
1051             */
1052            String[] frameworkFiles = mFrameworkDir.list();
1053            if (frameworkFiles != null) {
1054                for (int i=0; i<frameworkFiles.length; i++) {
1055                    File libPath = new File(mFrameworkDir, frameworkFiles[i]);
1056                    String path = libPath.getPath();
1057                    // Skip the file if we alrady did it.
1058                    if (libFiles.contains(path)) {
1059                        continue;
1060                    }
1061                    // Skip the file if it is not a type we want to dexopt.
1062                    if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
1063                        continue;
1064                    }
1065                    try {
1066                        if (dalvik.system.DexFile.isDexOptNeeded(path)) {
1067                            mInstaller.dexopt(path, Process.SYSTEM_UID, true);
1068                            didDexOpt = true;
1069                        }
1070                    } catch (FileNotFoundException e) {
1071                        Slog.w(TAG, "Jar not found: " + path);
1072                    } catch (IOException e) {
1073                        Slog.w(TAG, "Exception reading jar: " + path, e);
1074                    }
1075                }
1076            }
1077
1078            if (didDexOpt) {
1079                // If we had to do a dexopt of one of the previous
1080                // things, then something on the system has changed.
1081                // Consider this significant, and wipe away all other
1082                // existing dexopt files to ensure we don't leave any
1083                // dangling around.
1084                String[] files = mDalvikCacheDir.list();
1085                if (files != null) {
1086                    for (int i=0; i<files.length; i++) {
1087                        String fn = files[i];
1088                        if (fn.startsWith("data@app@")
1089                                || fn.startsWith("data@app-private@")) {
1090                            Slog.i(TAG, "Pruning dalvik file: " + fn);
1091                            (new File(mDalvikCacheDir, fn)).delete();
1092                        }
1093                    }
1094                }
1095            }
1096
1097            // Find base frameworks (resource packages without code).
1098            mFrameworkInstallObserver = new AppDirObserver(
1099                mFrameworkDir.getPath(), OBSERVER_EVENTS, true);
1100            mFrameworkInstallObserver.startWatching();
1101            scanDirLI(mFrameworkDir, PackageParser.PARSE_IS_SYSTEM
1102                    | PackageParser.PARSE_IS_SYSTEM_DIR,
1103                    scanMode | SCAN_NO_DEX, 0);
1104
1105            // Collect all system packages.
1106            mSystemAppDir = new File(Environment.getRootDirectory(), "app");
1107            mSystemInstallObserver = new AppDirObserver(
1108                mSystemAppDir.getPath(), OBSERVER_EVENTS, true);
1109            mSystemInstallObserver.startWatching();
1110            scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM
1111                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
1112
1113            // Collect all vendor packages.
1114            mVendorAppDir = new File("/vendor/app");
1115            mVendorInstallObserver = new AppDirObserver(
1116                mVendorAppDir.getPath(), OBSERVER_EVENTS, true);
1117            mVendorInstallObserver.startWatching();
1118            scanDirLI(mVendorAppDir, PackageParser.PARSE_IS_SYSTEM
1119                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
1120
1121            if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");
1122            mInstaller.moveFiles();
1123
1124            // Prune any system packages that no longer exist.
1125            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
1126            if (!mOnlyCore) {
1127                Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
1128                while (psit.hasNext()) {
1129                    PackageSetting ps = psit.next();
1130
1131                    /*
1132                     * If this is not a system app, it can't be a
1133                     * disable system app.
1134                     */
1135                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
1136                        continue;
1137                    }
1138
1139                    /*
1140                     * If the package is scanned, it's not erased.
1141                     */
1142                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
1143                    if (scannedPkg != null) {
1144                        /*
1145                         * If the system app is both scanned and in the
1146                         * disabled packages list, then it must have been
1147                         * added via OTA. Remove it from the currently
1148                         * scanned package so the previously user-installed
1149                         * application can be scanned.
1150                         */
1151                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
1152                            Slog.i(TAG, "Expecting better updatd system app for " + ps.name
1153                                    + "; removing system app");
1154                            removePackageLI(scannedPkg, true);
1155                        }
1156
1157                        continue;
1158                    }
1159
1160                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
1161                        psit.remove();
1162                        String msg = "System package " + ps.name
1163                                + " no longer exists; wiping its data";
1164                        reportSettingsProblem(Log.WARN, msg);
1165                        removeDataDirsLI(ps.name);
1166                    } else {
1167                        final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
1168                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
1169                            possiblyDeletedUpdatedSystemApps.add(ps.name);
1170                        }
1171                    }
1172                }
1173            }
1174
1175            mAppInstallDir = new File(dataDir, "app");
1176            //look for any incomplete package installations
1177            ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
1178            //clean up list
1179            for(int i = 0; i < deletePkgsList.size(); i++) {
1180                //clean up here
1181                cleanupInstallFailedPackage(deletePkgsList.get(i));
1182            }
1183            //delete tmp files
1184            deleteTempPackageFiles();
1185
1186            if (!mOnlyCore) {
1187                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
1188                        SystemClock.uptimeMillis());
1189                mAppInstallObserver = new AppDirObserver(
1190                    mAppInstallDir.getPath(), OBSERVER_EVENTS, false);
1191                mAppInstallObserver.startWatching();
1192                scanDirLI(mAppInstallDir, 0, scanMode, 0);
1193
1194                mDrmAppInstallObserver = new AppDirObserver(
1195                    mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false);
1196                mDrmAppInstallObserver.startWatching();
1197                scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
1198                        scanMode, 0);
1199
1200                /**
1201                 * Remove disable package settings for any updated system
1202                 * apps that were removed via an OTA. If they're not a
1203                 * previously-updated app, remove them completely.
1204                 * Otherwise, just revoke their system-level permissions.
1205                 */
1206                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
1207                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
1208                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
1209
1210                    String msg;
1211                    if (deletedPkg == null) {
1212                        msg = "Updated system package " + deletedAppName
1213                                + " no longer exists; wiping its data";
1214                        removeDataDirsLI(deletedAppName);
1215                    } else {
1216                        msg = "Updated system app + " + deletedAppName
1217                                + " no longer present; removing system privileges for "
1218                                + deletedAppName;
1219
1220                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
1221
1222                        PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
1223                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
1224                    }
1225                    reportSettingsProblem(Log.WARN, msg);
1226                }
1227            } else {
1228                mAppInstallObserver = null;
1229                mDrmAppInstallObserver = null;
1230            }
1231
1232            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
1233                    SystemClock.uptimeMillis());
1234            Slog.i(TAG, "Time to scan packages: "
1235                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
1236                    + " seconds");
1237
1238            // If the platform SDK has changed since the last time we booted,
1239            // we need to re-grant app permission to catch any new ones that
1240            // appear.  This is really a hack, and means that apps can in some
1241            // cases get permissions that the user didn't initially explicitly
1242            // allow...  it would be nice to have some better way to handle
1243            // this situation.
1244            final boolean regrantPermissions = mSettings.mInternalSdkPlatform
1245                    != mSdkVersion;
1246            if (regrantPermissions) Slog.i(TAG, "Platform changed from "
1247                    + mSettings.mInternalSdkPlatform + " to " + mSdkVersion
1248                    + "; regranting permissions for internal storage");
1249            mSettings.mInternalSdkPlatform = mSdkVersion;
1250
1251            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
1252                    | (regrantPermissions
1253                            ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
1254                            : 0));
1255
1256            // Verify that all of the preferred activity components actually
1257            // exist.  It is possible for applications to be updated and at
1258            // that point remove a previously declared activity component that
1259            // had been set as a preferred activity.  We try to clean this up
1260            // the next time we encounter that preferred activity, but it is
1261            // possible for the user flow to never be able to return to that
1262            // situation so here we do a sanity check to make sure we haven't
1263            // left any junk around.
1264            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
1265            for (PreferredActivity pa : mSettings.mPreferredActivities.filterSet()) {
1266                if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
1267                    removed.add(pa);
1268                }
1269            }
1270            for (int i=0; i<removed.size(); i++) {
1271                PreferredActivity pa = removed.get(i);
1272                Slog.w(TAG, "Removing dangling preferred activity: "
1273                        + pa.mPref.mComponent);
1274                mSettings.mPreferredActivities.removeFilter(pa);
1275            }
1276
1277            // can downgrade to reader
1278            mSettings.writeLPr();
1279
1280            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
1281                    SystemClock.uptimeMillis());
1282
1283            // Now after opening every single application zip, make sure they
1284            // are all flushed.  Not really needed, but keeps things nice and
1285            // tidy.
1286            Runtime.getRuntime().gc();
1287
1288            mRequiredVerifierPackage = getRequiredVerifierLPr();
1289        } // synchronized (mPackages)
1290        } // synchronized (mInstallLock)
1291    }
1292
1293    public boolean isFirstBoot() {
1294        return !mRestoredSettings;
1295    }
1296
1297    private String getRequiredVerifierLPr() {
1298        final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
1299        final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE,
1300                PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */);
1301
1302        String requiredVerifier = null;
1303
1304        final int N = receivers.size();
1305        for (int i = 0; i < N; i++) {
1306            final ResolveInfo info = receivers.get(i);
1307
1308            if (info.activityInfo == null) {
1309                continue;
1310            }
1311
1312            final String packageName = info.activityInfo.packageName;
1313
1314            final PackageSetting ps = mSettings.mPackages.get(packageName);
1315            if (ps == null) {
1316                continue;
1317            }
1318
1319            if (!ps.grantedPermissions
1320                    .contains(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT)) {
1321                continue;
1322            }
1323
1324            if (requiredVerifier != null) {
1325                throw new RuntimeException("There can be only one required verifier");
1326            }
1327
1328            requiredVerifier = packageName;
1329        }
1330
1331        return requiredVerifier;
1332    }
1333
1334    @Override
1335    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1336            throws RemoteException {
1337        try {
1338            return super.onTransact(code, data, reply, flags);
1339        } catch (RuntimeException e) {
1340            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
1341                Slog.e(TAG, "Package Manager Crash", e);
1342            }
1343            throw e;
1344        }
1345    }
1346
1347    void cleanupInstallFailedPackage(PackageSetting ps) {
1348        Slog.i(TAG, "Cleaning up incompletely installed app: " + ps.name);
1349        removeDataDirsLI(ps.name);
1350        if (ps.codePath != null) {
1351            if (!ps.codePath.delete()) {
1352                Slog.w(TAG, "Unable to remove old code file: " + ps.codePath);
1353            }
1354        }
1355        if (ps.resourcePath != null) {
1356            if (!ps.resourcePath.delete() && !ps.resourcePath.equals(ps.codePath)) {
1357                Slog.w(TAG, "Unable to remove old code file: " + ps.resourcePath);
1358            }
1359        }
1360        mSettings.removePackageLPw(ps.name);
1361    }
1362
1363    void readPermissions() {
1364        // Read permissions from .../etc/permission directory.
1365        File libraryDir = new File(Environment.getRootDirectory(), "etc/permissions");
1366        if (!libraryDir.exists() || !libraryDir.isDirectory()) {
1367            Slog.w(TAG, "No directory " + libraryDir + ", skipping");
1368            return;
1369        }
1370        if (!libraryDir.canRead()) {
1371            Slog.w(TAG, "Directory " + libraryDir + " cannot be read");
1372            return;
1373        }
1374
1375        // Iterate over the files in the directory and scan .xml files
1376        for (File f : libraryDir.listFiles()) {
1377            // We'll read platform.xml last
1378            if (f.getPath().endsWith("etc/permissions/platform.xml")) {
1379                continue;
1380            }
1381
1382            if (!f.getPath().endsWith(".xml")) {
1383                Slog.i(TAG, "Non-xml file " + f + " in " + libraryDir + " directory, ignoring");
1384                continue;
1385            }
1386            if (!f.canRead()) {
1387                Slog.w(TAG, "Permissions library file " + f + " cannot be read");
1388                continue;
1389            }
1390
1391            readPermissionsFromXml(f);
1392        }
1393
1394        // Read permissions from .../etc/permissions/platform.xml last so it will take precedence
1395        final File permFile = new File(Environment.getRootDirectory(),
1396                "etc/permissions/platform.xml");
1397        readPermissionsFromXml(permFile);
1398    }
1399
1400    private void readPermissionsFromXml(File permFile) {
1401        FileReader permReader = null;
1402        try {
1403            permReader = new FileReader(permFile);
1404        } catch (FileNotFoundException e) {
1405            Slog.w(TAG, "Couldn't find or open permissions file " + permFile);
1406            return;
1407        }
1408
1409        try {
1410            XmlPullParser parser = Xml.newPullParser();
1411            parser.setInput(permReader);
1412
1413            XmlUtils.beginDocument(parser, "permissions");
1414
1415            while (true) {
1416                XmlUtils.nextElement(parser);
1417                if (parser.getEventType() == XmlPullParser.END_DOCUMENT) {
1418                    break;
1419                }
1420
1421                String name = parser.getName();
1422                if ("group".equals(name)) {
1423                    String gidStr = parser.getAttributeValue(null, "gid");
1424                    if (gidStr != null) {
1425                        int gid = Integer.parseInt(gidStr);
1426                        mGlobalGids = appendInt(mGlobalGids, gid);
1427                    } else {
1428                        Slog.w(TAG, "<group> without gid at "
1429                                + parser.getPositionDescription());
1430                    }
1431
1432                    XmlUtils.skipCurrentTag(parser);
1433                    continue;
1434                } else if ("permission".equals(name)) {
1435                    String perm = parser.getAttributeValue(null, "name");
1436                    if (perm == null) {
1437                        Slog.w(TAG, "<permission> without name at "
1438                                + parser.getPositionDescription());
1439                        XmlUtils.skipCurrentTag(parser);
1440                        continue;
1441                    }
1442                    perm = perm.intern();
1443                    readPermission(parser, perm);
1444
1445                } else if ("assign-permission".equals(name)) {
1446                    String perm = parser.getAttributeValue(null, "name");
1447                    if (perm == null) {
1448                        Slog.w(TAG, "<assign-permission> without name at "
1449                                + parser.getPositionDescription());
1450                        XmlUtils.skipCurrentTag(parser);
1451                        continue;
1452                    }
1453                    String uidStr = parser.getAttributeValue(null, "uid");
1454                    if (uidStr == null) {
1455                        Slog.w(TAG, "<assign-permission> without uid at "
1456                                + parser.getPositionDescription());
1457                        XmlUtils.skipCurrentTag(parser);
1458                        continue;
1459                    }
1460                    int uid = Process.getUidForName(uidStr);
1461                    if (uid < 0) {
1462                        Slog.w(TAG, "<assign-permission> with unknown uid \""
1463                                + uidStr + "\" at "
1464                                + parser.getPositionDescription());
1465                        XmlUtils.skipCurrentTag(parser);
1466                        continue;
1467                    }
1468                    perm = perm.intern();
1469                    HashSet<String> perms = mSystemPermissions.get(uid);
1470                    if (perms == null) {
1471                        perms = new HashSet<String>();
1472                        mSystemPermissions.put(uid, perms);
1473                    }
1474                    perms.add(perm);
1475                    XmlUtils.skipCurrentTag(parser);
1476
1477                } else if ("library".equals(name)) {
1478                    String lname = parser.getAttributeValue(null, "name");
1479                    String lfile = parser.getAttributeValue(null, "file");
1480                    if (lname == null) {
1481                        Slog.w(TAG, "<library> without name at "
1482                                + parser.getPositionDescription());
1483                    } else if (lfile == null) {
1484                        Slog.w(TAG, "<library> without file at "
1485                                + parser.getPositionDescription());
1486                    } else {
1487                        //Log.i(TAG, "Got library " + lname + " in " + lfile);
1488                        mSharedLibraries.put(lname, lfile);
1489                    }
1490                    XmlUtils.skipCurrentTag(parser);
1491                    continue;
1492
1493                } else if ("feature".equals(name)) {
1494                    String fname = parser.getAttributeValue(null, "name");
1495                    if (fname == null) {
1496                        Slog.w(TAG, "<feature> without name at "
1497                                + parser.getPositionDescription());
1498                    } else {
1499                        //Log.i(TAG, "Got feature " + fname);
1500                        FeatureInfo fi = new FeatureInfo();
1501                        fi.name = fname;
1502                        mAvailableFeatures.put(fname, fi);
1503                    }
1504                    XmlUtils.skipCurrentTag(parser);
1505                    continue;
1506
1507                } else {
1508                    XmlUtils.skipCurrentTag(parser);
1509                    continue;
1510                }
1511
1512            }
1513            permReader.close();
1514        } catch (XmlPullParserException e) {
1515            Slog.w(TAG, "Got execption parsing permissions.", e);
1516        } catch (IOException e) {
1517            Slog.w(TAG, "Got execption parsing permissions.", e);
1518        }
1519    }
1520
1521    void readPermission(XmlPullParser parser, String name)
1522            throws IOException, XmlPullParserException {
1523
1524        name = name.intern();
1525
1526        BasePermission bp = mSettings.mPermissions.get(name);
1527        if (bp == null) {
1528            bp = new BasePermission(name, null, BasePermission.TYPE_BUILTIN);
1529            mSettings.mPermissions.put(name, bp);
1530        }
1531        int outerDepth = parser.getDepth();
1532        int type;
1533        while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
1534               && (type != XmlPullParser.END_TAG
1535                       || parser.getDepth() > outerDepth)) {
1536            if (type == XmlPullParser.END_TAG
1537                    || type == XmlPullParser.TEXT) {
1538                continue;
1539            }
1540
1541            String tagName = parser.getName();
1542            if ("group".equals(tagName)) {
1543                String gidStr = parser.getAttributeValue(null, "gid");
1544                if (gidStr != null) {
1545                    int gid = Process.getGidForName(gidStr);
1546                    bp.gids = appendInt(bp.gids, gid);
1547                } else {
1548                    Slog.w(TAG, "<group> without gid at "
1549                            + parser.getPositionDescription());
1550                }
1551            }
1552            XmlUtils.skipCurrentTag(parser);
1553        }
1554    }
1555
1556    static int[] appendInts(int[] cur, int[] add) {
1557        if (add == null) return cur;
1558        if (cur == null) return add;
1559        final int N = add.length;
1560        for (int i=0; i<N; i++) {
1561            cur = appendInt(cur, add[i]);
1562        }
1563        return cur;
1564    }
1565
1566    static int[] removeInts(int[] cur, int[] rem) {
1567        if (rem == null) return cur;
1568        if (cur == null) return cur;
1569        final int N = rem.length;
1570        for (int i=0; i<N; i++) {
1571            cur = removeInt(cur, rem[i]);
1572        }
1573        return cur;
1574    }
1575
1576    PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) {
1577        if (!sUserManager.exists(userId)) return null;
1578        PackageInfo pi;
1579        final PackageSetting ps = (PackageSetting) p.mExtras;
1580        if (ps == null) {
1581            return null;
1582        }
1583        final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
1584        final PackageUserState state = ps.readUserState(userId);
1585        pi = PackageParser.generatePackageInfo(p, gp.gids, flags,
1586                ps.firstInstallTime, ps.lastUpdateTime, gp.grantedPermissions,
1587                state, userId);
1588        if (pi != null) {
1589            pi.applicationInfo.enabledSetting = state.enabled;
1590            pi.applicationInfo.enabled =
1591                    pi.applicationInfo.enabledSetting == COMPONENT_ENABLED_STATE_DEFAULT
1592                    || pi.applicationInfo.enabledSetting == COMPONENT_ENABLED_STATE_ENABLED;
1593        }
1594        return pi;
1595    }
1596
1597    @Override
1598    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
1599        if (!sUserManager.exists(userId)) return null;
1600        // reader
1601        synchronized (mPackages) {
1602            PackageParser.Package p = mPackages.get(packageName);
1603            if (DEBUG_PACKAGE_INFO)
1604                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
1605            if (p != null) {
1606                return generatePackageInfo(p, flags, userId);
1607            }
1608            if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
1609                return generatePackageInfoFromSettingsLPw(packageName, flags, userId);
1610            }
1611        }
1612        return null;
1613    }
1614
1615    public String[] currentToCanonicalPackageNames(String[] names) {
1616        String[] out = new String[names.length];
1617        // reader
1618        synchronized (mPackages) {
1619            for (int i=names.length-1; i>=0; i--) {
1620                PackageSetting ps = mSettings.mPackages.get(names[i]);
1621                out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
1622            }
1623        }
1624        return out;
1625    }
1626
1627    public String[] canonicalToCurrentPackageNames(String[] names) {
1628        String[] out = new String[names.length];
1629        // reader
1630        synchronized (mPackages) {
1631            for (int i=names.length-1; i>=0; i--) {
1632                String cur = mSettings.mRenamedPackages.get(names[i]);
1633                out[i] = cur != null ? cur : names[i];
1634            }
1635        }
1636        return out;
1637    }
1638
1639    @Override
1640    public int getPackageUid(String packageName, int userId) {
1641        if (!sUserManager.exists(userId)) return -1;
1642        // reader
1643        synchronized (mPackages) {
1644            PackageParser.Package p = mPackages.get(packageName);
1645            if(p != null) {
1646                return UserHandle.getUid(userId, p.applicationInfo.uid);
1647            }
1648            PackageSetting ps = mSettings.mPackages.get(packageName);
1649            if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) {
1650                return -1;
1651            }
1652            p = ps.pkg;
1653            return p != null ? UserHandle.getUid(userId, p.applicationInfo.uid) : -1;
1654        }
1655    }
1656
1657    public int[] getPackageGids(String packageName) {
1658        // reader
1659        synchronized (mPackages) {
1660            PackageParser.Package p = mPackages.get(packageName);
1661            if (DEBUG_PACKAGE_INFO)
1662                Log.v(TAG, "getPackageGids" + packageName + ": " + p);
1663            if (p != null) {
1664                final PackageSetting ps = (PackageSetting)p.mExtras;
1665                final SharedUserSetting suid = ps.sharedUser;
1666                int[] gids = suid != null ? suid.gids : ps.gids;
1667
1668                // include GIDs for any unenforced permissions
1669                if (!isPermissionEnforcedLocked(READ_EXTERNAL_STORAGE)) {
1670                    final BasePermission basePerm = mSettings.mPermissions.get(
1671                            READ_EXTERNAL_STORAGE);
1672                    gids = appendInts(gids, basePerm.gids);
1673                }
1674
1675                return gids;
1676            }
1677        }
1678        // stupid thing to indicate an error.
1679        return new int[0];
1680    }
1681
1682    static final PermissionInfo generatePermissionInfo(
1683            BasePermission bp, int flags) {
1684        if (bp.perm != null) {
1685            return PackageParser.generatePermissionInfo(bp.perm, flags);
1686        }
1687        PermissionInfo pi = new PermissionInfo();
1688        pi.name = bp.name;
1689        pi.packageName = bp.sourcePackage;
1690        pi.nonLocalizedLabel = bp.name;
1691        pi.protectionLevel = bp.protectionLevel;
1692        return pi;
1693    }
1694
1695    public PermissionInfo getPermissionInfo(String name, int flags) {
1696        // reader
1697        synchronized (mPackages) {
1698            final BasePermission p = mSettings.mPermissions.get(name);
1699            if (p != null) {
1700                return generatePermissionInfo(p, flags);
1701            }
1702            return null;
1703        }
1704    }
1705
1706    public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) {
1707        // reader
1708        synchronized (mPackages) {
1709            ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
1710            for (BasePermission p : mSettings.mPermissions.values()) {
1711                if (group == null) {
1712                    if (p.perm == null || p.perm.info.group == null) {
1713                        out.add(generatePermissionInfo(p, flags));
1714                    }
1715                } else {
1716                    if (p.perm != null && group.equals(p.perm.info.group)) {
1717                        out.add(PackageParser.generatePermissionInfo(p.perm, flags));
1718                    }
1719                }
1720            }
1721
1722            if (out.size() > 0) {
1723                return out;
1724            }
1725            return mPermissionGroups.containsKey(group) ? out : null;
1726        }
1727    }
1728
1729    public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
1730        // reader
1731        synchronized (mPackages) {
1732            return PackageParser.generatePermissionGroupInfo(
1733                    mPermissionGroups.get(name), flags);
1734        }
1735    }
1736
1737    public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
1738        // reader
1739        synchronized (mPackages) {
1740            final int N = mPermissionGroups.size();
1741            ArrayList<PermissionGroupInfo> out
1742                    = new ArrayList<PermissionGroupInfo>(N);
1743            for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
1744                out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
1745            }
1746            return out;
1747        }
1748    }
1749
1750    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
1751            int userId) {
1752        if (!sUserManager.exists(userId)) return null;
1753        PackageSetting ps = mSettings.mPackages.get(packageName);
1754        if (ps != null) {
1755            if (ps.pkg == null) {
1756                PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName,
1757                        flags, userId);
1758                if (pInfo != null) {
1759                    return pInfo.applicationInfo;
1760                }
1761                return null;
1762            }
1763            return PackageParser.generateApplicationInfo(ps.pkg, flags,
1764                    ps.readUserState(userId), userId);
1765        }
1766        return null;
1767    }
1768
1769    private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags,
1770            int userId) {
1771        if (!sUserManager.exists(userId)) return null;
1772        PackageSetting ps = mSettings.mPackages.get(packageName);
1773        if (ps != null) {
1774            PackageParser.Package pkg = ps.pkg;
1775            if (pkg == null) {
1776                if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) == 0) {
1777                    return null;
1778                }
1779                pkg = new PackageParser.Package(packageName);
1780                pkg.applicationInfo.packageName = packageName;
1781                pkg.applicationInfo.flags = ps.pkgFlags;
1782                pkg.applicationInfo.publicSourceDir = ps.resourcePathString;
1783                pkg.applicationInfo.sourceDir = ps.codePathString;
1784                pkg.applicationInfo.dataDir =
1785                        getDataPathForPackage(ps.pkg.packageName, 0).getPath();
1786                pkg.applicationInfo.nativeLibraryDir = ps.nativeLibraryPathString;
1787            }
1788            // pkg.mSetEnabled = ps.getEnabled(userId);
1789            // pkg.mSetStopped = ps.getStopped(userId);
1790            return generatePackageInfo(pkg, flags, userId);
1791        }
1792        return null;
1793    }
1794
1795    @Override
1796    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
1797        if (!sUserManager.exists(userId)) return null;
1798        // writer
1799        synchronized (mPackages) {
1800            PackageParser.Package p = mPackages.get(packageName);
1801            if (DEBUG_PACKAGE_INFO) Log.v(
1802                    TAG, "getApplicationInfo " + packageName
1803                    + ": " + p);
1804            if (p != null) {
1805                PackageSetting ps = mSettings.mPackages.get(packageName);
1806                if (ps == null) return null;
1807                // Note: isEnabledLP() does not apply here - always return info
1808                return PackageParser.generateApplicationInfo(p, flags, ps.readUserState(userId));
1809            }
1810            if ("android".equals(packageName)||"system".equals(packageName)) {
1811                return mAndroidApplication;
1812            }
1813            if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
1814                return generateApplicationInfoFromSettingsLPw(packageName, flags, userId);
1815            }
1816        }
1817        return null;
1818    }
1819
1820
1821    public void freeStorageAndNotify(final long freeStorageSize, final IPackageDataObserver observer) {
1822        mContext.enforceCallingOrSelfPermission(
1823                android.Manifest.permission.CLEAR_APP_CACHE, null);
1824        // Queue up an async operation since clearing cache may take a little while.
1825        mHandler.post(new Runnable() {
1826            public void run() {
1827                mHandler.removeCallbacks(this);
1828                int retCode = -1;
1829                synchronized (mInstallLock) {
1830                    retCode = mInstaller.freeCache(freeStorageSize);
1831                    if (retCode < 0) {
1832                        Slog.w(TAG, "Couldn't clear application caches");
1833                    }
1834                }
1835                if (observer != null) {
1836                    try {
1837                        observer.onRemoveCompleted(null, (retCode >= 0));
1838                    } catch (RemoteException e) {
1839                        Slog.w(TAG, "RemoveException when invoking call back");
1840                    }
1841                }
1842            }
1843        });
1844    }
1845
1846    public void freeStorage(final long freeStorageSize, final IntentSender pi) {
1847        mContext.enforceCallingOrSelfPermission(
1848                android.Manifest.permission.CLEAR_APP_CACHE, null);
1849        // Queue up an async operation since clearing cache may take a little while.
1850        mHandler.post(new Runnable() {
1851            public void run() {
1852                mHandler.removeCallbacks(this);
1853                int retCode = -1;
1854                synchronized (mInstallLock) {
1855                    retCode = mInstaller.freeCache(freeStorageSize);
1856                    if (retCode < 0) {
1857                        Slog.w(TAG, "Couldn't clear application caches");
1858                    }
1859                }
1860                if(pi != null) {
1861                    try {
1862                        // Callback via pending intent
1863                        int code = (retCode >= 0) ? 1 : 0;
1864                        pi.sendIntent(null, code, null,
1865                                null, null);
1866                    } catch (SendIntentException e1) {
1867                        Slog.i(TAG, "Failed to send pending intent");
1868                    }
1869                }
1870            }
1871        });
1872    }
1873
1874    @Override
1875    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
1876        if (!sUserManager.exists(userId)) return null;
1877        synchronized (mPackages) {
1878            PackageParser.Activity a = mActivities.mActivities.get(component);
1879
1880            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
1881            if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
1882                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
1883                if (ps == null) return null;
1884                return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
1885                        userId);
1886            }
1887            if (mResolveComponentName.equals(component)) {
1888                return mResolveActivity;
1889            }
1890        }
1891        return null;
1892    }
1893
1894    @Override
1895    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
1896        if (!sUserManager.exists(userId)) return null;
1897        synchronized (mPackages) {
1898            PackageParser.Activity a = mReceivers.mActivities.get(component);
1899            if (DEBUG_PACKAGE_INFO) Log.v(
1900                TAG, "getReceiverInfo " + component + ": " + a);
1901            if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
1902                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
1903                if (ps == null) return null;
1904                return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
1905                        userId);
1906            }
1907        }
1908        return null;
1909    }
1910
1911    @Override
1912    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
1913        if (!sUserManager.exists(userId)) return null;
1914        synchronized (mPackages) {
1915            PackageParser.Service s = mServices.mServices.get(component);
1916            if (DEBUG_PACKAGE_INFO) Log.v(
1917                TAG, "getServiceInfo " + component + ": " + s);
1918            if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) {
1919                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
1920                if (ps == null) return null;
1921                return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
1922                        userId);
1923            }
1924        }
1925        return null;
1926    }
1927
1928    @Override
1929    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
1930        if (!sUserManager.exists(userId)) return null;
1931        synchronized (mPackages) {
1932            PackageParser.Provider p = mProvidersByComponent.get(component);
1933            if (DEBUG_PACKAGE_INFO) Log.v(
1934                TAG, "getProviderInfo " + component + ": " + p);
1935            if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) {
1936                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
1937                if (ps == null) return null;
1938                return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
1939                        userId);
1940            }
1941        }
1942        return null;
1943    }
1944
1945    public String[] getSystemSharedLibraryNames() {
1946        Set<String> libSet;
1947        synchronized (mPackages) {
1948            libSet = mSharedLibraries.keySet();
1949            int size = libSet.size();
1950            if (size > 0) {
1951                String[] libs = new String[size];
1952                libSet.toArray(libs);
1953                return libs;
1954            }
1955        }
1956        return null;
1957    }
1958
1959    public FeatureInfo[] getSystemAvailableFeatures() {
1960        Collection<FeatureInfo> featSet;
1961        synchronized (mPackages) {
1962            featSet = mAvailableFeatures.values();
1963            int size = featSet.size();
1964            if (size > 0) {
1965                FeatureInfo[] features = new FeatureInfo[size+1];
1966                featSet.toArray(features);
1967                FeatureInfo fi = new FeatureInfo();
1968                fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
1969                        FeatureInfo.GL_ES_VERSION_UNDEFINED);
1970                features[size] = fi;
1971                return features;
1972            }
1973        }
1974        return null;
1975    }
1976
1977    public boolean hasSystemFeature(String name) {
1978        synchronized (mPackages) {
1979            return mAvailableFeatures.containsKey(name);
1980        }
1981    }
1982
1983    private void checkValidCaller(int uid, int userId) {
1984        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0)
1985            return;
1986
1987        throw new SecurityException("Caller uid=" + uid
1988                + " is not privileged to communicate with user=" + userId);
1989    }
1990
1991    public int checkPermission(String permName, String pkgName) {
1992        synchronized (mPackages) {
1993            PackageParser.Package p = mPackages.get(pkgName);
1994            if (p != null && p.mExtras != null) {
1995                PackageSetting ps = (PackageSetting)p.mExtras;
1996                if (ps.sharedUser != null) {
1997                    if (ps.sharedUser.grantedPermissions.contains(permName)) {
1998                        return PackageManager.PERMISSION_GRANTED;
1999                    }
2000                } else if (ps.grantedPermissions.contains(permName)) {
2001                    return PackageManager.PERMISSION_GRANTED;
2002                }
2003            }
2004            if (!isPermissionEnforcedLocked(permName)) {
2005                return PackageManager.PERMISSION_GRANTED;
2006            }
2007        }
2008        return PackageManager.PERMISSION_DENIED;
2009    }
2010
2011    public int checkUidPermission(String permName, int uid) {
2012        synchronized (mPackages) {
2013            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2014            if (obj != null) {
2015                GrantedPermissions gp = (GrantedPermissions)obj;
2016                if (gp.grantedPermissions.contains(permName)) {
2017                    return PackageManager.PERMISSION_GRANTED;
2018                }
2019            } else {
2020                HashSet<String> perms = mSystemPermissions.get(uid);
2021                if (perms != null && perms.contains(permName)) {
2022                    return PackageManager.PERMISSION_GRANTED;
2023                }
2024            }
2025            if (!isPermissionEnforcedLocked(permName)) {
2026                return PackageManager.PERMISSION_GRANTED;
2027            }
2028        }
2029        return PackageManager.PERMISSION_DENIED;
2030    }
2031
2032    private BasePermission findPermissionTreeLP(String permName) {
2033        for(BasePermission bp : mSettings.mPermissionTrees.values()) {
2034            if (permName.startsWith(bp.name) &&
2035                    permName.length() > bp.name.length() &&
2036                    permName.charAt(bp.name.length()) == '.') {
2037                return bp;
2038            }
2039        }
2040        return null;
2041    }
2042
2043    private BasePermission checkPermissionTreeLP(String permName) {
2044        if (permName != null) {
2045            BasePermission bp = findPermissionTreeLP(permName);
2046            if (bp != null) {
2047                if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
2048                    return bp;
2049                }
2050                throw new SecurityException("Calling uid "
2051                        + Binder.getCallingUid()
2052                        + " is not allowed to add to permission tree "
2053                        + bp.name + " owned by uid " + bp.uid);
2054            }
2055        }
2056        throw new SecurityException("No permission tree found for " + permName);
2057    }
2058
2059    static boolean compareStrings(CharSequence s1, CharSequence s2) {
2060        if (s1 == null) {
2061            return s2 == null;
2062        }
2063        if (s2 == null) {
2064            return false;
2065        }
2066        if (s1.getClass() != s2.getClass()) {
2067            return false;
2068        }
2069        return s1.equals(s2);
2070    }
2071
2072    static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
2073        if (pi1.icon != pi2.icon) return false;
2074        if (pi1.logo != pi2.logo) return false;
2075        if (pi1.protectionLevel != pi2.protectionLevel) return false;
2076        if (!compareStrings(pi1.name, pi2.name)) return false;
2077        if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
2078        // We'll take care of setting this one.
2079        if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
2080        // These are not currently stored in settings.
2081        //if (!compareStrings(pi1.group, pi2.group)) return false;
2082        //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
2083        //if (pi1.labelRes != pi2.labelRes) return false;
2084        //if (pi1.descriptionRes != pi2.descriptionRes) return false;
2085        return true;
2086    }
2087
2088    boolean addPermissionLocked(PermissionInfo info, boolean async) {
2089        if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
2090            throw new SecurityException("Label must be specified in permission");
2091        }
2092        BasePermission tree = checkPermissionTreeLP(info.name);
2093        BasePermission bp = mSettings.mPermissions.get(info.name);
2094        boolean added = bp == null;
2095        boolean changed = true;
2096        int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
2097        if (added) {
2098            bp = new BasePermission(info.name, tree.sourcePackage,
2099                    BasePermission.TYPE_DYNAMIC);
2100        } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
2101            throw new SecurityException(
2102                    "Not allowed to modify non-dynamic permission "
2103                    + info.name);
2104        } else {
2105            if (bp.protectionLevel == fixedLevel
2106                    && bp.perm.owner.equals(tree.perm.owner)
2107                    && bp.uid == tree.uid
2108                    && comparePermissionInfos(bp.perm.info, info)) {
2109                changed = false;
2110            }
2111        }
2112        bp.protectionLevel = fixedLevel;
2113        info = new PermissionInfo(info);
2114        info.protectionLevel = fixedLevel;
2115        bp.perm = new PackageParser.Permission(tree.perm.owner, info);
2116        bp.perm.info.packageName = tree.perm.info.packageName;
2117        bp.uid = tree.uid;
2118        if (added) {
2119            mSettings.mPermissions.put(info.name, bp);
2120        }
2121        if (changed) {
2122            if (!async) {
2123                mSettings.writeLPr();
2124            } else {
2125                scheduleWriteSettingsLocked();
2126            }
2127        }
2128        return added;
2129    }
2130
2131    public boolean addPermission(PermissionInfo info) {
2132        synchronized (mPackages) {
2133            return addPermissionLocked(info, false);
2134        }
2135    }
2136
2137    public boolean addPermissionAsync(PermissionInfo info) {
2138        synchronized (mPackages) {
2139            return addPermissionLocked(info, true);
2140        }
2141    }
2142
2143    public void removePermission(String name) {
2144        synchronized (mPackages) {
2145            checkPermissionTreeLP(name);
2146            BasePermission bp = mSettings.mPermissions.get(name);
2147            if (bp != null) {
2148                if (bp.type != BasePermission.TYPE_DYNAMIC) {
2149                    throw new SecurityException(
2150                            "Not allowed to modify non-dynamic permission "
2151                            + name);
2152                }
2153                mSettings.mPermissions.remove(name);
2154                mSettings.writeLPr();
2155            }
2156        }
2157    }
2158
2159    public void grantPermission(String packageName, String permissionName) {
2160        mContext.enforceCallingOrSelfPermission(
2161                android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
2162        synchronized (mPackages) {
2163            final PackageParser.Package pkg = mPackages.get(packageName);
2164            if (pkg == null) {
2165                throw new IllegalArgumentException("Unknown package: " + packageName);
2166            }
2167            final BasePermission bp = mSettings.mPermissions.get(permissionName);
2168            if (bp == null) {
2169                throw new IllegalArgumentException("Unknown permission: " + packageName);
2170            }
2171            if (!pkg.requestedPermissions.contains(permissionName)) {
2172                throw new SecurityException("Package " + packageName
2173                        + " has not requested permission " + permissionName);
2174            }
2175            if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) == 0) {
2176                throw new SecurityException("Permission " + permissionName
2177                        + " is not a development permission");
2178            }
2179            final PackageSetting ps = (PackageSetting) pkg.mExtras;
2180            if (ps == null) {
2181                return;
2182            }
2183            final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
2184            if (gp.grantedPermissions.add(permissionName)) {
2185                if (ps.haveGids) {
2186                    gp.gids = appendInts(gp.gids, bp.gids);
2187                }
2188                mSettings.writeLPr();
2189            }
2190        }
2191    }
2192
2193    public void revokePermission(String packageName, String permissionName) {
2194        synchronized (mPackages) {
2195            final PackageParser.Package pkg = mPackages.get(packageName);
2196            if (pkg == null) {
2197                throw new IllegalArgumentException("Unknown package: " + packageName);
2198            }
2199            if (pkg.applicationInfo.uid != Binder.getCallingUid()) {
2200                mContext.enforceCallingOrSelfPermission(
2201                        android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
2202            }
2203            final BasePermission bp = mSettings.mPermissions.get(permissionName);
2204            if (bp == null) {
2205                throw new IllegalArgumentException("Unknown permission: " + packageName);
2206            }
2207            if (!pkg.requestedPermissions.contains(permissionName)) {
2208                throw new SecurityException("Package " + packageName
2209                        + " has not requested permission " + permissionName);
2210            }
2211            if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) == 0) {
2212                throw new SecurityException("Permission " + permissionName
2213                        + " is not a development permission");
2214            }
2215            final PackageSetting ps = (PackageSetting) pkg.mExtras;
2216            if (ps == null) {
2217                return;
2218            }
2219            final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
2220            if (gp.grantedPermissions.remove(permissionName)) {
2221                gp.grantedPermissions.remove(permissionName);
2222                if (ps.haveGids) {
2223                    gp.gids = removeInts(gp.gids, bp.gids);
2224                }
2225                mSettings.writeLPr();
2226            }
2227        }
2228    }
2229
2230    public boolean isProtectedBroadcast(String actionName) {
2231        synchronized (mPackages) {
2232            return mProtectedBroadcasts.contains(actionName);
2233        }
2234    }
2235
2236    public int checkSignatures(String pkg1, String pkg2) {
2237        synchronized (mPackages) {
2238            final PackageParser.Package p1 = mPackages.get(pkg1);
2239            final PackageParser.Package p2 = mPackages.get(pkg2);
2240            if (p1 == null || p1.mExtras == null
2241                    || p2 == null || p2.mExtras == null) {
2242                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2243            }
2244            return compareSignatures(p1.mSignatures, p2.mSignatures);
2245        }
2246    }
2247
2248    public int checkUidSignatures(int uid1, int uid2) {
2249        // Map to base uids.
2250        uid1 = UserHandle.getAppId(uid1);
2251        uid2 = UserHandle.getAppId(uid2);
2252        // reader
2253        synchronized (mPackages) {
2254            Signature[] s1;
2255            Signature[] s2;
2256            Object obj = mSettings.getUserIdLPr(uid1);
2257            if (obj != null) {
2258                if (obj instanceof SharedUserSetting) {
2259                    s1 = ((SharedUserSetting)obj).signatures.mSignatures;
2260                } else if (obj instanceof PackageSetting) {
2261                    s1 = ((PackageSetting)obj).signatures.mSignatures;
2262                } else {
2263                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2264                }
2265            } else {
2266                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2267            }
2268            obj = mSettings.getUserIdLPr(uid2);
2269            if (obj != null) {
2270                if (obj instanceof SharedUserSetting) {
2271                    s2 = ((SharedUserSetting)obj).signatures.mSignatures;
2272                } else if (obj instanceof PackageSetting) {
2273                    s2 = ((PackageSetting)obj).signatures.mSignatures;
2274                } else {
2275                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2276                }
2277            } else {
2278                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2279            }
2280            return compareSignatures(s1, s2);
2281        }
2282    }
2283
2284    static int compareSignatures(Signature[] s1, Signature[] s2) {
2285        if (s1 == null) {
2286            return s2 == null
2287                    ? PackageManager.SIGNATURE_NEITHER_SIGNED
2288                    : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
2289        }
2290        if (s2 == null) {
2291            return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
2292        }
2293        HashSet<Signature> set1 = new HashSet<Signature>();
2294        for (Signature sig : s1) {
2295            set1.add(sig);
2296        }
2297        HashSet<Signature> set2 = new HashSet<Signature>();
2298        for (Signature sig : s2) {
2299            set2.add(sig);
2300        }
2301        // Make sure s2 contains all signatures in s1.
2302        if (set1.equals(set2)) {
2303            return PackageManager.SIGNATURE_MATCH;
2304        }
2305        return PackageManager.SIGNATURE_NO_MATCH;
2306    }
2307
2308    public String[] getPackagesForUid(int uid) {
2309        uid = UserHandle.getAppId(uid);
2310        // reader
2311        synchronized (mPackages) {
2312            Object obj = mSettings.getUserIdLPr(uid);
2313            if (obj instanceof SharedUserSetting) {
2314                final SharedUserSetting sus = (SharedUserSetting) obj;
2315                final int N = sus.packages.size();
2316                final String[] res = new String[N];
2317                final Iterator<PackageSetting> it = sus.packages.iterator();
2318                int i = 0;
2319                while (it.hasNext()) {
2320                    res[i++] = it.next().name;
2321                }
2322                return res;
2323            } else if (obj instanceof PackageSetting) {
2324                final PackageSetting ps = (PackageSetting) obj;
2325                return new String[] { ps.name };
2326            }
2327        }
2328        return null;
2329    }
2330
2331    public String getNameForUid(int uid) {
2332        // reader
2333        synchronized (mPackages) {
2334            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2335            if (obj instanceof SharedUserSetting) {
2336                final SharedUserSetting sus = (SharedUserSetting) obj;
2337                return sus.name + ":" + sus.userId;
2338            } else if (obj instanceof PackageSetting) {
2339                final PackageSetting ps = (PackageSetting) obj;
2340                return ps.name;
2341            }
2342        }
2343        return null;
2344    }
2345
2346    public int getUidForSharedUser(String sharedUserName) {
2347        if(sharedUserName == null) {
2348            return -1;
2349        }
2350        // reader
2351        synchronized (mPackages) {
2352            final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, false);
2353            if (suid == null) {
2354                return -1;
2355            }
2356            return suid.userId;
2357        }
2358    }
2359
2360    @Override
2361    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
2362            int flags, int userId) {
2363        if (!sUserManager.exists(userId)) return null;
2364        List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
2365        return chooseBestActivity(intent, resolvedType, flags, query, userId);
2366    }
2367
2368    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
2369            int flags, List<ResolveInfo> query, int userId) {
2370        if (query != null) {
2371            final int N = query.size();
2372            if (N == 1) {
2373                return query.get(0);
2374            } else if (N > 1) {
2375                // If there is more than one activity with the same priority,
2376                // then let the user decide between them.
2377                ResolveInfo r0 = query.get(0);
2378                ResolveInfo r1 = query.get(1);
2379                if (DEBUG_INTENT_MATCHING) {
2380                    Log.d(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
2381                            + r1.activityInfo.name + "=" + r1.priority);
2382                }
2383                // If the first activity has a higher priority, or a different
2384                // default, then it is always desireable to pick it.
2385                if (r0.priority != r1.priority
2386                        || r0.preferredOrder != r1.preferredOrder
2387                        || r0.isDefault != r1.isDefault) {
2388                    return query.get(0);
2389                }
2390                // If we have saved a preference for a preferred activity for
2391                // this Intent, use that.
2392                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
2393                        flags, query, r0.priority, userId);
2394                if (ri != null) {
2395                    return ri;
2396                }
2397                return mResolveInfo;
2398            }
2399        }
2400        return null;
2401    }
2402
2403    ResolveInfo findPreferredActivity(Intent intent, String resolvedType,
2404            int flags, List<ResolveInfo> query, int priority, int userId) {
2405        if (!sUserManager.exists(userId)) return null;
2406        // writer
2407        synchronized (mPackages) {
2408            if (intent.getSelector() != null) {
2409                intent = intent.getSelector();
2410            }
2411            if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
2412            List<PreferredActivity> prefs =
2413                    mSettings.mPreferredActivities.queryIntent(intent, resolvedType,
2414                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
2415            if (prefs != null && prefs.size() > 0) {
2416                // First figure out how good the original match set is.
2417                // We will only allow preferred activities that came
2418                // from the same match quality.
2419                int match = 0;
2420
2421                if (DEBUG_PREFERRED) {
2422                    Log.v(TAG, "Figuring out best match...");
2423                }
2424
2425                final int N = query.size();
2426                for (int j=0; j<N; j++) {
2427                    final ResolveInfo ri = query.get(j);
2428                    if (DEBUG_PREFERRED) {
2429                        Log.v(TAG, "Match for " + ri.activityInfo + ": 0x"
2430                                + Integer.toHexString(match));
2431                    }
2432                    if (ri.match > match) {
2433                        match = ri.match;
2434                    }
2435                }
2436
2437                if (DEBUG_PREFERRED) {
2438                    Log.v(TAG, "Best match: 0x" + Integer.toHexString(match));
2439                }
2440
2441                match &= IntentFilter.MATCH_CATEGORY_MASK;
2442                final int M = prefs.size();
2443                for (int i=0; i<M; i++) {
2444                    final PreferredActivity pa = prefs.get(i);
2445                    if (pa.mUserId != userId) {
2446                        continue;
2447                    }
2448                    if (pa.mPref.mMatch != match) {
2449                        continue;
2450                    }
2451                    final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent, flags, userId);
2452                    if (DEBUG_PREFERRED) {
2453                        Log.v(TAG, "Got preferred activity:");
2454                        if (ai != null) {
2455                            ai.dump(new LogPrinter(Log.VERBOSE, TAG), "  ");
2456                        } else {
2457                            Log.v(TAG, "  null");
2458                        }
2459                    }
2460                    if (ai == null) {
2461                        // This previously registered preferred activity
2462                        // component is no longer known.  Most likely an update
2463                        // to the app was installed and in the new version this
2464                        // component no longer exists.  Clean it up by removing
2465                        // it from the preferred activities list, and skip it.
2466                        Slog.w(TAG, "Removing dangling preferred activity: "
2467                                + pa.mPref.mComponent);
2468                        mSettings.mPreferredActivities.removeFilter(pa);
2469                        continue;
2470                    }
2471                    for (int j=0; j<N; j++) {
2472                        final ResolveInfo ri = query.get(j);
2473                        if (!ri.activityInfo.applicationInfo.packageName
2474                                .equals(ai.applicationInfo.packageName)) {
2475                            continue;
2476                        }
2477                        if (!ri.activityInfo.name.equals(ai.name)) {
2478                            continue;
2479                        }
2480
2481                        // Okay we found a previously set preferred app.
2482                        // If the result set is different from when this
2483                        // was created, we need to clear it and re-ask the
2484                        // user their preference.
2485                        if (!pa.mPref.sameSet(query, priority)) {
2486                            Slog.i(TAG, "Result set changed, dropping preferred activity for "
2487                                    + intent + " type " + resolvedType);
2488                            mSettings.mPreferredActivities.removeFilter(pa);
2489                            return null;
2490                        }
2491
2492                        // Yay!
2493                        return ri;
2494                    }
2495                }
2496            }
2497        }
2498        return null;
2499    }
2500
2501    @Override
2502    public List<ResolveInfo> queryIntentActivities(Intent intent,
2503            String resolvedType, int flags, int userId) {
2504        if (!sUserManager.exists(userId)) return null;
2505        ComponentName comp = intent.getComponent();
2506        if (comp == null) {
2507            if (intent.getSelector() != null) {
2508                intent = intent.getSelector();
2509                comp = intent.getComponent();
2510            }
2511        }
2512
2513        if (comp != null) {
2514            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
2515            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
2516            if (ai != null) {
2517                final ResolveInfo ri = new ResolveInfo();
2518                ri.activityInfo = ai;
2519                list.add(ri);
2520            }
2521            return list;
2522        }
2523
2524        // reader
2525        synchronized (mPackages) {
2526            final String pkgName = intent.getPackage();
2527            if (pkgName == null) {
2528                return mActivities.queryIntent(intent, resolvedType, flags, userId);
2529            }
2530            final PackageParser.Package pkg = mPackages.get(pkgName);
2531            if (pkg != null) {
2532                return mActivities.queryIntentForPackage(intent, resolvedType, flags,
2533                        pkg.activities, userId);
2534            }
2535            return new ArrayList<ResolveInfo>();
2536        }
2537    }
2538
2539    @Override
2540    public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
2541            Intent[] specifics, String[] specificTypes, Intent intent,
2542            String resolvedType, int flags, int userId) {
2543        if (!sUserManager.exists(userId)) return null;
2544        final String resultsAction = intent.getAction();
2545
2546        List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags
2547                | PackageManager.GET_RESOLVED_FILTER, userId);
2548
2549        if (DEBUG_INTENT_MATCHING) {
2550            Log.v(TAG, "Query " + intent + ": " + results);
2551        }
2552
2553        int specificsPos = 0;
2554        int N;
2555
2556        // todo: note that the algorithm used here is O(N^2).  This
2557        // isn't a problem in our current environment, but if we start running
2558        // into situations where we have more than 5 or 10 matches then this
2559        // should probably be changed to something smarter...
2560
2561        // First we go through and resolve each of the specific items
2562        // that were supplied, taking care of removing any corresponding
2563        // duplicate items in the generic resolve list.
2564        if (specifics != null) {
2565            for (int i=0; i<specifics.length; i++) {
2566                final Intent sintent = specifics[i];
2567                if (sintent == null) {
2568                    continue;
2569                }
2570
2571                if (DEBUG_INTENT_MATCHING) {
2572                    Log.v(TAG, "Specific #" + i + ": " + sintent);
2573                }
2574
2575                String action = sintent.getAction();
2576                if (resultsAction != null && resultsAction.equals(action)) {
2577                    // If this action was explicitly requested, then don't
2578                    // remove things that have it.
2579                    action = null;
2580                }
2581
2582                ResolveInfo ri = null;
2583                ActivityInfo ai = null;
2584
2585                ComponentName comp = sintent.getComponent();
2586                if (comp == null) {
2587                    ri = resolveIntent(
2588                        sintent,
2589                        specificTypes != null ? specificTypes[i] : null,
2590                            flags, userId);
2591                    if (ri == null) {
2592                        continue;
2593                    }
2594                    if (ri == mResolveInfo) {
2595                        // ACK!  Must do something better with this.
2596                    }
2597                    ai = ri.activityInfo;
2598                    comp = new ComponentName(ai.applicationInfo.packageName,
2599                            ai.name);
2600                } else {
2601                    ai = getActivityInfo(comp, flags, userId);
2602                    if (ai == null) {
2603                        continue;
2604                    }
2605                }
2606
2607                // Look for any generic query activities that are duplicates
2608                // of this specific one, and remove them from the results.
2609                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
2610                N = results.size();
2611                int j;
2612                for (j=specificsPos; j<N; j++) {
2613                    ResolveInfo sri = results.get(j);
2614                    if ((sri.activityInfo.name.equals(comp.getClassName())
2615                            && sri.activityInfo.applicationInfo.packageName.equals(
2616                                    comp.getPackageName()))
2617                        || (action != null && sri.filter.matchAction(action))) {
2618                        results.remove(j);
2619                        if (DEBUG_INTENT_MATCHING) Log.v(
2620                            TAG, "Removing duplicate item from " + j
2621                            + " due to specific " + specificsPos);
2622                        if (ri == null) {
2623                            ri = sri;
2624                        }
2625                        j--;
2626                        N--;
2627                    }
2628                }
2629
2630                // Add this specific item to its proper place.
2631                if (ri == null) {
2632                    ri = new ResolveInfo();
2633                    ri.activityInfo = ai;
2634                }
2635                results.add(specificsPos, ri);
2636                ri.specificIndex = i;
2637                specificsPos++;
2638            }
2639        }
2640
2641        // Now we go through the remaining generic results and remove any
2642        // duplicate actions that are found here.
2643        N = results.size();
2644        for (int i=specificsPos; i<N-1; i++) {
2645            final ResolveInfo rii = results.get(i);
2646            if (rii.filter == null) {
2647                continue;
2648            }
2649
2650            // Iterate over all of the actions of this result's intent
2651            // filter...  typically this should be just one.
2652            final Iterator<String> it = rii.filter.actionsIterator();
2653            if (it == null) {
2654                continue;
2655            }
2656            while (it.hasNext()) {
2657                final String action = it.next();
2658                if (resultsAction != null && resultsAction.equals(action)) {
2659                    // If this action was explicitly requested, then don't
2660                    // remove things that have it.
2661                    continue;
2662                }
2663                for (int j=i+1; j<N; j++) {
2664                    final ResolveInfo rij = results.get(j);
2665                    if (rij.filter != null && rij.filter.hasAction(action)) {
2666                        results.remove(j);
2667                        if (DEBUG_INTENT_MATCHING) Log.v(
2668                            TAG, "Removing duplicate item from " + j
2669                            + " due to action " + action + " at " + i);
2670                        j--;
2671                        N--;
2672                    }
2673                }
2674            }
2675
2676            // If the caller didn't request filter information, drop it now
2677            // so we don't have to marshall/unmarshall it.
2678            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
2679                rii.filter = null;
2680            }
2681        }
2682
2683        // Filter out the caller activity if so requested.
2684        if (caller != null) {
2685            N = results.size();
2686            for (int i=0; i<N; i++) {
2687                ActivityInfo ainfo = results.get(i).activityInfo;
2688                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
2689                        && caller.getClassName().equals(ainfo.name)) {
2690                    results.remove(i);
2691                    break;
2692                }
2693            }
2694        }
2695
2696        // If the caller didn't request filter information,
2697        // drop them now so we don't have to
2698        // marshall/unmarshall it.
2699        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
2700            N = results.size();
2701            for (int i=0; i<N; i++) {
2702                results.get(i).filter = null;
2703            }
2704        }
2705
2706        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
2707        return results;
2708    }
2709
2710    @Override
2711    public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags,
2712            int userId) {
2713        if (!sUserManager.exists(userId)) return null;
2714        ComponentName comp = intent.getComponent();
2715        if (comp == null) {
2716            if (intent.getSelector() != null) {
2717                intent = intent.getSelector();
2718                comp = intent.getComponent();
2719            }
2720        }
2721        if (comp != null) {
2722            List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
2723            ActivityInfo ai = getReceiverInfo(comp, flags, userId);
2724            if (ai != null) {
2725                ResolveInfo ri = new ResolveInfo();
2726                ri.activityInfo = ai;
2727                list.add(ri);
2728            }
2729            return list;
2730        }
2731
2732        // reader
2733        synchronized (mPackages) {
2734            String pkgName = intent.getPackage();
2735            if (pkgName == null) {
2736                return mReceivers.queryIntent(intent, resolvedType, flags, userId);
2737            }
2738            final PackageParser.Package pkg = mPackages.get(pkgName);
2739            if (pkg != null) {
2740                return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
2741                        userId);
2742            }
2743            return null;
2744        }
2745    }
2746
2747    @Override
2748    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
2749        List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId);
2750        if (!sUserManager.exists(userId)) return null;
2751        if (query != null) {
2752            if (query.size() >= 1) {
2753                // If there is more than one service with the same priority,
2754                // just arbitrarily pick the first one.
2755                return query.get(0);
2756            }
2757        }
2758        return null;
2759    }
2760
2761    @Override
2762    public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags,
2763            int userId) {
2764        if (!sUserManager.exists(userId)) return null;
2765        ComponentName comp = intent.getComponent();
2766        if (comp == null) {
2767            if (intent.getSelector() != null) {
2768                intent = intent.getSelector();
2769                comp = intent.getComponent();
2770            }
2771        }
2772        if (comp != null) {
2773            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
2774            final ServiceInfo si = getServiceInfo(comp, flags, userId);
2775            if (si != null) {
2776                final ResolveInfo ri = new ResolveInfo();
2777                ri.serviceInfo = si;
2778                list.add(ri);
2779            }
2780            return list;
2781        }
2782
2783        // reader
2784        synchronized (mPackages) {
2785            String pkgName = intent.getPackage();
2786            if (pkgName == null) {
2787                return mServices.queryIntent(intent, resolvedType, flags, userId);
2788            }
2789            final PackageParser.Package pkg = mPackages.get(pkgName);
2790            if (pkg != null) {
2791                return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
2792                        userId);
2793            }
2794            return null;
2795        }
2796    }
2797
2798    private static final int getContinuationPoint(final String[] keys, final String key) {
2799        final int index;
2800        if (key == null) {
2801            index = 0;
2802        } else {
2803            final int insertPoint = Arrays.binarySearch(keys, key);
2804            if (insertPoint < 0) {
2805                index = -insertPoint;
2806            } else {
2807                index = insertPoint + 1;
2808            }
2809        }
2810        return index;
2811    }
2812
2813    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, String lastRead) {
2814        final ParceledListSlice<PackageInfo> list = new ParceledListSlice<PackageInfo>();
2815        final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
2816        final String[] keys;
2817        int userId = UserHandle.getCallingUserId();
2818
2819        // writer
2820        synchronized (mPackages) {
2821            if (listUninstalled) {
2822                keys = mSettings.mPackages.keySet().toArray(new String[mSettings.mPackages.size()]);
2823            } else {
2824                keys = mPackages.keySet().toArray(new String[mPackages.size()]);
2825            }
2826
2827            Arrays.sort(keys);
2828            int i = getContinuationPoint(keys, lastRead);
2829            final int N = keys.length;
2830
2831            while (i < N) {
2832                final String packageName = keys[i++];
2833
2834                PackageInfo pi = null;
2835                if (listUninstalled) {
2836                    final PackageSetting ps = mSettings.mPackages.get(packageName);
2837                    if (ps != null) {
2838                        pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
2839                    }
2840                } else {
2841                    final PackageParser.Package p = mPackages.get(packageName);
2842                    if (p != null) {
2843                        pi = generatePackageInfo(p, flags, userId);
2844                    }
2845                }
2846
2847                if (pi != null && list.append(pi)) {
2848                    break;
2849                }
2850            }
2851
2852            if (i == N) {
2853                list.setLastSlice(true);
2854            }
2855        }
2856
2857        return list;
2858    }
2859
2860    @Override
2861    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags,
2862            String lastRead, int userId) {
2863        if (!sUserManager.exists(userId)) return null;
2864        final ParceledListSlice<ApplicationInfo> list = new ParceledListSlice<ApplicationInfo>();
2865        final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
2866        final String[] keys;
2867
2868        // writer
2869        synchronized (mPackages) {
2870            if (listUninstalled) {
2871                keys = mSettings.mPackages.keySet().toArray(new String[mSettings.mPackages.size()]);
2872            } else {
2873                keys = mPackages.keySet().toArray(new String[mPackages.size()]);
2874            }
2875
2876            Arrays.sort(keys);
2877            int i = getContinuationPoint(keys, lastRead);
2878            final int N = keys.length;
2879
2880            while (i < N) {
2881                final String packageName = keys[i++];
2882
2883                ApplicationInfo ai = null;
2884                final PackageSetting ps = mSettings.mPackages.get(packageName);
2885                if (listUninstalled) {
2886                    if (ps != null) {
2887                        ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
2888                    }
2889                } else {
2890                    final PackageParser.Package p = mPackages.get(packageName);
2891                    if (p != null && ps != null) {
2892                        ai = PackageParser.generateApplicationInfo(p, flags,
2893                                ps.readUserState(userId), userId);
2894                    }
2895                }
2896
2897                if (ai != null && list.append(ai)) {
2898                    break;
2899                }
2900            }
2901
2902            if (i == N) {
2903                list.setLastSlice(true);
2904            }
2905        }
2906
2907        return list;
2908    }
2909
2910    public List<ApplicationInfo> getPersistentApplications(int flags) {
2911        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
2912
2913        // reader
2914        synchronized (mPackages) {
2915            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
2916            final int userId = UserHandle.getCallingUserId();
2917            while (i.hasNext()) {
2918                final PackageParser.Package p = i.next();
2919                if (p.applicationInfo != null
2920                        && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0
2921                        && (!mSafeMode || isSystemApp(p))) {
2922                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
2923                    if (ps != null) {
2924                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
2925                                ps.readUserState(userId), userId);
2926                        if (ai != null) {
2927                            finalList.add(ai);
2928                        }
2929                    }
2930                }
2931            }
2932        }
2933
2934        return finalList;
2935    }
2936
2937    @Override
2938    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
2939        if (!sUserManager.exists(userId)) return null;
2940        // reader
2941        synchronized (mPackages) {
2942            final PackageParser.Provider provider = mProviders.get(name);
2943            PackageSetting ps = provider != null
2944                    ? mSettings.mPackages.get(provider.owner.packageName)
2945                    : null;
2946            return ps != null
2947                    && mSettings.isEnabledLPr(provider.info, flags, userId)
2948                    && (!mSafeMode || (provider.info.applicationInfo.flags
2949                            &ApplicationInfo.FLAG_SYSTEM) != 0)
2950                    ? PackageParser.generateProviderInfo(provider, flags,
2951                            ps.readUserState(userId), userId)
2952                    : null;
2953        }
2954    }
2955
2956    /**
2957     * @deprecated
2958     */
2959    @Deprecated
2960    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
2961        // reader
2962        synchronized (mPackages) {
2963            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProviders.entrySet()
2964                    .iterator();
2965            final int userId = UserHandle.getCallingUserId();
2966            while (i.hasNext()) {
2967                Map.Entry<String, PackageParser.Provider> entry = i.next();
2968                PackageParser.Provider p = entry.getValue();
2969                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
2970
2971                if (ps != null && p.syncable
2972                        && (!mSafeMode || (p.info.applicationInfo.flags
2973                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
2974                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
2975                            ps.readUserState(userId), userId);
2976                    if (info != null) {
2977                        outNames.add(entry.getKey());
2978                        outInfo.add(info);
2979                    }
2980                }
2981            }
2982        }
2983    }
2984
2985    public List<ProviderInfo> queryContentProviders(String processName,
2986            int uid, int flags) {
2987        ArrayList<ProviderInfo> finalList = null;
2988
2989        // reader
2990        synchronized (mPackages) {
2991            final Iterator<PackageParser.Provider> i = mProvidersByComponent.values().iterator();
2992            final int userId = processName != null ?
2993                    UserHandle.getUserId(uid) : UserHandle.getCallingUserId();
2994            while (i.hasNext()) {
2995                final PackageParser.Provider p = i.next();
2996                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
2997                if (ps != null && p.info.authority != null
2998                        && (processName == null
2999                                || (p.info.processName.equals(processName)
3000                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
3001                        && mSettings.isEnabledLPr(p.info, flags, userId)
3002                        && (!mSafeMode
3003                                || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
3004                    if (finalList == null) {
3005                        finalList = new ArrayList<ProviderInfo>(3);
3006                    }
3007                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
3008                            ps.readUserState(userId), userId);
3009                    if (info != null) {
3010                        finalList.add(info);
3011                    }
3012                }
3013            }
3014        }
3015
3016        if (finalList != null) {
3017            Collections.sort(finalList, mProviderInitOrderSorter);
3018        }
3019
3020        return finalList;
3021    }
3022
3023    public InstrumentationInfo getInstrumentationInfo(ComponentName name,
3024            int flags) {
3025        // reader
3026        synchronized (mPackages) {
3027            final PackageParser.Instrumentation i = mInstrumentation.get(name);
3028            return PackageParser.generateInstrumentationInfo(i, flags);
3029        }
3030    }
3031
3032    public List<InstrumentationInfo> queryInstrumentation(String targetPackage,
3033            int flags) {
3034        ArrayList<InstrumentationInfo> finalList =
3035            new ArrayList<InstrumentationInfo>();
3036
3037        // reader
3038        synchronized (mPackages) {
3039            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
3040            while (i.hasNext()) {
3041                final PackageParser.Instrumentation p = i.next();
3042                if (targetPackage == null
3043                        || targetPackage.equals(p.info.targetPackage)) {
3044                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
3045                            flags);
3046                    if (ii != null) {
3047                        finalList.add(ii);
3048                    }
3049                }
3050            }
3051        }
3052
3053        return finalList;
3054    }
3055
3056    private void scanDirLI(File dir, int flags, int scanMode, long currentTime) {
3057        String[] files = dir.list();
3058        if (files == null) {
3059            Log.d(TAG, "No files in app dir " + dir);
3060            return;
3061        }
3062
3063        if (DEBUG_PACKAGE_SCANNING) {
3064            Log.d(TAG, "Scanning app dir " + dir);
3065        }
3066
3067        int i;
3068        for (i=0; i<files.length; i++) {
3069            File file = new File(dir, files[i]);
3070            if (!isPackageFilename(files[i])) {
3071                // Ignore entries which are not apk's
3072                continue;
3073            }
3074            PackageParser.Package pkg = scanPackageLI(file,
3075                    flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime, null);
3076            // Don't mess around with apps in system partition.
3077            if (pkg == null && (flags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
3078                    mLastScanError == PackageManager.INSTALL_FAILED_INVALID_APK) {
3079                // Delete the apk
3080                Slog.w(TAG, "Cleaning up failed install of " + file);
3081                file.delete();
3082            }
3083        }
3084    }
3085
3086    private static File getSettingsProblemFile() {
3087        File dataDir = Environment.getDataDirectory();
3088        File systemDir = new File(dataDir, "system");
3089        File fname = new File(systemDir, "uiderrors.txt");
3090        return fname;
3091    }
3092
3093    static void reportSettingsProblem(int priority, String msg) {
3094        try {
3095            File fname = getSettingsProblemFile();
3096            FileOutputStream out = new FileOutputStream(fname, true);
3097            PrintWriter pw = new PrintWriter(out);
3098            SimpleDateFormat formatter = new SimpleDateFormat();
3099            String dateString = formatter.format(new Date(System.currentTimeMillis()));
3100            pw.println(dateString + ": " + msg);
3101            pw.close();
3102            FileUtils.setPermissions(
3103                    fname.toString(),
3104                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
3105                    -1, -1);
3106        } catch (java.io.IOException e) {
3107        }
3108        Slog.println(priority, TAG, msg);
3109    }
3110
3111    private boolean collectCertificatesLI(PackageParser pp, PackageSetting ps,
3112            PackageParser.Package pkg, File srcFile, int parseFlags) {
3113        if (GET_CERTIFICATES) {
3114            if (ps != null
3115                    && ps.codePath.equals(srcFile)
3116                    && ps.timeStamp == srcFile.lastModified()) {
3117                if (ps.signatures.mSignatures != null
3118                        && ps.signatures.mSignatures.length != 0) {
3119                    // Optimization: reuse the existing cached certificates
3120                    // if the package appears to be unchanged.
3121                    pkg.mSignatures = ps.signatures.mSignatures;
3122                    return true;
3123                }
3124
3125                Slog.w(TAG, "PackageSetting for " + ps.name + " is missing signatures.  Collecting certs again to recover them.");
3126            } else {
3127                Log.i(TAG, srcFile.toString() + " changed; collecting certs");
3128            }
3129
3130            if (!pp.collectCertificates(pkg, parseFlags)) {
3131                mLastScanError = pp.getParseError();
3132                return false;
3133            }
3134        }
3135        return true;
3136    }
3137
3138    /*
3139     *  Scan a package and return the newly parsed package.
3140     *  Returns null in case of errors and the error code is stored in mLastScanError
3141     */
3142    private PackageParser.Package scanPackageLI(File scanFile,
3143            int parseFlags, int scanMode, long currentTime, UserHandle user) {
3144        mLastScanError = PackageManager.INSTALL_SUCCEEDED;
3145        String scanPath = scanFile.getPath();
3146        parseFlags |= mDefParseFlags;
3147        PackageParser pp = new PackageParser(scanPath);
3148        pp.setSeparateProcesses(mSeparateProcesses);
3149        pp.setOnlyCoreApps(mOnlyCore);
3150        final PackageParser.Package pkg = pp.parsePackage(scanFile,
3151                scanPath, mMetrics, parseFlags);
3152        if (pkg == null) {
3153            mLastScanError = pp.getParseError();
3154            return null;
3155        }
3156        PackageSetting ps = null;
3157        PackageSetting updatedPkg;
3158        // reader
3159        synchronized (mPackages) {
3160            // Look to see if we already know about this package.
3161            String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
3162            if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
3163                // This package has been renamed to its original name.  Let's
3164                // use that.
3165                ps = mSettings.peekPackageLPr(oldName);
3166            }
3167            // If there was no original package, see one for the real package name.
3168            if (ps == null) {
3169                ps = mSettings.peekPackageLPr(pkg.packageName);
3170            }
3171            // Check to see if this package could be hiding/updating a system
3172            // package.  Must look for it either under the original or real
3173            // package name depending on our state.
3174            updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
3175        }
3176        // First check if this is a system package that may involve an update
3177        if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
3178            if (ps != null && !ps.codePath.equals(scanFile)) {
3179                // The path has changed from what was last scanned...  check the
3180                // version of the new path against what we have stored to determine
3181                // what to do.
3182                if (pkg.mVersionCode < ps.versionCode) {
3183                    // The system package has been updated and the code path does not match
3184                    // Ignore entry. Skip it.
3185                    Log.i(TAG, "Package " + ps.name + " at " + scanFile
3186                            + " ignored: updated version " + ps.versionCode
3187                            + " better than this " + pkg.mVersionCode);
3188                    mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
3189                    return null;
3190                } else {
3191                    // The current app on the system partion is better than
3192                    // what we have updated to on the data partition; switch
3193                    // back to the system partition version.
3194                    // At this point, its safely assumed that package installation for
3195                    // apps in system partition will go through. If not there won't be a working
3196                    // version of the app
3197                    // writer
3198                    synchronized (mPackages) {
3199                        // Just remove the loaded entries from package lists.
3200                        mPackages.remove(ps.name);
3201                    }
3202                    Slog.w(TAG, "Package " + ps.name + " at " + scanFile
3203                            + "reverting from " + ps.codePathString
3204                            + ": new version " + pkg.mVersionCode
3205                            + " better than installed " + ps.versionCode);
3206
3207                    InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps),
3208                            ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString);
3209                    synchronized (mInstallLock) {
3210                        args.cleanUpResourcesLI();
3211                    }
3212                    synchronized (mPackages) {
3213                        mSettings.enableSystemPackageLPw(ps.name);
3214                    }
3215                }
3216            }
3217        }
3218
3219        if (updatedPkg != null) {
3220            // An updated system app will not have the PARSE_IS_SYSTEM flag set
3221            // initially
3222            parseFlags |= PackageParser.PARSE_IS_SYSTEM;
3223        }
3224        // Verify certificates against what was last scanned
3225        if (!collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags)) {
3226            Slog.w(TAG, "Failed verifying certificates for package:" + pkg.packageName);
3227            return null;
3228        }
3229
3230        /*
3231         * A new system app appeared, but we already had a non-system one of the
3232         * same name installed earlier.
3233         */
3234        boolean shouldHideSystemApp = false;
3235        if (updatedPkg == null && ps != null
3236                && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
3237            /*
3238             * Check to make sure the signatures match first. If they don't,
3239             * wipe the installed application and its data.
3240             */
3241            if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
3242                    != PackageManager.SIGNATURE_MATCH) {
3243                deletePackageLI(pkg.packageName, null, true, 0, null, false);
3244                ps = null;
3245            } else {
3246                /*
3247                 * If the newly-added system app is an older version than the
3248                 * already installed version, hide it. It will be scanned later
3249                 * and re-added like an update.
3250                 */
3251                if (pkg.mVersionCode < ps.versionCode) {
3252                    shouldHideSystemApp = true;
3253                } else {
3254                    /*
3255                     * The newly found system app is a newer version that the
3256                     * one previously installed. Simply remove the
3257                     * already-installed application and replace it with our own
3258                     * while keeping the application data.
3259                     */
3260                    Slog.w(TAG, "Package " + ps.name + " at " + scanFile + "reverting from "
3261                            + ps.codePathString + ": new version " + pkg.mVersionCode
3262                            + " better than installed " + ps.versionCode);
3263                    InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps),
3264                            ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString);
3265                    synchronized (mInstallLock) {
3266                        args.cleanUpResourcesLI();
3267                    }
3268                }
3269            }
3270        }
3271
3272        // The apk is forward locked (not public) if its code and resources
3273        // are kept in different files.
3274        // TODO grab this value from PackageSettings
3275        if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
3276            parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
3277        }
3278
3279        String codePath = null;
3280        String resPath = null;
3281        if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0) {
3282            if (ps != null && ps.resourcePathString != null) {
3283                resPath = ps.resourcePathString;
3284            } else {
3285                // Should not happen at all. Just log an error.
3286                Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName);
3287            }
3288        } else {
3289            resPath = pkg.mScanPath;
3290        }
3291        codePath = pkg.mScanPath;
3292        // Set application objects path explicitly.
3293        setApplicationInfoPaths(pkg, codePath, resPath);
3294        // Note that we invoke the following method only if we are about to unpack an application
3295        PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanMode
3296                | SCAN_UPDATE_SIGNATURE, currentTime, user);
3297
3298        /*
3299         * If the system app should be overridden by a previously installed
3300         * data, hide the system app now and let the /data/app scan pick it up
3301         * again.
3302         */
3303        if (shouldHideSystemApp) {
3304            synchronized (mPackages) {
3305                /*
3306                 * We have to grant systems permissions before we hide, because
3307                 * grantPermissions will assume the package update is trying to
3308                 * expand its permissions.
3309                 */
3310                grantPermissionsLPw(pkg, true);
3311                mSettings.disableSystemPackageLPw(pkg.packageName);
3312            }
3313        }
3314
3315        return scannedPkg;
3316    }
3317
3318    private static void setApplicationInfoPaths(PackageParser.Package pkg, String destCodePath,
3319            String destResPath) {
3320        pkg.mPath = pkg.mScanPath = destCodePath;
3321        pkg.applicationInfo.sourceDir = destCodePath;
3322        pkg.applicationInfo.publicSourceDir = destResPath;
3323    }
3324
3325    private static String fixProcessName(String defProcessName,
3326            String processName, int uid) {
3327        if (processName == null) {
3328            return defProcessName;
3329        }
3330        return processName;
3331    }
3332
3333    private boolean verifySignaturesLP(PackageSetting pkgSetting,
3334            PackageParser.Package pkg) {
3335        if (pkgSetting.signatures.mSignatures != null) {
3336            // Already existing package. Make sure signatures match
3337            if (compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) !=
3338                PackageManager.SIGNATURE_MATCH) {
3339                    Slog.e(TAG, "Package " + pkg.packageName
3340                            + " signatures do not match the previously installed version; ignoring!");
3341                    mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
3342                    return false;
3343                }
3344        }
3345        // Check for shared user signatures
3346        if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
3347            if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
3348                    pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
3349                Slog.e(TAG, "Package " + pkg.packageName
3350                        + " has no signatures that match those in shared user "
3351                        + pkgSetting.sharedUser.name + "; ignoring!");
3352                mLastScanError = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
3353                return false;
3354            }
3355        }
3356        return true;
3357    }
3358
3359    /**
3360     * Enforces that only the system UID or root's UID can call a method exposed
3361     * via Binder.
3362     *
3363     * @param message used as message if SecurityException is thrown
3364     * @throws SecurityException if the caller is not system or root
3365     */
3366    private static final void enforceSystemOrRoot(String message) {
3367        final int uid = Binder.getCallingUid();
3368        if (uid != Process.SYSTEM_UID && uid != 0) {
3369            throw new SecurityException(message);
3370        }
3371    }
3372
3373    public void performBootDexOpt() {
3374        ArrayList<PackageParser.Package> pkgs = null;
3375        synchronized (mPackages) {
3376            if (mDeferredDexOpt.size() > 0) {
3377                pkgs = new ArrayList<PackageParser.Package>(mDeferredDexOpt);
3378                mDeferredDexOpt.clear();
3379            }
3380        }
3381        if (pkgs != null) {
3382            for (int i=0; i<pkgs.size(); i++) {
3383                if (!isFirstBoot()) {
3384                    try {
3385                        ActivityManagerNative.getDefault().showBootMessage(
3386                                mContext.getResources().getString(
3387                                        com.android.internal.R.string.android_upgrading_apk,
3388                                        i+1, pkgs.size()), true);
3389                    } catch (RemoteException e) {
3390                    }
3391                }
3392                PackageParser.Package p = pkgs.get(i);
3393                synchronized (mInstallLock) {
3394                    if (!p.mDidDexOpt) {
3395                        performDexOptLI(p, false, false);
3396                    }
3397                }
3398            }
3399        }
3400    }
3401
3402    public boolean performDexOpt(String packageName) {
3403        enforceSystemOrRoot("Only the system can request dexopt be performed");
3404
3405        if (!mNoDexOpt) {
3406            return false;
3407        }
3408
3409        PackageParser.Package p;
3410        synchronized (mPackages) {
3411            p = mPackages.get(packageName);
3412            if (p == null || p.mDidDexOpt) {
3413                return false;
3414            }
3415        }
3416        synchronized (mInstallLock) {
3417            return performDexOptLI(p, false, false) == DEX_OPT_PERFORMED;
3418        }
3419    }
3420
3421    static final int DEX_OPT_SKIPPED = 0;
3422    static final int DEX_OPT_PERFORMED = 1;
3423    static final int DEX_OPT_DEFERRED = 2;
3424    static final int DEX_OPT_FAILED = -1;
3425
3426    private int performDexOptLI(PackageParser.Package pkg, boolean forceDex, boolean defer) {
3427        boolean performed = false;
3428        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
3429            String path = pkg.mScanPath;
3430            int ret = 0;
3431            try {
3432                if (forceDex || dalvik.system.DexFile.isDexOptNeeded(path)) {
3433                    if (!forceDex && defer) {
3434                        mDeferredDexOpt.add(pkg);
3435                        return DEX_OPT_DEFERRED;
3436                    } else {
3437                        Log.i(TAG, "Running dexopt on: " + pkg.applicationInfo.packageName);
3438                        ret = mInstaller.dexopt(path, pkg.applicationInfo.uid,
3439                                !isForwardLocked(pkg));
3440                        pkg.mDidDexOpt = true;
3441                        performed = true;
3442                    }
3443                }
3444            } catch (FileNotFoundException e) {
3445                Slog.w(TAG, "Apk not found for dexopt: " + path);
3446                ret = -1;
3447            } catch (IOException e) {
3448                Slog.w(TAG, "IOException reading apk: " + path, e);
3449                ret = -1;
3450            } catch (dalvik.system.StaleDexCacheError e) {
3451                Slog.w(TAG, "StaleDexCacheError when reading apk: " + path, e);
3452                ret = -1;
3453            } catch (Exception e) {
3454                Slog.w(TAG, "Exception when doing dexopt : ", e);
3455                ret = -1;
3456            }
3457            if (ret < 0) {
3458                //error from installer
3459                return DEX_OPT_FAILED;
3460            }
3461        }
3462
3463        return performed ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED;
3464    }
3465
3466    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
3467        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
3468            Slog.w(TAG, "Unable to update from " + oldPkg.name
3469                    + " to " + newPkg.packageName
3470                    + ": old package not in system partition");
3471            return false;
3472        } else if (mPackages.get(oldPkg.name) != null) {
3473            Slog.w(TAG, "Unable to update from " + oldPkg.name
3474                    + " to " + newPkg.packageName
3475                    + ": old package still exists");
3476            return false;
3477        }
3478        return true;
3479    }
3480
3481    File getDataPathForUser(int userId) {
3482        return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId);
3483    }
3484
3485    private File getDataPathForPackage(String packageName, int userId) {
3486        /*
3487         * Until we fully support multiple users, return the directory we
3488         * previously would have. The PackageManagerTests will need to be
3489         * revised when this is changed back..
3490         */
3491        if (userId == 0) {
3492            return new File(mAppDataDir, packageName);
3493        } else {
3494            return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId
3495                + File.separator + packageName);
3496        }
3497    }
3498
3499    private int createDataDirsLI(String packageName, int uid) {
3500        int[] users = sUserManager.getUserIds();
3501        int res = mInstaller.install(packageName, uid, uid);
3502        if (res < 0) {
3503            return res;
3504        }
3505        for (int user : users) {
3506            if (user != 0) {
3507                res = mInstaller.createUserData(packageName,
3508                        UserHandle.getUid(user, uid), user);
3509                if (res < 0) {
3510                    return res;
3511                }
3512            }
3513        }
3514        return res;
3515    }
3516
3517    private int removeDataDirsLI(String packageName) {
3518        int[] users = sUserManager.getUserIds();
3519        int res = 0;
3520        for (int user : users) {
3521            int resInner = mInstaller.remove(packageName, user);
3522            if (resInner < 0) {
3523                res = resInner;
3524            }
3525        }
3526        return res;
3527    }
3528
3529    private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
3530            int parseFlags, int scanMode, long currentTime, UserHandle user) {
3531        File scanFile = new File(pkg.mScanPath);
3532        if (scanFile == null || pkg.applicationInfo.sourceDir == null ||
3533                pkg.applicationInfo.publicSourceDir == null) {
3534            // Bail out. The resource and code paths haven't been set.
3535            Slog.w(TAG, " Code and resource paths haven't been set correctly");
3536            mLastScanError = PackageManager.INSTALL_FAILED_INVALID_APK;
3537            return null;
3538        }
3539        mScanningPath = scanFile;
3540
3541        if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
3542            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
3543        }
3544
3545        if (pkg.packageName.equals("android")) {
3546            synchronized (mPackages) {
3547                if (mAndroidApplication != null) {
3548                    Slog.w(TAG, "*************************************************");
3549                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
3550                    Slog.w(TAG, " file=" + mScanningPath);
3551                    Slog.w(TAG, "*************************************************");
3552                    mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
3553                    return null;
3554                }
3555
3556                // Set up information for our fall-back user intent resolution
3557                // activity.
3558                mPlatformPackage = pkg;
3559                pkg.mVersionCode = mSdkVersion;
3560                mAndroidApplication = pkg.applicationInfo;
3561                mResolveActivity.applicationInfo = mAndroidApplication;
3562                mResolveActivity.name = ResolverActivity.class.getName();
3563                mResolveActivity.packageName = mAndroidApplication.packageName;
3564                mResolveActivity.processName = mAndroidApplication.processName;
3565                mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
3566                mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
3567                mResolveActivity.theme = com.android.internal.R.style.Theme_Holo_Dialog_Alert;
3568                mResolveActivity.exported = true;
3569                mResolveActivity.enabled = true;
3570                mResolveInfo.activityInfo = mResolveActivity;
3571                mResolveInfo.priority = 0;
3572                mResolveInfo.preferredOrder = 0;
3573                mResolveInfo.match = 0;
3574                mResolveComponentName = new ComponentName(
3575                        mAndroidApplication.packageName, mResolveActivity.name);
3576            }
3577        }
3578
3579        if (DEBUG_PACKAGE_SCANNING) {
3580            if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
3581                Log.d(TAG, "Scanning package " + pkg.packageName);
3582        }
3583
3584        if (mPackages.containsKey(pkg.packageName)
3585                || mSharedLibraries.containsKey(pkg.packageName)) {
3586            Slog.w(TAG, "Application package " + pkg.packageName
3587                    + " already installed.  Skipping duplicate.");
3588            mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
3589            return null;
3590        }
3591
3592        // Initialize package source and resource directories
3593        File destCodeFile = new File(pkg.applicationInfo.sourceDir);
3594        File destResourceFile = new File(pkg.applicationInfo.publicSourceDir);
3595
3596        SharedUserSetting suid = null;
3597        PackageSetting pkgSetting = null;
3598
3599        if (!isSystemApp(pkg)) {
3600            // Only system apps can use these features.
3601            pkg.mOriginalPackages = null;
3602            pkg.mRealPackage = null;
3603            pkg.mAdoptPermissions = null;
3604        }
3605
3606        // writer
3607        synchronized (mPackages) {
3608            // Check all shared libraries and map to their actual file path.
3609            if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
3610                if (mTmpSharedLibraries == null ||
3611                        mTmpSharedLibraries.length < mSharedLibraries.size()) {
3612                    mTmpSharedLibraries = new String[mSharedLibraries.size()];
3613                }
3614                int num = 0;
3615                int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
3616                for (int i=0; i<N; i++) {
3617                    final String file = mSharedLibraries.get(pkg.usesLibraries.get(i));
3618                    if (file == null) {
3619                        Slog.e(TAG, "Package " + pkg.packageName
3620                                + " requires unavailable shared library "
3621                                + pkg.usesLibraries.get(i) + "; failing!");
3622                        mLastScanError = PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
3623                        return null;
3624                    }
3625                    mTmpSharedLibraries[num] = file;
3626                    num++;
3627                }
3628                N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
3629                for (int i=0; i<N; i++) {
3630                    final String file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
3631                    if (file == null) {
3632                        Slog.w(TAG, "Package " + pkg.packageName
3633                                + " desires unavailable shared library "
3634                                + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
3635                    } else {
3636                        mTmpSharedLibraries[num] = file;
3637                        num++;
3638                    }
3639                }
3640                if (num > 0) {
3641                    pkg.usesLibraryFiles = new String[num];
3642                    System.arraycopy(mTmpSharedLibraries, 0,
3643                            pkg.usesLibraryFiles, 0, num);
3644                }
3645            }
3646
3647            if (pkg.mSharedUserId != null) {
3648                suid = mSettings.getSharedUserLPw(pkg.mSharedUserId,
3649                        pkg.applicationInfo.flags, true);
3650                if (suid == null) {
3651                    Slog.w(TAG, "Creating application package " + pkg.packageName
3652                            + " for shared user failed");
3653                    mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
3654                    return null;
3655                }
3656                if (DEBUG_PACKAGE_SCANNING) {
3657                    if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
3658                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
3659                                + "): packages=" + suid.packages);
3660                }
3661            }
3662
3663            // Check if we are renaming from an original package name.
3664            PackageSetting origPackage = null;
3665            String realName = null;
3666            if (pkg.mOriginalPackages != null) {
3667                // This package may need to be renamed to a previously
3668                // installed name.  Let's check on that...
3669                final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
3670                if (pkg.mOriginalPackages.contains(renamed)) {
3671                    // This package had originally been installed as the
3672                    // original name, and we have already taken care of
3673                    // transitioning to the new one.  Just update the new
3674                    // one to continue using the old name.
3675                    realName = pkg.mRealPackage;
3676                    if (!pkg.packageName.equals(renamed)) {
3677                        // Callers into this function may have already taken
3678                        // care of renaming the package; only do it here if
3679                        // it is not already done.
3680                        pkg.setPackageName(renamed);
3681                    }
3682
3683                } else {
3684                    for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
3685                        if ((origPackage = mSettings.peekPackageLPr(
3686                                pkg.mOriginalPackages.get(i))) != null) {
3687                            // We do have the package already installed under its
3688                            // original name...  should we use it?
3689                            if (!verifyPackageUpdateLPr(origPackage, pkg)) {
3690                                // New package is not compatible with original.
3691                                origPackage = null;
3692                                continue;
3693                            } else if (origPackage.sharedUser != null) {
3694                                // Make sure uid is compatible between packages.
3695                                if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
3696                                    Slog.w(TAG, "Unable to migrate data from " + origPackage.name
3697                                            + " to " + pkg.packageName + ": old uid "
3698                                            + origPackage.sharedUser.name
3699                                            + " differs from " + pkg.mSharedUserId);
3700                                    origPackage = null;
3701                                    continue;
3702                                }
3703                            } else {
3704                                if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
3705                                        + pkg.packageName + " to old name " + origPackage.name);
3706                            }
3707                            break;
3708                        }
3709                    }
3710                }
3711            }
3712
3713            if (mTransferedPackages.contains(pkg.packageName)) {
3714                Slog.w(TAG, "Package " + pkg.packageName
3715                        + " was transferred to another, but its .apk remains");
3716            }
3717
3718            // Just create the setting, don't add it yet. For already existing packages
3719            // the PkgSetting exists already and doesn't have to be created.
3720            pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
3721                    destResourceFile, pkg.applicationInfo.nativeLibraryDir,
3722                    pkg.applicationInfo.flags, user, false);
3723            if (pkgSetting == null) {
3724                Slog.w(TAG, "Creating application package " + pkg.packageName + " failed");
3725                mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
3726                return null;
3727            }
3728
3729            if (pkgSetting.origPackage != null) {
3730                // If we are first transitioning from an original package,
3731                // fix up the new package's name now.  We need to do this after
3732                // looking up the package under its new name, so getPackageLP
3733                // can take care of fiddling things correctly.
3734                pkg.setPackageName(origPackage.name);
3735
3736                // File a report about this.
3737                String msg = "New package " + pkgSetting.realName
3738                        + " renamed to replace old package " + pkgSetting.name;
3739                reportSettingsProblem(Log.WARN, msg);
3740
3741                // Make a note of it.
3742                mTransferedPackages.add(origPackage.name);
3743
3744                // No longer need to retain this.
3745                pkgSetting.origPackage = null;
3746            }
3747
3748            if (realName != null) {
3749                // Make a note of it.
3750                mTransferedPackages.add(pkg.packageName);
3751            }
3752
3753            if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
3754                pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
3755            }
3756
3757            pkg.applicationInfo.uid = pkgSetting.appId;
3758            pkg.mExtras = pkgSetting;
3759
3760            if (!verifySignaturesLP(pkgSetting, pkg)) {
3761                if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
3762                    return null;
3763                }
3764                // The signature has changed, but this package is in the system
3765                // image...  let's recover!
3766                pkgSetting.signatures.mSignatures = pkg.mSignatures;
3767                // However...  if this package is part of a shared user, but it
3768                // doesn't match the signature of the shared user, let's fail.
3769                // What this means is that you can't change the signatures
3770                // associated with an overall shared user, which doesn't seem all
3771                // that unreasonable.
3772                if (pkgSetting.sharedUser != null) {
3773                    if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
3774                            pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
3775                        Log.w(TAG, "Signature mismatch for shared user : " + pkgSetting.sharedUser);
3776                        mLastScanError = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
3777                        return null;
3778                    }
3779                }
3780                // File a report about this.
3781                String msg = "System package " + pkg.packageName
3782                        + " signature changed; retaining data.";
3783                reportSettingsProblem(Log.WARN, msg);
3784            }
3785
3786            // Verify that this new package doesn't have any content providers
3787            // that conflict with existing packages.  Only do this if the
3788            // package isn't already installed, since we don't want to break
3789            // things that are installed.
3790            if ((scanMode&SCAN_NEW_INSTALL) != 0) {
3791                final int N = pkg.providers.size();
3792                int i;
3793                for (i=0; i<N; i++) {
3794                    PackageParser.Provider p = pkg.providers.get(i);
3795                    if (p.info.authority != null) {
3796                        String names[] = p.info.authority.split(";");
3797                        for (int j = 0; j < names.length; j++) {
3798                            if (mProviders.containsKey(names[j])) {
3799                                PackageParser.Provider other = mProviders.get(names[j]);
3800                                Slog.w(TAG, "Can't install because provider name " + names[j] +
3801                                        " (in package " + pkg.applicationInfo.packageName +
3802                                        ") is already used by "
3803                                        + ((other != null && other.getComponentName() != null)
3804                                                ? other.getComponentName().getPackageName() : "?"));
3805                                mLastScanError = PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
3806                                return null;
3807                            }
3808                        }
3809                    }
3810                }
3811            }
3812
3813            if (pkg.mAdoptPermissions != null) {
3814                // This package wants to adopt ownership of permissions from
3815                // another package.
3816                for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
3817                    final String origName = pkg.mAdoptPermissions.get(i);
3818                    final PackageSetting orig = mSettings.peekPackageLPr(origName);
3819                    if (orig != null) {
3820                        if (verifyPackageUpdateLPr(orig, pkg)) {
3821                            Slog.i(TAG, "Adopting permissions from " + origName + " to "
3822                                    + pkg.packageName);
3823                            mSettings.transferPermissionsLPw(origName, pkg.packageName);
3824                        }
3825                    }
3826                }
3827            }
3828        }
3829
3830        final String pkgName = pkg.packageName;
3831
3832        final long scanFileTime = scanFile.lastModified();
3833        final boolean forceDex = (scanMode&SCAN_FORCE_DEX) != 0;
3834        pkg.applicationInfo.processName = fixProcessName(
3835                pkg.applicationInfo.packageName,
3836                pkg.applicationInfo.processName,
3837                pkg.applicationInfo.uid);
3838
3839        File dataPath;
3840        if (mPlatformPackage == pkg) {
3841            // The system package is special.
3842            dataPath = new File (Environment.getDataDirectory(), "system");
3843            pkg.applicationInfo.dataDir = dataPath.getPath();
3844        } else {
3845            // This is a normal package, need to make its data directory.
3846            dataPath = getDataPathForPackage(pkg.packageName, 0);
3847
3848            boolean uidError = false;
3849
3850            if (dataPath.exists()) {
3851                int currentUid = 0;
3852                try {
3853                    StructStat stat = Libcore.os.stat(dataPath.getPath());
3854                    currentUid = stat.st_uid;
3855                } catch (ErrnoException e) {
3856                    Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e);
3857                }
3858
3859                // If we have mismatched owners for the data path, we have a problem.
3860                if (currentUid != pkg.applicationInfo.uid) {
3861                    boolean recovered = false;
3862                    if (currentUid == 0) {
3863                        // The directory somehow became owned by root.  Wow.
3864                        // This is probably because the system was stopped while
3865                        // installd was in the middle of messing with its libs
3866                        // directory.  Ask installd to fix that.
3867                        int ret = mInstaller.fixUid(pkgName, pkg.applicationInfo.uid,
3868                                pkg.applicationInfo.uid);
3869                        if (ret >= 0) {
3870                            recovered = true;
3871                            String msg = "Package " + pkg.packageName
3872                                    + " unexpectedly changed to uid 0; recovered to " +
3873                                    + pkg.applicationInfo.uid;
3874                            reportSettingsProblem(Log.WARN, msg);
3875                        }
3876                    }
3877                    if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
3878                            || (scanMode&SCAN_BOOTING) != 0)) {
3879                        // If this is a system app, we can at least delete its
3880                        // current data so the application will still work.
3881                        int ret = removeDataDirsLI(pkgName);
3882                        if (ret >= 0) {
3883                            // TODO: Kill the processes first
3884                            // Old data gone!
3885                            String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
3886                                    ? "System package " : "Third party package ";
3887                            String msg = prefix + pkg.packageName
3888                                    + " has changed from uid: "
3889                                    + currentUid + " to "
3890                                    + pkg.applicationInfo.uid + "; old data erased";
3891                            reportSettingsProblem(Log.WARN, msg);
3892                            recovered = true;
3893
3894                            // And now re-install the app.
3895                            ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid);
3896                            if (ret == -1) {
3897                                // Ack should not happen!
3898                                msg = prefix + pkg.packageName
3899                                        + " could not have data directory re-created after delete.";
3900                                reportSettingsProblem(Log.WARN, msg);
3901                                mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
3902                                return null;
3903                            }
3904                        }
3905                        if (!recovered) {
3906                            mHasSystemUidErrors = true;
3907                        }
3908                    } else if (!recovered) {
3909                        // If we allow this install to proceed, we will be broken.
3910                        // Abort, abort!
3911                        mLastScanError = PackageManager.INSTALL_FAILED_UID_CHANGED;
3912                        return null;
3913                    }
3914                    if (!recovered) {
3915                        pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
3916                            + pkg.applicationInfo.uid + "/fs_"
3917                            + currentUid;
3918                        pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
3919                        String msg = "Package " + pkg.packageName
3920                                + " has mismatched uid: "
3921                                + currentUid + " on disk, "
3922                                + pkg.applicationInfo.uid + " in settings";
3923                        // writer
3924                        synchronized (mPackages) {
3925                            mSettings.mReadMessages.append(msg);
3926                            mSettings.mReadMessages.append('\n');
3927                            uidError = true;
3928                            if (!pkgSetting.uidError) {
3929                                reportSettingsProblem(Log.ERROR, msg);
3930                            }
3931                        }
3932                    }
3933                }
3934                pkg.applicationInfo.dataDir = dataPath.getPath();
3935            } else {
3936                if (DEBUG_PACKAGE_SCANNING) {
3937                    if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
3938                        Log.v(TAG, "Want this data dir: " + dataPath);
3939                }
3940                //invoke installer to do the actual installation
3941                int ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid);
3942                if (ret < 0) {
3943                    // Error from installer
3944                    mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
3945                    return null;
3946                }
3947
3948                if (dataPath.exists()) {
3949                    pkg.applicationInfo.dataDir = dataPath.getPath();
3950                } else {
3951                    Slog.w(TAG, "Unable to create data directory: " + dataPath);
3952                    pkg.applicationInfo.dataDir = null;
3953                }
3954            }
3955
3956            /*
3957             * Set the data dir to the default "/data/data/<package name>/lib"
3958             * if we got here without anyone telling us different (e.g., apps
3959             * stored on SD card have their native libraries stored in the ASEC
3960             * container with the APK).
3961             *
3962             * This happens during an upgrade from a package settings file that
3963             * doesn't have a native library path attribute at all.
3964             */
3965            if (pkg.applicationInfo.nativeLibraryDir == null && pkg.applicationInfo.dataDir != null) {
3966                if (pkgSetting.nativeLibraryPathString == null) {
3967                    final String nativeLibraryPath = new File(dataPath, LIB_DIR_NAME).getPath();
3968                    pkg.applicationInfo.nativeLibraryDir = nativeLibraryPath;
3969                    pkgSetting.nativeLibraryPathString = nativeLibraryPath;
3970                } else {
3971                    pkg.applicationInfo.nativeLibraryDir = pkgSetting.nativeLibraryPathString;
3972                }
3973            }
3974
3975            pkgSetting.uidError = uidError;
3976        }
3977
3978        String path = scanFile.getPath();
3979        /* Note: We don't want to unpack the native binaries for
3980         *        system applications, unless they have been updated
3981         *        (the binaries are already under /system/lib).
3982         *        Also, don't unpack libs for apps on the external card
3983         *        since they should have their libraries in the ASEC
3984         *        container already.
3985         *
3986         *        In other words, we're going to unpack the binaries
3987         *        only for non-system apps and system app upgrades.
3988         */
3989        if (pkg.applicationInfo.nativeLibraryDir != null) {
3990            try {
3991                final File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
3992                final String dataPathString = dataPath.getCanonicalPath();
3993
3994                if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
3995                    /*
3996                     * Upgrading from a previous version of the OS sometimes
3997                     * leaves native libraries in the /data/data/<app>/lib
3998                     * directory for system apps even when they shouldn't be.
3999                     * Recent changes in the JNI library search path
4000                     * necessitates we remove those to match previous behavior.
4001                     */
4002                    if (NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryDir)) {
4003                        Log.i(TAG, "removed obsolete native libraries for system package "
4004                                + path);
4005                    }
4006                } else if (nativeLibraryDir.getParentFile().getCanonicalPath()
4007                        .equals(dataPathString)) {
4008                    /*
4009                     * Make sure the native library dir isn't a symlink to
4010                     * something. If it is, ask installd to remove it and create
4011                     * a directory so we can copy to it afterwards.
4012                     */
4013                    boolean isSymLink;
4014                    try {
4015                        isSymLink = S_ISLNK(Libcore.os.lstat(nativeLibraryDir.getPath()).st_mode);
4016                    } catch (ErrnoException e) {
4017                        // This shouldn't happen, but we'll fail-safe.
4018                        isSymLink = true;
4019                    }
4020                    if (isSymLink) {
4021                        mInstaller.unlinkNativeLibraryDirectory(dataPathString);
4022                    }
4023
4024                    /*
4025                     * If this is an internal application or our
4026                     * nativeLibraryPath points to our data directory, unpack
4027                     * the libraries if necessary.
4028                     */
4029                    NativeLibraryHelper.copyNativeBinariesIfNeededLI(scanFile, nativeLibraryDir);
4030                } else {
4031                    Slog.i(TAG, "Linking native library dir for " + path);
4032                    mInstaller.linkNativeLibraryDirectory(dataPathString,
4033                            pkg.applicationInfo.nativeLibraryDir);
4034                }
4035            } catch (IOException ioe) {
4036                Log.e(TAG, "Unable to get canonical file " + ioe.toString());
4037            }
4038        }
4039        pkg.mScanPath = path;
4040
4041        if ((scanMode&SCAN_NO_DEX) == 0) {
4042            if (performDexOptLI(pkg, forceDex, (scanMode&SCAN_DEFER_DEX) != 0)
4043                    == DEX_OPT_FAILED) {
4044                mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT;
4045                return null;
4046            }
4047        }
4048
4049        if (mFactoryTest && pkg.requestedPermissions.contains(
4050                android.Manifest.permission.FACTORY_TEST)) {
4051            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
4052        }
4053
4054        // Request the ActivityManager to kill the process(only for existing packages)
4055        // so that we do not end up in a confused state while the user is still using the older
4056        // version of the application while the new one gets installed.
4057        if ((parseFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
4058            killApplication(pkg.applicationInfo.packageName,
4059                        pkg.applicationInfo.uid);
4060        }
4061
4062        // writer
4063        synchronized (mPackages) {
4064            // We don't expect installation to fail beyond this point,
4065            if ((scanMode&SCAN_MONITOR) != 0) {
4066                mAppDirs.put(pkg.mPath, pkg);
4067            }
4068            // Add the new setting to mSettings
4069            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
4070            // Add the new setting to mPackages
4071            mPackages.put(pkg.applicationInfo.packageName, pkg);
4072            // Make sure we don't accidentally delete its data.
4073            for (int i=0; i<mSettings.mPackagesToBeCleaned.size(); i++) {
4074                mSettings.mPackagesToBeCleaned.valueAt(i).remove(pkgName);
4075            }
4076
4077            // Take care of first install / last update times.
4078            if (currentTime != 0) {
4079                if (pkgSetting.firstInstallTime == 0) {
4080                    pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
4081                } else if ((scanMode&SCAN_UPDATE_TIME) != 0) {
4082                    pkgSetting.lastUpdateTime = currentTime;
4083                }
4084            } else if (pkgSetting.firstInstallTime == 0) {
4085                // We need *something*.  Take time time stamp of the file.
4086                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
4087            } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
4088                if (scanFileTime != pkgSetting.timeStamp) {
4089                    // A package on the system image has changed; consider this
4090                    // to be an update.
4091                    pkgSetting.lastUpdateTime = scanFileTime;
4092                }
4093            }
4094
4095            int N = pkg.providers.size();
4096            StringBuilder r = null;
4097            int i;
4098            for (i=0; i<N; i++) {
4099                PackageParser.Provider p = pkg.providers.get(i);
4100                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
4101                        p.info.processName, pkg.applicationInfo.uid);
4102                mProvidersByComponent.put(new ComponentName(p.info.packageName,
4103                        p.info.name), p);
4104                p.syncable = p.info.isSyncable;
4105                if (p.info.authority != null) {
4106                    String names[] = p.info.authority.split(";");
4107                    p.info.authority = null;
4108                    for (int j = 0; j < names.length; j++) {
4109                        if (j == 1 && p.syncable) {
4110                            // We only want the first authority for a provider to possibly be
4111                            // syncable, so if we already added this provider using a different
4112                            // authority clear the syncable flag. We copy the provider before
4113                            // changing it because the mProviders object contains a reference
4114                            // to a provider that we don't want to change.
4115                            // Only do this for the second authority since the resulting provider
4116                            // object can be the same for all future authorities for this provider.
4117                            p = new PackageParser.Provider(p);
4118                            p.syncable = false;
4119                        }
4120                        if (!mProviders.containsKey(names[j])) {
4121                            mProviders.put(names[j], p);
4122                            if (p.info.authority == null) {
4123                                p.info.authority = names[j];
4124                            } else {
4125                                p.info.authority = p.info.authority + ";" + names[j];
4126                            }
4127                            if (DEBUG_PACKAGE_SCANNING) {
4128                                if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
4129                                    Log.d(TAG, "Registered content provider: " + names[j]
4130                                            + ", className = " + p.info.name + ", isSyncable = "
4131                                            + p.info.isSyncable);
4132                            }
4133                        } else {
4134                            PackageParser.Provider other = mProviders.get(names[j]);
4135                            Slog.w(TAG, "Skipping provider name " + names[j] +
4136                                    " (in package " + pkg.applicationInfo.packageName +
4137                                    "): name already used by "
4138                                    + ((other != null && other.getComponentName() != null)
4139                                            ? other.getComponentName().getPackageName() : "?"));
4140                        }
4141                    }
4142                }
4143                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4144                    if (r == null) {
4145                        r = new StringBuilder(256);
4146                    } else {
4147                        r.append(' ');
4148                    }
4149                    r.append(p.info.name);
4150                }
4151            }
4152            if (r != null) {
4153                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
4154            }
4155
4156            N = pkg.services.size();
4157            r = null;
4158            for (i=0; i<N; i++) {
4159                PackageParser.Service s = pkg.services.get(i);
4160                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
4161                        s.info.processName, pkg.applicationInfo.uid);
4162                mServices.addService(s);
4163                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4164                    if (r == null) {
4165                        r = new StringBuilder(256);
4166                    } else {
4167                        r.append(' ');
4168                    }
4169                    r.append(s.info.name);
4170                }
4171            }
4172            if (r != null) {
4173                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
4174            }
4175
4176            N = pkg.receivers.size();
4177            r = null;
4178            for (i=0; i<N; i++) {
4179                PackageParser.Activity a = pkg.receivers.get(i);
4180                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
4181                        a.info.processName, pkg.applicationInfo.uid);
4182                mReceivers.addActivity(a, "receiver");
4183                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4184                    if (r == null) {
4185                        r = new StringBuilder(256);
4186                    } else {
4187                        r.append(' ');
4188                    }
4189                    r.append(a.info.name);
4190                }
4191            }
4192            if (r != null) {
4193                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
4194            }
4195
4196            N = pkg.activities.size();
4197            r = null;
4198            for (i=0; i<N; i++) {
4199                PackageParser.Activity a = pkg.activities.get(i);
4200                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
4201                        a.info.processName, pkg.applicationInfo.uid);
4202                mActivities.addActivity(a, "activity");
4203                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4204                    if (r == null) {
4205                        r = new StringBuilder(256);
4206                    } else {
4207                        r.append(' ');
4208                    }
4209                    r.append(a.info.name);
4210                }
4211            }
4212            if (r != null) {
4213                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
4214            }
4215
4216            N = pkg.permissionGroups.size();
4217            r = null;
4218            for (i=0; i<N; i++) {
4219                PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
4220                PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
4221                if (cur == null) {
4222                    mPermissionGroups.put(pg.info.name, pg);
4223                    if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4224                        if (r == null) {
4225                            r = new StringBuilder(256);
4226                        } else {
4227                            r.append(' ');
4228                        }
4229                        r.append(pg.info.name);
4230                    }
4231                } else {
4232                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
4233                            + pg.info.packageName + " ignored: original from "
4234                            + cur.info.packageName);
4235                    if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4236                        if (r == null) {
4237                            r = new StringBuilder(256);
4238                        } else {
4239                            r.append(' ');
4240                        }
4241                        r.append("DUP:");
4242                        r.append(pg.info.name);
4243                    }
4244                }
4245            }
4246            if (r != null) {
4247                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
4248            }
4249
4250            N = pkg.permissions.size();
4251            r = null;
4252            for (i=0; i<N; i++) {
4253                PackageParser.Permission p = pkg.permissions.get(i);
4254                HashMap<String, BasePermission> permissionMap =
4255                        p.tree ? mSettings.mPermissionTrees
4256                        : mSettings.mPermissions;
4257                p.group = mPermissionGroups.get(p.info.group);
4258                if (p.info.group == null || p.group != null) {
4259                    BasePermission bp = permissionMap.get(p.info.name);
4260                    if (bp == null) {
4261                        bp = new BasePermission(p.info.name, p.info.packageName,
4262                                BasePermission.TYPE_NORMAL);
4263                        permissionMap.put(p.info.name, bp);
4264                    }
4265                    if (bp.perm == null) {
4266                        if (bp.sourcePackage == null
4267                                || bp.sourcePackage.equals(p.info.packageName)) {
4268                            BasePermission tree = findPermissionTreeLP(p.info.name);
4269                            if (tree == null
4270                                    || tree.sourcePackage.equals(p.info.packageName)) {
4271                                bp.packageSetting = pkgSetting;
4272                                bp.perm = p;
4273                                bp.uid = pkg.applicationInfo.uid;
4274                                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4275                                    if (r == null) {
4276                                        r = new StringBuilder(256);
4277                                    } else {
4278                                        r.append(' ');
4279                                    }
4280                                    r.append(p.info.name);
4281                                }
4282                            } else {
4283                                Slog.w(TAG, "Permission " + p.info.name + " from package "
4284                                        + p.info.packageName + " ignored: base tree "
4285                                        + tree.name + " is from package "
4286                                        + tree.sourcePackage);
4287                            }
4288                        } else {
4289                            Slog.w(TAG, "Permission " + p.info.name + " from package "
4290                                    + p.info.packageName + " ignored: original from "
4291                                    + bp.sourcePackage);
4292                        }
4293                    } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4294                        if (r == null) {
4295                            r = new StringBuilder(256);
4296                        } else {
4297                            r.append(' ');
4298                        }
4299                        r.append("DUP:");
4300                        r.append(p.info.name);
4301                    }
4302                    if (bp.perm == p) {
4303                        bp.protectionLevel = p.info.protectionLevel;
4304                    }
4305                } else {
4306                    Slog.w(TAG, "Permission " + p.info.name + " from package "
4307                            + p.info.packageName + " ignored: no group "
4308                            + p.group);
4309                }
4310            }
4311            if (r != null) {
4312                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
4313            }
4314
4315            N = pkg.instrumentation.size();
4316            r = null;
4317            for (i=0; i<N; i++) {
4318                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
4319                a.info.packageName = pkg.applicationInfo.packageName;
4320                a.info.sourceDir = pkg.applicationInfo.sourceDir;
4321                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
4322                a.info.dataDir = pkg.applicationInfo.dataDir;
4323                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
4324                mInstrumentation.put(a.getComponentName(), a);
4325                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4326                    if (r == null) {
4327                        r = new StringBuilder(256);
4328                    } else {
4329                        r.append(' ');
4330                    }
4331                    r.append(a.info.name);
4332                }
4333            }
4334            if (r != null) {
4335                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
4336            }
4337
4338            if (pkg.protectedBroadcasts != null) {
4339                N = pkg.protectedBroadcasts.size();
4340                for (i=0; i<N; i++) {
4341                    mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
4342                }
4343            }
4344
4345            pkgSetting.setTimeStamp(scanFileTime);
4346        }
4347
4348        return pkg;
4349    }
4350
4351    private void killApplication(String pkgName, int uid) {
4352        // Request the ActivityManager to kill the process(only for existing packages)
4353        // so that we do not end up in a confused state while the user is still using the older
4354        // version of the application while the new one gets installed.
4355        IActivityManager am = ActivityManagerNative.getDefault();
4356        if (am != null) {
4357            try {
4358                am.killApplicationWithUid(pkgName, uid);
4359            } catch (RemoteException e) {
4360            }
4361        }
4362    }
4363
4364    void removePackageLI(PackageParser.Package pkg, boolean chatty) {
4365        if (DEBUG_INSTALL) {
4366            if (chatty)
4367                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
4368        }
4369
4370        // writer
4371        synchronized (mPackages) {
4372            mPackages.remove(pkg.applicationInfo.packageName);
4373            if (pkg.mPath != null) {
4374                mAppDirs.remove(pkg.mPath);
4375            }
4376
4377            int N = pkg.providers.size();
4378            StringBuilder r = null;
4379            int i;
4380            for (i=0; i<N; i++) {
4381                PackageParser.Provider p = pkg.providers.get(i);
4382                mProvidersByComponent.remove(new ComponentName(p.info.packageName,
4383                        p.info.name));
4384                if (p.info.authority == null) {
4385
4386                    /* The is another ContentProvider with this authority when
4387                     * this app was installed so this authority is null,
4388                     * Ignore it as we don't have to unregister the provider.
4389                     */
4390                    continue;
4391                }
4392                String names[] = p.info.authority.split(";");
4393                for (int j = 0; j < names.length; j++) {
4394                    if (mProviders.get(names[j]) == p) {
4395                        mProviders.remove(names[j]);
4396                        if (DEBUG_REMOVE) {
4397                            if (chatty)
4398                                Log.d(TAG, "Unregistered content provider: " + names[j]
4399                                        + ", className = " + p.info.name + ", isSyncable = "
4400                                        + p.info.isSyncable);
4401                        }
4402                    }
4403                }
4404                if (chatty) {
4405                    if (r == null) {
4406                        r = new StringBuilder(256);
4407                    } else {
4408                        r.append(' ');
4409                    }
4410                    r.append(p.info.name);
4411                }
4412            }
4413            if (r != null) {
4414                if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
4415            }
4416
4417            N = pkg.services.size();
4418            r = null;
4419            for (i=0; i<N; i++) {
4420                PackageParser.Service s = pkg.services.get(i);
4421                mServices.removeService(s);
4422                if (chatty) {
4423                    if (r == null) {
4424                        r = new StringBuilder(256);
4425                    } else {
4426                        r.append(' ');
4427                    }
4428                    r.append(s.info.name);
4429                }
4430            }
4431            if (r != null) {
4432                if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
4433            }
4434
4435            N = pkg.receivers.size();
4436            r = null;
4437            for (i=0; i<N; i++) {
4438                PackageParser.Activity a = pkg.receivers.get(i);
4439                mReceivers.removeActivity(a, "receiver");
4440                if (chatty) {
4441                    if (r == null) {
4442                        r = new StringBuilder(256);
4443                    } else {
4444                        r.append(' ');
4445                    }
4446                    r.append(a.info.name);
4447                }
4448            }
4449            if (r != null) {
4450                if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
4451            }
4452
4453            N = pkg.activities.size();
4454            r = null;
4455            for (i=0; i<N; i++) {
4456                PackageParser.Activity a = pkg.activities.get(i);
4457                mActivities.removeActivity(a, "activity");
4458                if (chatty) {
4459                    if (r == null) {
4460                        r = new StringBuilder(256);
4461                    } else {
4462                        r.append(' ');
4463                    }
4464                    r.append(a.info.name);
4465                }
4466            }
4467            if (r != null) {
4468                if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
4469            }
4470
4471            N = pkg.permissions.size();
4472            r = null;
4473            for (i=0; i<N; i++) {
4474                PackageParser.Permission p = pkg.permissions.get(i);
4475                BasePermission bp = mSettings.mPermissions.get(p.info.name);
4476                if (bp == null) {
4477                    bp = mSettings.mPermissionTrees.get(p.info.name);
4478                }
4479                if (bp != null && bp.perm == p) {
4480                    bp.perm = null;
4481                    if (chatty) {
4482                        if (r == null) {
4483                            r = new StringBuilder(256);
4484                        } else {
4485                            r.append(' ');
4486                        }
4487                        r.append(p.info.name);
4488                    }
4489                }
4490            }
4491            if (r != null) {
4492                if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
4493            }
4494
4495            N = pkg.instrumentation.size();
4496            r = null;
4497            for (i=0; i<N; i++) {
4498                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
4499                mInstrumentation.remove(a.getComponentName());
4500                if (chatty) {
4501                    if (r == null) {
4502                        r = new StringBuilder(256);
4503                    } else {
4504                        r.append(' ');
4505                    }
4506                    r.append(a.info.name);
4507                }
4508            }
4509            if (r != null) {
4510                if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
4511            }
4512        }
4513    }
4514
4515    private static final boolean isPackageFilename(String name) {
4516        return name != null && name.endsWith(".apk");
4517    }
4518
4519    private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
4520        for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
4521            if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
4522                return true;
4523            }
4524        }
4525        return false;
4526    }
4527
4528    static final int UPDATE_PERMISSIONS_ALL = 1<<0;
4529    static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
4530    static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
4531
4532    private void updatePermissionsLPw(String changingPkg,
4533            PackageParser.Package pkgInfo, int flags) {
4534        // Make sure there are no dangling permission trees.
4535        Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
4536        while (it.hasNext()) {
4537            final BasePermission bp = it.next();
4538            if (bp.packageSetting == null) {
4539                // We may not yet have parsed the package, so just see if
4540                // we still know about its settings.
4541                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
4542            }
4543            if (bp.packageSetting == null) {
4544                Slog.w(TAG, "Removing dangling permission tree: " + bp.name
4545                        + " from package " + bp.sourcePackage);
4546                it.remove();
4547            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
4548                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
4549                    Slog.i(TAG, "Removing old permission tree: " + bp.name
4550                            + " from package " + bp.sourcePackage);
4551                    flags |= UPDATE_PERMISSIONS_ALL;
4552                    it.remove();
4553                }
4554            }
4555        }
4556
4557        // Make sure all dynamic permissions have been assigned to a package,
4558        // and make sure there are no dangling permissions.
4559        it = mSettings.mPermissions.values().iterator();
4560        while (it.hasNext()) {
4561            final BasePermission bp = it.next();
4562            if (bp.type == BasePermission.TYPE_DYNAMIC) {
4563                if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
4564                        + bp.name + " pkg=" + bp.sourcePackage
4565                        + " info=" + bp.pendingInfo);
4566                if (bp.packageSetting == null && bp.pendingInfo != null) {
4567                    final BasePermission tree = findPermissionTreeLP(bp.name);
4568                    if (tree != null && tree.perm != null) {
4569                        bp.packageSetting = tree.packageSetting;
4570                        bp.perm = new PackageParser.Permission(tree.perm.owner,
4571                                new PermissionInfo(bp.pendingInfo));
4572                        bp.perm.info.packageName = tree.perm.info.packageName;
4573                        bp.perm.info.name = bp.name;
4574                        bp.uid = tree.uid;
4575                    }
4576                }
4577            }
4578            if (bp.packageSetting == null) {
4579                // We may not yet have parsed the package, so just see if
4580                // we still know about its settings.
4581                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
4582            }
4583            if (bp.packageSetting == null) {
4584                Slog.w(TAG, "Removing dangling permission: " + bp.name
4585                        + " from package " + bp.sourcePackage);
4586                it.remove();
4587            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
4588                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
4589                    Slog.i(TAG, "Removing old permission: " + bp.name
4590                            + " from package " + bp.sourcePackage);
4591                    flags |= UPDATE_PERMISSIONS_ALL;
4592                    it.remove();
4593                }
4594            }
4595        }
4596
4597        // Now update the permissions for all packages, in particular
4598        // replace the granted permissions of the system packages.
4599        if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
4600            for (PackageParser.Package pkg : mPackages.values()) {
4601                if (pkg != pkgInfo) {
4602                    grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0);
4603                }
4604            }
4605        }
4606
4607        if (pkgInfo != null) {
4608            grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0);
4609        }
4610    }
4611
4612    private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace) {
4613        final PackageSetting ps = (PackageSetting) pkg.mExtras;
4614        if (ps == null) {
4615            return;
4616        }
4617        final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
4618        HashSet<String> origPermissions = gp.grantedPermissions;
4619        boolean changedPermission = false;
4620
4621        if (replace) {
4622            ps.permissionsFixed = false;
4623            if (gp == ps) {
4624                origPermissions = new HashSet<String>(gp.grantedPermissions);
4625                gp.grantedPermissions.clear();
4626                gp.gids = mGlobalGids;
4627            }
4628        }
4629
4630        if (gp.gids == null) {
4631            gp.gids = mGlobalGids;
4632        }
4633
4634        final int N = pkg.requestedPermissions.size();
4635        for (int i=0; i<N; i++) {
4636            final String name = pkg.requestedPermissions.get(i);
4637            //final boolean required = pkg.requestedPermssionsRequired.get(i);
4638            final BasePermission bp = mSettings.mPermissions.get(name);
4639            if (DEBUG_INSTALL) {
4640                if (gp != ps) {
4641                    Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
4642                }
4643            }
4644            if (bp != null && bp.packageSetting != null) {
4645                final String perm = bp.name;
4646                boolean allowed;
4647                boolean allowedSig = false;
4648                final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
4649                if (level == PermissionInfo.PROTECTION_NORMAL
4650                        || level == PermissionInfo.PROTECTION_DANGEROUS) {
4651                    allowed = true;
4652                } else if (bp.packageSetting == null) {
4653                    // This permission is invalid; skip it.
4654                    allowed = false;
4655                } else if (level == PermissionInfo.PROTECTION_SIGNATURE) {
4656                    allowed = (compareSignatures(
4657                            bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
4658                                    == PackageManager.SIGNATURE_MATCH)
4659                            || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
4660                                    == PackageManager.SIGNATURE_MATCH);
4661                    if (!allowed && (bp.protectionLevel
4662                            & PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) {
4663                        if (isSystemApp(pkg)) {
4664                            // For updated system applications, a system permission
4665                            // is granted only if it had been defined by the original application.
4666                            if (isUpdatedSystemApp(pkg)) {
4667                                final PackageSetting sysPs = mSettings
4668                                        .getDisabledSystemPkgLPr(pkg.packageName);
4669                                final GrantedPermissions origGp = sysPs.sharedUser != null
4670                                        ? sysPs.sharedUser : sysPs;
4671                                if (origGp.grantedPermissions.contains(perm)) {
4672                                    allowed = true;
4673                                } else {
4674                                    allowed = false;
4675                                }
4676                            } else {
4677                                allowed = true;
4678                            }
4679                        }
4680                    }
4681                    if (!allowed && (bp.protectionLevel
4682                            & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
4683                        // For development permissions, a development permission
4684                        // is granted only if it was already granted.
4685                        if (origPermissions.contains(perm)) {
4686                            allowed = true;
4687                        } else {
4688                            allowed = false;
4689                        }
4690                    }
4691                    if (allowed) {
4692                        allowedSig = true;
4693                    }
4694                } else {
4695                    allowed = false;
4696                }
4697                if (DEBUG_INSTALL) {
4698                    if (gp != ps) {
4699                        Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
4700                    }
4701                }
4702                if (allowed) {
4703                    if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
4704                            && ps.permissionsFixed) {
4705                        // If this is an existing, non-system package, then
4706                        // we can't add any new permissions to it.
4707                        if (!allowedSig && !gp.grantedPermissions.contains(perm)) {
4708                            allowed = false;
4709                            // Except...  if this is a permission that was added
4710                            // to the platform (note: need to only do this when
4711                            // updating the platform).
4712                            final int NP = PackageParser.NEW_PERMISSIONS.length;
4713                            for (int ip=0; ip<NP; ip++) {
4714                                final PackageParser.NewPermissionInfo npi
4715                                        = PackageParser.NEW_PERMISSIONS[ip];
4716                                if (npi.name.equals(perm)
4717                                        && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
4718                                    allowed = true;
4719                                    Log.i(TAG, "Auto-granting " + perm + " to old pkg "
4720                                            + pkg.packageName);
4721                                    break;
4722                                }
4723                            }
4724                        }
4725                    }
4726                    if (allowed) {
4727                        if (!gp.grantedPermissions.contains(perm)) {
4728                            changedPermission = true;
4729                            gp.grantedPermissions.add(perm);
4730                            gp.gids = appendInts(gp.gids, bp.gids);
4731                        } else if (!ps.haveGids) {
4732                            gp.gids = appendInts(gp.gids, bp.gids);
4733                        }
4734                    } else {
4735                        Slog.w(TAG, "Not granting permission " + perm
4736                                + " to package " + pkg.packageName
4737                                + " because it was previously installed without");
4738                    }
4739                } else {
4740                    if (gp.grantedPermissions.remove(perm)) {
4741                        changedPermission = true;
4742                        gp.gids = removeInts(gp.gids, bp.gids);
4743                        Slog.i(TAG, "Un-granting permission " + perm
4744                                + " from package " + pkg.packageName
4745                                + " (protectionLevel=" + bp.protectionLevel
4746                                + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
4747                                + ")");
4748                    } else {
4749                        Slog.w(TAG, "Not granting permission " + perm
4750                                + " to package " + pkg.packageName
4751                                + " (protectionLevel=" + bp.protectionLevel
4752                                + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
4753                                + ")");
4754                    }
4755                }
4756            } else {
4757                Slog.w(TAG, "Unknown permission " + name
4758                        + " in package " + pkg.packageName);
4759            }
4760        }
4761
4762        if ((changedPermission || replace) && !ps.permissionsFixed &&
4763                ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) ||
4764                ((ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0)){
4765            // This is the first that we have heard about this package, so the
4766            // permissions we have now selected are fixed until explicitly
4767            // changed.
4768            ps.permissionsFixed = true;
4769        }
4770        ps.haveGids = true;
4771    }
4772
4773    private final class ActivityIntentResolver
4774            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
4775        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
4776                boolean defaultOnly, int userId) {
4777            if (!sUserManager.exists(userId)) return null;
4778            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
4779            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
4780        }
4781
4782        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
4783                int userId) {
4784            if (!sUserManager.exists(userId)) return null;
4785            mFlags = flags;
4786            return super.queryIntent(intent, resolvedType,
4787                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
4788        }
4789
4790        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
4791                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
4792            if (!sUserManager.exists(userId)) return null;
4793            if (packageActivities == null) {
4794                return null;
4795            }
4796            mFlags = flags;
4797            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
4798            final int N = packageActivities.size();
4799            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
4800                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
4801
4802            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
4803            for (int i = 0; i < N; ++i) {
4804                intentFilters = packageActivities.get(i).intents;
4805                if (intentFilters != null && intentFilters.size() > 0) {
4806                    PackageParser.ActivityIntentInfo[] array =
4807                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
4808                    intentFilters.toArray(array);
4809                    listCut.add(array);
4810                }
4811            }
4812            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
4813        }
4814
4815        public final void addActivity(PackageParser.Activity a, String type) {
4816            final boolean systemApp = isSystemApp(a.info.applicationInfo);
4817            mActivities.put(a.getComponentName(), a);
4818            if (DEBUG_SHOW_INFO)
4819                Log.v(
4820                TAG, "  " + type + " " +
4821                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
4822            if (DEBUG_SHOW_INFO)
4823                Log.v(TAG, "    Class=" + a.info.name);
4824            final int NI = a.intents.size();
4825            for (int j=0; j<NI; j++) {
4826                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
4827                if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) {
4828                    intent.setPriority(0);
4829                    Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity "
4830                            + a.className + " with priority > 0, forcing to 0");
4831                }
4832                if (DEBUG_SHOW_INFO) {
4833                    Log.v(TAG, "    IntentFilter:");
4834                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
4835                }
4836                if (!intent.debugCheck()) {
4837                    Log.w(TAG, "==> For Activity " + a.info.name);
4838                }
4839                addFilter(intent);
4840            }
4841        }
4842
4843        public final void removeActivity(PackageParser.Activity a, String type) {
4844            mActivities.remove(a.getComponentName());
4845            if (DEBUG_SHOW_INFO) {
4846                Log.v(TAG, "  " + type + " "
4847                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
4848                                : a.info.name) + ":");
4849                Log.v(TAG, "    Class=" + a.info.name);
4850            }
4851            final int NI = a.intents.size();
4852            for (int j=0; j<NI; j++) {
4853                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
4854                if (DEBUG_SHOW_INFO) {
4855                    Log.v(TAG, "    IntentFilter:");
4856                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
4857                }
4858                removeFilter(intent);
4859            }
4860        }
4861
4862        @Override
4863        protected boolean allowFilterResult(
4864                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
4865            ActivityInfo filterAi = filter.activity.info;
4866            for (int i=dest.size()-1; i>=0; i--) {
4867                ActivityInfo destAi = dest.get(i).activityInfo;
4868                if (destAi.name == filterAi.name
4869                        && destAi.packageName == filterAi.packageName) {
4870                    return false;
4871                }
4872            }
4873            return true;
4874        }
4875
4876        @Override
4877        protected ActivityIntentInfo[] newArray(int size) {
4878            return new ActivityIntentInfo[size];
4879        }
4880
4881        @Override
4882        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
4883            if (!sUserManager.exists(userId)) return true;
4884            PackageParser.Package p = filter.activity.owner;
4885            if (p != null) {
4886                PackageSetting ps = (PackageSetting)p.mExtras;
4887                if (ps != null) {
4888                    // System apps are never considered stopped for purposes of
4889                    // filtering, because there may be no way for the user to
4890                    // actually re-launch them.
4891                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
4892                            && ps.getStopped(userId);
4893                }
4894            }
4895            return false;
4896        }
4897
4898        @Override
4899        protected String packageForFilter(PackageParser.ActivityIntentInfo info) {
4900            return info.activity.owner.packageName;
4901        }
4902
4903        @Override
4904        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
4905                int match, int userId) {
4906            if (!sUserManager.exists(userId)) return null;
4907            if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) {
4908                return null;
4909            }
4910            final PackageParser.Activity activity = info.activity;
4911            if (mSafeMode && (activity.info.applicationInfo.flags
4912                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
4913                return null;
4914            }
4915            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
4916            if (ps == null) {
4917                return null;
4918            }
4919            ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags,
4920                    ps.readUserState(userId), userId);
4921            if (ai == null) {
4922                return null;
4923            }
4924            final ResolveInfo res = new ResolveInfo();
4925            res.activityInfo = ai;
4926            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
4927                res.filter = info;
4928            }
4929            res.priority = info.getPriority();
4930            res.preferredOrder = activity.owner.mPreferredOrder;
4931            //System.out.println("Result: " + res.activityInfo.className +
4932            //                   " = " + res.priority);
4933            res.match = match;
4934            res.isDefault = info.hasDefault;
4935            res.labelRes = info.labelRes;
4936            res.nonLocalizedLabel = info.nonLocalizedLabel;
4937            res.icon = info.icon;
4938            res.system = isSystemApp(res.activityInfo.applicationInfo);
4939            return res;
4940        }
4941
4942        @Override
4943        protected void sortResults(List<ResolveInfo> results) {
4944            Collections.sort(results, mResolvePrioritySorter);
4945        }
4946
4947        @Override
4948        protected void dumpFilter(PrintWriter out, String prefix,
4949                PackageParser.ActivityIntentInfo filter) {
4950            out.print(prefix); out.print(
4951                    Integer.toHexString(System.identityHashCode(filter.activity)));
4952                    out.print(' ');
4953                    out.print(filter.activity.getComponentShortName());
4954                    out.print(" filter ");
4955                    out.println(Integer.toHexString(System.identityHashCode(filter)));
4956        }
4957
4958//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
4959//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
4960//            final List<ResolveInfo> retList = Lists.newArrayList();
4961//            while (i.hasNext()) {
4962//                final ResolveInfo resolveInfo = i.next();
4963//                if (isEnabledLP(resolveInfo.activityInfo)) {
4964//                    retList.add(resolveInfo);
4965//                }
4966//            }
4967//            return retList;
4968//        }
4969
4970        // Keys are String (activity class name), values are Activity.
4971        private final HashMap<ComponentName, PackageParser.Activity> mActivities
4972                = new HashMap<ComponentName, PackageParser.Activity>();
4973        private int mFlags;
4974    }
4975
4976    private final class ServiceIntentResolver
4977            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
4978        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
4979                boolean defaultOnly, int userId) {
4980            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
4981            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
4982        }
4983
4984        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
4985                int userId) {
4986            if (!sUserManager.exists(userId)) return null;
4987            mFlags = flags;
4988            return super.queryIntent(intent, resolvedType,
4989                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
4990        }
4991
4992        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
4993                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
4994            if (!sUserManager.exists(userId)) return null;
4995            if (packageServices == null) {
4996                return null;
4997            }
4998            mFlags = flags;
4999            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
5000            final int N = packageServices.size();
5001            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
5002                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
5003
5004            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
5005            for (int i = 0; i < N; ++i) {
5006                intentFilters = packageServices.get(i).intents;
5007                if (intentFilters != null && intentFilters.size() > 0) {
5008                    PackageParser.ServiceIntentInfo[] array =
5009                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
5010                    intentFilters.toArray(array);
5011                    listCut.add(array);
5012                }
5013            }
5014            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
5015        }
5016
5017        public final void addService(PackageParser.Service s) {
5018            mServices.put(s.getComponentName(), s);
5019            if (DEBUG_SHOW_INFO) {
5020                Log.v(TAG, "  "
5021                        + (s.info.nonLocalizedLabel != null
5022                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
5023                Log.v(TAG, "    Class=" + s.info.name);
5024            }
5025            final int NI = s.intents.size();
5026            int j;
5027            for (j=0; j<NI; j++) {
5028                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
5029                if (DEBUG_SHOW_INFO) {
5030                    Log.v(TAG, "    IntentFilter:");
5031                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
5032                }
5033                if (!intent.debugCheck()) {
5034                    Log.w(TAG, "==> For Service " + s.info.name);
5035                }
5036                addFilter(intent);
5037            }
5038        }
5039
5040        public final void removeService(PackageParser.Service s) {
5041            mServices.remove(s.getComponentName());
5042            if (DEBUG_SHOW_INFO) {
5043                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
5044                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
5045                Log.v(TAG, "    Class=" + s.info.name);
5046            }
5047            final int NI = s.intents.size();
5048            int j;
5049            for (j=0; j<NI; j++) {
5050                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
5051                if (DEBUG_SHOW_INFO) {
5052                    Log.v(TAG, "    IntentFilter:");
5053                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
5054                }
5055                removeFilter(intent);
5056            }
5057        }
5058
5059        @Override
5060        protected boolean allowFilterResult(
5061                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
5062            ServiceInfo filterSi = filter.service.info;
5063            for (int i=dest.size()-1; i>=0; i--) {
5064                ServiceInfo destAi = dest.get(i).serviceInfo;
5065                if (destAi.name == filterSi.name
5066                        && destAi.packageName == filterSi.packageName) {
5067                    return false;
5068                }
5069            }
5070            return true;
5071        }
5072
5073        @Override
5074        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
5075            return new PackageParser.ServiceIntentInfo[size];
5076        }
5077
5078        @Override
5079        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
5080            if (!sUserManager.exists(userId)) return true;
5081            PackageParser.Package p = filter.service.owner;
5082            if (p != null) {
5083                PackageSetting ps = (PackageSetting)p.mExtras;
5084                if (ps != null) {
5085                    // System apps are never considered stopped for purposes of
5086                    // filtering, because there may be no way for the user to
5087                    // actually re-launch them.
5088                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
5089                            && ps.getStopped(userId);
5090                }
5091            }
5092            return false;
5093        }
5094
5095        @Override
5096        protected String packageForFilter(PackageParser.ServiceIntentInfo info) {
5097            return info.service.owner.packageName;
5098        }
5099
5100        @Override
5101        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
5102                int match, int userId) {
5103            if (!sUserManager.exists(userId)) return null;
5104            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
5105            if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) {
5106                return null;
5107            }
5108            final PackageParser.Service service = info.service;
5109            if (mSafeMode && (service.info.applicationInfo.flags
5110                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
5111                return null;
5112            }
5113            PackageSetting ps = (PackageSetting) service.owner.mExtras;
5114            if (ps == null) {
5115                return null;
5116            }
5117            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
5118                    ps.readUserState(userId), userId);
5119            if (si == null) {
5120                return null;
5121            }
5122            final ResolveInfo res = new ResolveInfo();
5123            res.serviceInfo = si;
5124            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
5125                res.filter = filter;
5126            }
5127            res.priority = info.getPriority();
5128            res.preferredOrder = service.owner.mPreferredOrder;
5129            //System.out.println("Result: " + res.activityInfo.className +
5130            //                   " = " + res.priority);
5131            res.match = match;
5132            res.isDefault = info.hasDefault;
5133            res.labelRes = info.labelRes;
5134            res.nonLocalizedLabel = info.nonLocalizedLabel;
5135            res.icon = info.icon;
5136            res.system = isSystemApp(res.serviceInfo.applicationInfo);
5137            return res;
5138        }
5139
5140        @Override
5141        protected void sortResults(List<ResolveInfo> results) {
5142            Collections.sort(results, mResolvePrioritySorter);
5143        }
5144
5145        @Override
5146        protected void dumpFilter(PrintWriter out, String prefix,
5147                PackageParser.ServiceIntentInfo filter) {
5148            out.print(prefix); out.print(
5149                    Integer.toHexString(System.identityHashCode(filter.service)));
5150                    out.print(' ');
5151                    out.print(filter.service.getComponentShortName());
5152                    out.print(" filter ");
5153                    out.println(Integer.toHexString(System.identityHashCode(filter)));
5154        }
5155
5156//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
5157//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
5158//            final List<ResolveInfo> retList = Lists.newArrayList();
5159//            while (i.hasNext()) {
5160//                final ResolveInfo resolveInfo = (ResolveInfo) i;
5161//                if (isEnabledLP(resolveInfo.serviceInfo)) {
5162//                    retList.add(resolveInfo);
5163//                }
5164//            }
5165//            return retList;
5166//        }
5167
5168        // Keys are String (activity class name), values are Activity.
5169        private final HashMap<ComponentName, PackageParser.Service> mServices
5170                = new HashMap<ComponentName, PackageParser.Service>();
5171        private int mFlags;
5172    };
5173
5174    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
5175            new Comparator<ResolveInfo>() {
5176        public int compare(ResolveInfo r1, ResolveInfo r2) {
5177            int v1 = r1.priority;
5178            int v2 = r2.priority;
5179            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
5180            if (v1 != v2) {
5181                return (v1 > v2) ? -1 : 1;
5182            }
5183            v1 = r1.preferredOrder;
5184            v2 = r2.preferredOrder;
5185            if (v1 != v2) {
5186                return (v1 > v2) ? -1 : 1;
5187            }
5188            if (r1.isDefault != r2.isDefault) {
5189                return r1.isDefault ? -1 : 1;
5190            }
5191            v1 = r1.match;
5192            v2 = r2.match;
5193            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
5194            if (v1 != v2) {
5195                return (v1 > v2) ? -1 : 1;
5196            }
5197            if (r1.system != r2.system) {
5198                return r1.system ? -1 : 1;
5199            }
5200            return 0;
5201        }
5202    };
5203
5204    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
5205            new Comparator<ProviderInfo>() {
5206        public int compare(ProviderInfo p1, ProviderInfo p2) {
5207            final int v1 = p1.initOrder;
5208            final int v2 = p2.initOrder;
5209            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
5210        }
5211    };
5212
5213    static final void sendPackageBroadcast(String action, String pkg,
5214            Bundle extras, String targetPkg, IIntentReceiver finishedReceiver,
5215            int[] userIds) {
5216        IActivityManager am = ActivityManagerNative.getDefault();
5217        if (am != null) {
5218            try {
5219                if (userIds == null) {
5220                    userIds = sUserManager.getUserIds();
5221                }
5222                for (int id : userIds) {
5223                    final Intent intent = new Intent(action,
5224                            pkg != null ? Uri.fromParts("package", pkg, null) : null);
5225                    if (extras != null) {
5226                        intent.putExtras(extras);
5227                    }
5228                    if (targetPkg != null) {
5229                        intent.setPackage(targetPkg);
5230                    }
5231                    // Modify the UID when posting to other users
5232                    int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
5233                    if (uid > 0 && UserHandle.getUserId(uid) != id) {
5234                        uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
5235                        intent.putExtra(Intent.EXTRA_UID, uid);
5236                    }
5237                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
5238                    if (DEBUG_BROADCASTS) {
5239                        RuntimeException here = new RuntimeException("here");
5240                        here.fillInStackTrace();
5241                        Slog.d(TAG, "Sending to user " + id + ": "
5242                                + intent.toShortString(false, true, false, false)
5243                                + " " + intent.getExtras(), here);
5244                    }
5245                    am.broadcastIntent(null, intent, null, finishedReceiver,
5246                            0, null, null, null, finishedReceiver != null, false, id);
5247                }
5248            } catch (RemoteException ex) {
5249            }
5250        }
5251    }
5252
5253    /**
5254     * Check if the external storage media is available. This is true if there
5255     * is a mounted external storage medium or if the external storage is
5256     * emulated.
5257     */
5258    private boolean isExternalMediaAvailable() {
5259        return mMediaMounted || Environment.isExternalStorageEmulated();
5260    }
5261
5262    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
5263        // writer
5264        final int userId = UserHandle.getCallingUserId();
5265        synchronized (mPackages) {
5266            if (!isExternalMediaAvailable()) {
5267                // If the external storage is no longer mounted at this point,
5268                // the caller may not have been able to delete all of this
5269                // packages files and can not delete any more.  Bail.
5270                return null;
5271            }
5272            ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned.get(userId);
5273            if (pkgs != null) {
5274                if (lastPackage != null) {
5275                    pkgs.remove(lastPackage);
5276                }
5277                if (pkgs.size() > 0) {
5278                    return pkgs.get(0);
5279                }
5280            }
5281        }
5282        // Move on to the next user to clean.
5283        long ident = Binder.clearCallingIdentity();
5284        try {
5285            startCleaningPackages(userId);
5286        } finally {
5287            Binder.restoreCallingIdentity(ident);
5288        }
5289        return null;
5290    }
5291
5292    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
5293        if (false) {
5294            RuntimeException here = new RuntimeException("here");
5295            here.fillInStackTrace();
5296            Slog.d(TAG, "Schedule cleaning " + packageName + " user=" + userId
5297                    + " andCode=" + andCode, here);
5298        }
5299        mHandler.sendMessage(mHandler.obtainMessage(START_CLEANING_PACKAGE,
5300                userId, andCode ? 1 : 0, packageName));
5301    }
5302
5303    void startCleaningPackages(int lastUser) {
5304        // reader
5305        int nextUser = -1;
5306        synchronized (mPackages) {
5307            if (!isExternalMediaAvailable()) {
5308                return;
5309            }
5310            final int N = mSettings.mPackagesToBeCleaned.size();
5311            if (N <= 0) {
5312                return;
5313            }
5314            for (int i=0; i<N; i++) {
5315                int user = mSettings.mPackagesToBeCleaned.keyAt(i);
5316                if (user > lastUser) {
5317                    nextUser = user;
5318                    break;
5319                }
5320            }
5321            if (nextUser < 0) {
5322                nextUser = mSettings.mPackagesToBeCleaned.keyAt(0);
5323            }
5324        }
5325        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
5326        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
5327        IActivityManager am = ActivityManagerNative.getDefault();
5328        if (am != null) {
5329            try {
5330                am.startService(null, intent, null, nextUser);
5331            } catch (RemoteException e) {
5332            }
5333        }
5334    }
5335
5336    private final class AppDirObserver extends FileObserver {
5337        public AppDirObserver(String path, int mask, boolean isrom) {
5338            super(path, mask);
5339            mRootDir = path;
5340            mIsRom = isrom;
5341        }
5342
5343        public void onEvent(int event, String path) {
5344            String removedPackage = null;
5345            int removedUid = -1;
5346            String addedPackage = null;
5347            int addedUid = -1;
5348
5349            // TODO post a message to the handler to obtain serial ordering
5350            synchronized (mInstallLock) {
5351                String fullPathStr = null;
5352                File fullPath = null;
5353                if (path != null) {
5354                    fullPath = new File(mRootDir, path);
5355                    fullPathStr = fullPath.getPath();
5356                }
5357
5358                if (DEBUG_APP_DIR_OBSERVER)
5359                    Log.v(TAG, "File " + fullPathStr + " changed: " + Integer.toHexString(event));
5360
5361                if (!isPackageFilename(path)) {
5362                    if (DEBUG_APP_DIR_OBSERVER)
5363                        Log.v(TAG, "Ignoring change of non-package file: " + fullPathStr);
5364                    return;
5365                }
5366
5367                // Ignore packages that are being installed or
5368                // have just been installed.
5369                if (ignoreCodePath(fullPathStr)) {
5370                    return;
5371                }
5372                PackageParser.Package p = null;
5373                // reader
5374                synchronized (mPackages) {
5375                    p = mAppDirs.get(fullPathStr);
5376                }
5377                if ((event&REMOVE_EVENTS) != 0) {
5378                    if (p != null) {
5379                        removePackageLI(p, true);
5380                        removedPackage = p.applicationInfo.packageName;
5381                        removedUid = p.applicationInfo.uid;
5382                    }
5383                }
5384
5385                if ((event&ADD_EVENTS) != 0) {
5386                    if (p == null) {
5387                        p = scanPackageLI(fullPath,
5388                                (mIsRom ? PackageParser.PARSE_IS_SYSTEM
5389                                        | PackageParser.PARSE_IS_SYSTEM_DIR: 0) |
5390                                PackageParser.PARSE_CHATTY |
5391                                PackageParser.PARSE_MUST_BE_APK,
5392                                SCAN_MONITOR | SCAN_NO_PATHS | SCAN_UPDATE_TIME,
5393                                System.currentTimeMillis(), null);
5394                        if (p != null) {
5395                            /*
5396                             * TODO this seems dangerous as the package may have
5397                             * changed since we last acquired the mPackages
5398                             * lock.
5399                             */
5400                            // writer
5401                            synchronized (mPackages) {
5402                                updatePermissionsLPw(p.packageName, p,
5403                                        p.permissions.size() > 0 ? UPDATE_PERMISSIONS_ALL : 0);
5404                            }
5405                            addedPackage = p.applicationInfo.packageName;
5406                            addedUid = p.applicationInfo.uid;
5407                        }
5408                    }
5409                }
5410
5411                // reader
5412                synchronized (mPackages) {
5413                    mSettings.writeLPr();
5414                }
5415            }
5416
5417            if (removedPackage != null) {
5418                Bundle extras = new Bundle(1);
5419                extras.putInt(Intent.EXTRA_UID, removedUid);
5420                extras.putBoolean(Intent.EXTRA_DATA_REMOVED, false);
5421                sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
5422                        extras, null, null, null);
5423            }
5424            if (addedPackage != null) {
5425                Bundle extras = new Bundle(1);
5426                extras.putInt(Intent.EXTRA_UID, addedUid);
5427                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, addedPackage,
5428                        extras, null, null, null);
5429            }
5430        }
5431
5432        private final String mRootDir;
5433        private final boolean mIsRom;
5434    }
5435
5436    /* Called when a downloaded package installation has been confirmed by the user */
5437    public void installPackage(
5438            final Uri packageURI, final IPackageInstallObserver observer, final int flags) {
5439        installPackage(packageURI, observer, flags, null);
5440    }
5441
5442    /* Called when a downloaded package installation has been confirmed by the user */
5443    public void installPackage(
5444            final Uri packageURI, final IPackageInstallObserver observer, final int flags,
5445            final String installerPackageName) {
5446        installPackageWithVerification(packageURI, observer, flags, installerPackageName, null,
5447                null, null);
5448    }
5449
5450    @Override
5451    public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
5452            int flags, String installerPackageName, Uri verificationURI,
5453            ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
5454        VerificationParams verificationParams = new VerificationParams(verificationURI, null, null,
5455                manifestDigest);
5456        installPackageWithVerificationAndEncryption(packageURI, observer, flags,
5457                installerPackageName, verificationParams, encryptionParams);
5458    }
5459
5460    public void installPackageWithVerificationAndEncryption(Uri packageURI,
5461            IPackageInstallObserver observer, int flags, String installerPackageName,
5462            VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
5463        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
5464                null);
5465
5466        final int uid = Binder.getCallingUid();
5467        UserHandle user;
5468        if ((flags&PackageManager.INSTALL_ALL_USERS) != 0) {
5469            user = UserHandle.ALL;
5470        } else {
5471            user = Process.myUserHandle();
5472        }
5473
5474        final int filteredFlags;
5475
5476        if (uid == Process.SHELL_UID || uid == 0) {
5477            if (DEBUG_INSTALL) {
5478                Slog.v(TAG, "Install from ADB");
5479            }
5480            filteredFlags = flags | PackageManager.INSTALL_FROM_ADB;
5481        } else {
5482            filteredFlags = flags & ~PackageManager.INSTALL_FROM_ADB;
5483        }
5484
5485        final Message msg = mHandler.obtainMessage(INIT_COPY);
5486        msg.obj = new InstallParams(packageURI, observer, filteredFlags, installerPackageName,
5487                verificationParams, encryptionParams, user);
5488        mHandler.sendMessage(msg);
5489    }
5490
5491    /**
5492     * @hide
5493     */
5494    @Override
5495    public int installExistingPackage(String packageName) {
5496        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
5497                null);
5498        PackageSetting pkgSetting;
5499        final int uid = Binder.getCallingUid();
5500        final int userId = UserHandle.getUserId(uid);
5501
5502        long callingId = Binder.clearCallingIdentity();
5503        try {
5504            boolean sendAdded = false;
5505            Bundle extras = new Bundle(1);
5506
5507            // writer
5508            synchronized (mPackages) {
5509                pkgSetting = mSettings.mPackages.get(packageName);
5510                if (pkgSetting == null) {
5511                    return PackageManager.INSTALL_FAILED_INVALID_URI;
5512                }
5513                if (!pkgSetting.getInstalled(userId)) {
5514                    pkgSetting.setInstalled(true, userId);
5515                    mSettings.writePackageRestrictionsLPr(userId);
5516                    extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId));
5517                    sendAdded = true;
5518                }
5519            }
5520
5521            if (sendAdded) {
5522                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
5523                        packageName, extras, null, null, new int[] {userId});
5524            }
5525        } finally {
5526            Binder.restoreCallingIdentity(callingId);
5527        }
5528
5529        return PackageManager.INSTALL_SUCCEEDED;
5530    }
5531
5532    @Override
5533    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
5534        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
5535        final PackageVerificationResponse response = new PackageVerificationResponse(
5536                verificationCode, Binder.getCallingUid());
5537        msg.arg1 = id;
5538        msg.obj = response;
5539        mHandler.sendMessage(msg);
5540    }
5541
5542    @Override
5543    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
5544            long millisecondsToDelay) {
5545        final PackageVerificationState state = mPendingVerification.get(id);
5546        final PackageVerificationResponse response = new PackageVerificationResponse(
5547                verificationCodeAtTimeout, Binder.getCallingUid());
5548
5549        if ((millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT)
5550                || (millisecondsToDelay < 0)) {
5551            throw new IllegalArgumentException("millisecondsToDelay is out of bounds.");
5552        }
5553        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
5554              || (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
5555            throw new IllegalArgumentException("verificationCodeAtTimeout is unknown.");
5556        }
5557
5558        if ((state != null) && !state.timeoutExtended()) {
5559            state.extendTimeout();
5560
5561            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
5562            msg.arg1 = id;
5563            msg.obj = response;
5564            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
5565        }
5566    }
5567
5568    private ComponentName matchComponentForVerifier(String packageName,
5569            List<ResolveInfo> receivers) {
5570        ActivityInfo targetReceiver = null;
5571
5572        final int NR = receivers.size();
5573        for (int i = 0; i < NR; i++) {
5574            final ResolveInfo info = receivers.get(i);
5575            if (info.activityInfo == null) {
5576                continue;
5577            }
5578
5579            if (packageName.equals(info.activityInfo.packageName)) {
5580                targetReceiver = info.activityInfo;
5581                break;
5582            }
5583        }
5584
5585        if (targetReceiver == null) {
5586            return null;
5587        }
5588
5589        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
5590    }
5591
5592    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
5593            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
5594        if (pkgInfo.verifiers.length == 0) {
5595            return null;
5596        }
5597
5598        final int N = pkgInfo.verifiers.length;
5599        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
5600        for (int i = 0; i < N; i++) {
5601            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
5602
5603            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
5604                    receivers);
5605            if (comp == null) {
5606                continue;
5607            }
5608
5609            final int verifierUid = getUidForVerifier(verifierInfo);
5610            if (verifierUid == -1) {
5611                continue;
5612            }
5613
5614            if (DEBUG_VERIFY) {
5615                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
5616                        + " with the correct signature");
5617            }
5618            sufficientVerifiers.add(comp);
5619            verificationState.addSufficientVerifier(verifierUid);
5620        }
5621
5622        return sufficientVerifiers;
5623    }
5624
5625    private int getUidForVerifier(VerifierInfo verifierInfo) {
5626        synchronized (mPackages) {
5627            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
5628            if (pkg == null) {
5629                return -1;
5630            } else if (pkg.mSignatures.length != 1) {
5631                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
5632                        + " has more than one signature; ignoring");
5633                return -1;
5634            }
5635
5636            /*
5637             * If the public key of the package's signature does not match
5638             * our expected public key, then this is a different package and
5639             * we should skip.
5640             */
5641
5642            final byte[] expectedPublicKey;
5643            try {
5644                final Signature verifierSig = pkg.mSignatures[0];
5645                final PublicKey publicKey = verifierSig.getPublicKey();
5646                expectedPublicKey = publicKey.getEncoded();
5647            } catch (CertificateException e) {
5648                return -1;
5649            }
5650
5651            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
5652
5653            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
5654                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
5655                        + " does not have the expected public key; ignoring");
5656                return -1;
5657            }
5658
5659            return pkg.applicationInfo.uid;
5660        }
5661    }
5662
5663    public void finishPackageInstall(int token) {
5664        enforceSystemOrRoot("Only the system is allowed to finish installs");
5665
5666        if (DEBUG_INSTALL) {
5667            Slog.v(TAG, "BM finishing package install for " + token);
5668        }
5669
5670        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
5671        mHandler.sendMessage(msg);
5672    }
5673
5674    /**
5675     * Get the verification agent timeout.
5676     *
5677     * @return verification timeout in milliseconds
5678     */
5679    private long getVerificationTimeout() {
5680        return android.provider.Settings.Secure.getLong(mContext.getContentResolver(),
5681                android.provider.Settings.Secure.PACKAGE_VERIFIER_TIMEOUT,
5682                DEFAULT_VERIFICATION_TIMEOUT);
5683    }
5684
5685    /**
5686     * Get the default verification agent response code.
5687     *
5688     * @return default verification response code
5689     */
5690    private int getDefaultVerificationResponse() {
5691        return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
5692                android.provider.Settings.Secure.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
5693                DEFAULT_VERIFICATION_RESPONSE);
5694    }
5695
5696    /**
5697     * Check whether or not package verification has been enabled.
5698     *
5699     * @return true if verification should be performed
5700     */
5701    private boolean isVerificationEnabled() {
5702        return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
5703                android.provider.Settings.Secure.PACKAGE_VERIFIER_ENABLE,
5704                DEFAULT_VERIFY_ENABLE ? 1 : 0) == 1 ? true : false;
5705    }
5706
5707    /**
5708     * Get the "allow unknown sources" setting.
5709     *
5710     * @return the current "allow unknown sources" setting
5711     */
5712    private int getUnknownSourcesSettings() {
5713        return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
5714                android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
5715                -1);
5716    }
5717
5718    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
5719        final int uid = Binder.getCallingUid();
5720        // writer
5721        synchronized (mPackages) {
5722            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
5723            if (targetPackageSetting == null) {
5724                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
5725            }
5726
5727            PackageSetting installerPackageSetting;
5728            if (installerPackageName != null) {
5729                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
5730                if (installerPackageSetting == null) {
5731                    throw new IllegalArgumentException("Unknown installer package: "
5732                            + installerPackageName);
5733                }
5734            } else {
5735                installerPackageSetting = null;
5736            }
5737
5738            Signature[] callerSignature;
5739            Object obj = mSettings.getUserIdLPr(uid);
5740            if (obj != null) {
5741                if (obj instanceof SharedUserSetting) {
5742                    callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
5743                } else if (obj instanceof PackageSetting) {
5744                    callerSignature = ((PackageSetting)obj).signatures.mSignatures;
5745                } else {
5746                    throw new SecurityException("Bad object " + obj + " for uid " + uid);
5747                }
5748            } else {
5749                throw new SecurityException("Unknown calling uid " + uid);
5750            }
5751
5752            // Verify: can't set installerPackageName to a package that is
5753            // not signed with the same cert as the caller.
5754            if (installerPackageSetting != null) {
5755                if (compareSignatures(callerSignature,
5756                        installerPackageSetting.signatures.mSignatures)
5757                        != PackageManager.SIGNATURE_MATCH) {
5758                    throw new SecurityException(
5759                            "Caller does not have same cert as new installer package "
5760                            + installerPackageName);
5761                }
5762            }
5763
5764            // Verify: if target already has an installer package, it must
5765            // be signed with the same cert as the caller.
5766            if (targetPackageSetting.installerPackageName != null) {
5767                PackageSetting setting = mSettings.mPackages.get(
5768                        targetPackageSetting.installerPackageName);
5769                // If the currently set package isn't valid, then it's always
5770                // okay to change it.
5771                if (setting != null) {
5772                    if (compareSignatures(callerSignature,
5773                            setting.signatures.mSignatures)
5774                            != PackageManager.SIGNATURE_MATCH) {
5775                        throw new SecurityException(
5776                                "Caller does not have same cert as old installer package "
5777                                + targetPackageSetting.installerPackageName);
5778                    }
5779                }
5780            }
5781
5782            // Okay!
5783            targetPackageSetting.installerPackageName = installerPackageName;
5784            scheduleWriteSettingsLocked();
5785        }
5786    }
5787
5788    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
5789        // Queue up an async operation since the package installation may take a little while.
5790        mHandler.post(new Runnable() {
5791            public void run() {
5792                mHandler.removeCallbacks(this);
5793                 // Result object to be returned
5794                PackageInstalledInfo res = new PackageInstalledInfo();
5795                res.returnCode = currentStatus;
5796                res.uid = -1;
5797                res.pkg = null;
5798                res.removedInfo = new PackageRemovedInfo();
5799                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
5800                    args.doPreInstall(res.returnCode);
5801                    synchronized (mInstallLock) {
5802                        installPackageLI(args, true, res);
5803                    }
5804                    args.doPostInstall(res.returnCode, res.uid);
5805                }
5806
5807                // A restore should be performed at this point if (a) the install
5808                // succeeded, (b) the operation is not an update, and (c) the new
5809                // package has a backupAgent defined.
5810                final boolean update = res.removedInfo.removedPackage != null;
5811                boolean doRestore = (!update
5812                        && res.pkg != null
5813                        && res.pkg.applicationInfo.backupAgentName != null);
5814
5815                // Set up the post-install work request bookkeeping.  This will be used
5816                // and cleaned up by the post-install event handling regardless of whether
5817                // there's a restore pass performed.  Token values are >= 1.
5818                int token;
5819                if (mNextInstallToken < 0) mNextInstallToken = 1;
5820                token = mNextInstallToken++;
5821
5822                PostInstallData data = new PostInstallData(args, res);
5823                mRunningInstalls.put(token, data);
5824                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
5825
5826                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
5827                    // Pass responsibility to the Backup Manager.  It will perform a
5828                    // restore if appropriate, then pass responsibility back to the
5829                    // Package Manager to run the post-install observer callbacks
5830                    // and broadcasts.
5831                    IBackupManager bm = IBackupManager.Stub.asInterface(
5832                            ServiceManager.getService(Context.BACKUP_SERVICE));
5833                    if (bm != null) {
5834                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
5835                                + " to BM for possible restore");
5836                        try {
5837                            bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
5838                        } catch (RemoteException e) {
5839                            // can't happen; the backup manager is local
5840                        } catch (Exception e) {
5841                            Slog.e(TAG, "Exception trying to enqueue restore", e);
5842                            doRestore = false;
5843                        }
5844                    } else {
5845                        Slog.e(TAG, "Backup Manager not found!");
5846                        doRestore = false;
5847                    }
5848                }
5849
5850                if (!doRestore) {
5851                    // No restore possible, or the Backup Manager was mysteriously not
5852                    // available -- just fire the post-install work request directly.
5853                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
5854                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
5855                    mHandler.sendMessage(msg);
5856                }
5857            }
5858        });
5859    }
5860
5861    private abstract class HandlerParams {
5862        private static final int MAX_RETRIES = 4;
5863
5864        /**
5865         * Number of times startCopy() has been attempted and had a non-fatal
5866         * error.
5867         */
5868        private int mRetries = 0;
5869
5870        /** User handle for the user requesting the information or installation. */
5871        private final UserHandle mUser;
5872
5873        HandlerParams(UserHandle user) {
5874            mUser = user;
5875        }
5876
5877        UserHandle getUser() {
5878            return mUser;
5879        }
5880
5881        final boolean startCopy() {
5882            boolean res;
5883            try {
5884                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy");
5885
5886                if (++mRetries > MAX_RETRIES) {
5887                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
5888                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
5889                    handleServiceError();
5890                    return false;
5891                } else {
5892                    handleStartCopy();
5893                    res = true;
5894                }
5895            } catch (RemoteException e) {
5896                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
5897                mHandler.sendEmptyMessage(MCS_RECONNECT);
5898                res = false;
5899            }
5900            handleReturnCode();
5901            return res;
5902        }
5903
5904        final void serviceError() {
5905            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
5906            handleServiceError();
5907            handleReturnCode();
5908        }
5909
5910        abstract void handleStartCopy() throws RemoteException;
5911        abstract void handleServiceError();
5912        abstract void handleReturnCode();
5913    }
5914
5915    class MeasureParams extends HandlerParams {
5916        private final PackageStats mStats;
5917        private boolean mSuccess;
5918
5919        private final IPackageStatsObserver mObserver;
5920
5921        public MeasureParams(PackageStats stats, IPackageStatsObserver observer) {
5922            super(new UserHandle(stats.userHandle));
5923            mObserver = observer;
5924            mStats = stats;
5925        }
5926
5927        @Override
5928        void handleStartCopy() throws RemoteException {
5929            synchronized (mInstallLock) {
5930                mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats);
5931            }
5932
5933            final boolean mounted;
5934            if (Environment.isExternalStorageEmulated()) {
5935                mounted = true;
5936            } else {
5937                final String status = Environment.getExternalStorageState();
5938
5939                mounted = status.equals(Environment.MEDIA_MOUNTED)
5940                        || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
5941            }
5942
5943            if (mounted) {
5944                final File externalCacheDir = Environment
5945                        .getExternalStorageAppCacheDirectory(mStats.packageName);
5946                final long externalCacheSize = mContainerService
5947                        .calculateDirectorySize(externalCacheDir.getPath());
5948                mStats.externalCacheSize = externalCacheSize;
5949
5950                final File externalDataDir = Environment
5951                        .getExternalStorageAppDataDirectory(mStats.packageName);
5952                long externalDataSize = mContainerService.calculateDirectorySize(externalDataDir
5953                        .getPath());
5954
5955                if (externalCacheDir.getParentFile().equals(externalDataDir)) {
5956                    externalDataSize -= externalCacheSize;
5957                }
5958                mStats.externalDataSize = externalDataSize;
5959
5960                final File externalMediaDir = Environment
5961                        .getExternalStorageAppMediaDirectory(mStats.packageName);
5962                mStats.externalMediaSize = mContainerService
5963                        .calculateDirectorySize(externalMediaDir.getPath());
5964
5965                final File externalObbDir = Environment
5966                        .getExternalStorageAppObbDirectory(mStats.packageName);
5967                mStats.externalObbSize = mContainerService.calculateDirectorySize(externalObbDir
5968                        .getPath());
5969            }
5970        }
5971
5972        @Override
5973        void handleReturnCode() {
5974            if (mObserver != null) {
5975                try {
5976                    mObserver.onGetStatsCompleted(mStats, mSuccess);
5977                } catch (RemoteException e) {
5978                    Slog.i(TAG, "Observer no longer exists.");
5979                }
5980            }
5981        }
5982
5983        @Override
5984        void handleServiceError() {
5985            Slog.e(TAG, "Could not measure application " + mStats.packageName
5986                            + " external storage");
5987        }
5988    }
5989
5990    class InstallParams extends HandlerParams {
5991        final IPackageInstallObserver observer;
5992        int flags;
5993
5994        private final Uri mPackageURI;
5995        final String installerPackageName;
5996        final VerificationParams verificationParams;
5997        private InstallArgs mArgs;
5998        private int mRet;
5999        private File mTempPackage;
6000        final ContainerEncryptionParams encryptionParams;
6001
6002        InstallParams(Uri packageURI,
6003                IPackageInstallObserver observer, int flags,
6004                String installerPackageName, VerificationParams verificationParams,
6005                ContainerEncryptionParams encryptionParams, UserHandle user) {
6006            super(user);
6007            this.mPackageURI = packageURI;
6008            this.flags = flags;
6009            this.observer = observer;
6010            this.installerPackageName = installerPackageName;
6011            this.verificationParams = verificationParams;
6012            this.encryptionParams = encryptionParams;
6013        }
6014
6015        public ManifestDigest getManifestDigest() {
6016            if (verificationParams == null) {
6017                return null;
6018            }
6019            return verificationParams.getManifestDigest();
6020        }
6021
6022        private int installLocationPolicy(PackageInfoLite pkgLite, int flags) {
6023            String packageName = pkgLite.packageName;
6024            int installLocation = pkgLite.installLocation;
6025            boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0;
6026            // reader
6027            synchronized (mPackages) {
6028                PackageParser.Package pkg = mPackages.get(packageName);
6029                if (pkg != null) {
6030                    if ((flags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
6031                        // Check for downgrading.
6032                        if ((flags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0) {
6033                            if (pkgLite.versionCode < pkg.mVersionCode) {
6034                                Slog.w(TAG, "Can't install update of " + packageName
6035                                        + " update version " + pkgLite.versionCode
6036                                        + " is older than installed version "
6037                                        + pkg.mVersionCode);
6038                                return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
6039                            }
6040                        }
6041                        // Check for updated system application.
6042                        if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
6043                            if (onSd) {
6044                                Slog.w(TAG, "Cannot install update to system app on sdcard");
6045                                return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
6046                            }
6047                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
6048                        } else {
6049                            if (onSd) {
6050                                // Install flag overrides everything.
6051                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
6052                            }
6053                            // If current upgrade specifies particular preference
6054                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
6055                                // Application explicitly specified internal.
6056                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
6057                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
6058                                // App explictly prefers external. Let policy decide
6059                            } else {
6060                                // Prefer previous location
6061                                if (isExternal(pkg)) {
6062                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
6063                                }
6064                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
6065                            }
6066                        }
6067                    } else {
6068                        // Invalid install. Return error code
6069                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
6070                    }
6071                }
6072            }
6073            // All the special cases have been taken care of.
6074            // Return result based on recommended install location.
6075            if (onSd) {
6076                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
6077            }
6078            return pkgLite.recommendedInstallLocation;
6079        }
6080
6081        /*
6082         * Invoke remote method to get package information and install
6083         * location values. Override install location based on default
6084         * policy if needed and then create install arguments based
6085         * on the install location.
6086         */
6087        public void handleStartCopy() throws RemoteException {
6088            int ret = PackageManager.INSTALL_SUCCEEDED;
6089            final boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0;
6090            final boolean onInt = (flags & PackageManager.INSTALL_INTERNAL) != 0;
6091            PackageInfoLite pkgLite = null;
6092
6093            if (onInt && onSd) {
6094                // Check if both bits are set.
6095                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
6096                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
6097            } else {
6098                final long lowThreshold;
6099
6100                final DeviceStorageMonitorService dsm = (DeviceStorageMonitorService) ServiceManager
6101                        .getService(DeviceStorageMonitorService.SERVICE);
6102                if (dsm == null) {
6103                    Log.w(TAG, "Couldn't get low memory threshold; no free limit imposed");
6104                    lowThreshold = 0L;
6105                } else {
6106                    lowThreshold = dsm.getMemoryLowThreshold();
6107                }
6108
6109                try {
6110                    mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, mPackageURI,
6111                            Intent.FLAG_GRANT_READ_URI_PERMISSION);
6112
6113                    final File packageFile;
6114                    if (encryptionParams != null || !"file".equals(mPackageURI.getScheme())) {
6115                        ParcelFileDescriptor out = null;
6116
6117                        mTempPackage = createTempPackageFile(mDrmAppPrivateInstallDir);
6118                        if (mTempPackage != null) {
6119                            try {
6120                                out = ParcelFileDescriptor.open(mTempPackage,
6121                                        ParcelFileDescriptor.MODE_READ_WRITE);
6122                            } catch (FileNotFoundException e) {
6123                                Slog.e(TAG, "Failed to create temporary file for : " + mPackageURI);
6124                            }
6125
6126                            // Make a temporary file for decryption.
6127                            ret = mContainerService
6128                                    .copyResource(mPackageURI, encryptionParams, out);
6129
6130                            packageFile = mTempPackage;
6131
6132                            FileUtils.setPermissions(packageFile.getAbsolutePath(),
6133                                    FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IROTH,
6134                                    -1, -1);
6135                        } else {
6136                            packageFile = null;
6137                        }
6138                    } else {
6139                        packageFile = new File(mPackageURI.getPath());
6140                    }
6141
6142                    if (packageFile != null) {
6143                        // Remote call to find out default install location
6144                        pkgLite = mContainerService.getMinimalPackageInfo(
6145                                packageFile.getAbsolutePath(), flags, lowThreshold);
6146                    }
6147                } finally {
6148                    mContext.revokeUriPermission(mPackageURI,
6149                            Intent.FLAG_GRANT_READ_URI_PERMISSION);
6150                }
6151            }
6152
6153            if (ret == PackageManager.INSTALL_SUCCEEDED) {
6154                int loc = pkgLite.recommendedInstallLocation;
6155                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
6156                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
6157                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
6158                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
6159                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
6160                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
6161                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
6162                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
6163                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
6164                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
6165                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
6166                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
6167                } else if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
6168                    ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
6169                } else {
6170                    // Override with defaults if needed.
6171                    loc = installLocationPolicy(pkgLite, flags);
6172                    if (!onSd && !onInt) {
6173                        // Override install location with flags
6174                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
6175                            // Set the flag to install on external media.
6176                            flags |= PackageManager.INSTALL_EXTERNAL;
6177                            flags &= ~PackageManager.INSTALL_INTERNAL;
6178                        } else {
6179                            // Make sure the flag for installing on external
6180                            // media is unset
6181                            flags |= PackageManager.INSTALL_INTERNAL;
6182                            flags &= ~PackageManager.INSTALL_EXTERNAL;
6183                        }
6184                    }
6185                }
6186            }
6187
6188            final InstallArgs args = createInstallArgs(this);
6189            mArgs = args;
6190
6191            if (ret == PackageManager.INSTALL_SUCCEEDED) {
6192                /*
6193                 * Determine if we have any installed package verifiers. If we
6194                 * do, then we'll defer to them to verify the packages.
6195                 */
6196                final int requiredUid = mRequiredVerifierPackage == null ? -1
6197                        : getPackageUid(mRequiredVerifierPackage, 0);
6198                if (requiredUid != -1 && isVerificationEnabled()) {
6199                    final Intent verification = new Intent(
6200                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
6201                    verification.setDataAndType(getPackageUri(), PACKAGE_MIME_TYPE);
6202                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
6203
6204                    final List<ResolveInfo> receivers = queryIntentReceivers(verification, null,
6205                            PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */);
6206
6207                    if (DEBUG_VERIFY) {
6208                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
6209                                + verification.toString() + " with " + pkgLite.verifiers.length
6210                                + " optional verifiers");
6211                    }
6212
6213                    final int verificationId = mPendingVerificationToken++;
6214
6215                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
6216
6217                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
6218                            installerPackageName);
6219
6220                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, flags);
6221
6222                    if (verificationParams != null) {
6223                        if (verificationParams.getVerificationURI() != null) {
6224                           verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI,
6225                                 verificationParams.getVerificationURI());
6226                        }
6227                        if (verificationParams.getOriginatingURI() != null) {
6228                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
6229                                  verificationParams.getOriginatingURI());
6230                        }
6231                        if (verificationParams.getReferrer() != null) {
6232                            verification.putExtra(Intent.EXTRA_REFERRER,
6233                                  verificationParams.getReferrer());
6234                        }
6235                    }
6236
6237                    final PackageVerificationState verificationState = new PackageVerificationState(
6238                            requiredUid, args);
6239
6240                    mPendingVerification.append(verificationId, verificationState);
6241
6242                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
6243                            receivers, verificationState);
6244
6245                    /*
6246                     * If any sufficient verifiers were listed in the package
6247                     * manifest, attempt to ask them.
6248                     */
6249                    if (sufficientVerifiers != null) {
6250                        final int N = sufficientVerifiers.size();
6251                        if (N == 0) {
6252                            Slog.i(TAG, "Additional verifiers required, but none installed.");
6253                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
6254                        } else {
6255                            for (int i = 0; i < N; i++) {
6256                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
6257
6258                                final Intent sufficientIntent = new Intent(verification);
6259                                sufficientIntent.setComponent(verifierComponent);
6260
6261                                mContext.sendBroadcast(sufficientIntent);
6262                            }
6263                        }
6264                    }
6265
6266                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
6267                            mRequiredVerifierPackage, receivers);
6268                    if (ret == PackageManager.INSTALL_SUCCEEDED
6269                            && mRequiredVerifierPackage != null) {
6270                        /*
6271                         * Send the intent to the required verification agent,
6272                         * but only start the verification timeout after the
6273                         * target BroadcastReceivers have run.
6274                         */
6275                        verification.setComponent(requiredVerifierComponent);
6276                        mContext.sendOrderedBroadcast(verification,
6277                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
6278                                new BroadcastReceiver() {
6279                                    @Override
6280                                    public void onReceive(Context context, Intent intent) {
6281                                        final Message msg = mHandler
6282                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
6283                                        msg.arg1 = verificationId;
6284                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
6285                                    }
6286                                }, null, 0, null, null);
6287
6288                        /*
6289                         * We don't want the copy to proceed until verification
6290                         * succeeds, so null out this field.
6291                         */
6292                        mArgs = null;
6293                    }
6294                } else {
6295                    /*
6296                     * No package verification is enabled, so immediately start
6297                     * the remote call to initiate copy using temporary file.
6298                     */
6299                    ret = args.copyApk(mContainerService, true);
6300                }
6301            }
6302
6303            mRet = ret;
6304        }
6305
6306        @Override
6307        void handleReturnCode() {
6308            // If mArgs is null, then MCS couldn't be reached. When it
6309            // reconnects, it will try again to install. At that point, this
6310            // will succeed.
6311            if (mArgs != null) {
6312                processPendingInstall(mArgs, mRet);
6313            }
6314
6315            if (mTempPackage != null) {
6316                if (!mTempPackage.delete()) {
6317                    Slog.w(TAG, "Couldn't delete temporary file: "
6318                            + mTempPackage.getAbsolutePath());
6319                }
6320            }
6321        }
6322
6323        @Override
6324        void handleServiceError() {
6325            mArgs = createInstallArgs(this);
6326            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
6327        }
6328
6329        public boolean isForwardLocked() {
6330            return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
6331        }
6332
6333        public Uri getPackageUri() {
6334            if (mTempPackage != null) {
6335                return Uri.fromFile(mTempPackage);
6336            } else {
6337                return mPackageURI;
6338            }
6339        }
6340    }
6341
6342    /*
6343     * Utility class used in movePackage api.
6344     * srcArgs and targetArgs are not set for invalid flags and make
6345     * sure to do null checks when invoking methods on them.
6346     * We probably want to return ErrorPrams for both failed installs
6347     * and moves.
6348     */
6349    class MoveParams extends HandlerParams {
6350        final IPackageMoveObserver observer;
6351        final int flags;
6352        final String packageName;
6353        final InstallArgs srcArgs;
6354        final InstallArgs targetArgs;
6355        int uid;
6356        int mRet;
6357
6358        MoveParams(InstallArgs srcArgs, IPackageMoveObserver observer, int flags,
6359                String packageName, String dataDir, int uid, UserHandle user) {
6360            super(user);
6361            this.srcArgs = srcArgs;
6362            this.observer = observer;
6363            this.flags = flags;
6364            this.packageName = packageName;
6365            this.uid = uid;
6366            if (srcArgs != null) {
6367                Uri packageUri = Uri.fromFile(new File(srcArgs.getCodePath()));
6368                targetArgs = createInstallArgs(packageUri, flags, packageName, dataDir);
6369            } else {
6370                targetArgs = null;
6371            }
6372        }
6373
6374        public void handleStartCopy() throws RemoteException {
6375            mRet = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
6376            // Check for storage space on target medium
6377            if (!targetArgs.checkFreeStorage(mContainerService)) {
6378                Log.w(TAG, "Insufficient storage to install");
6379                return;
6380            }
6381
6382            mRet = srcArgs.doPreCopy();
6383            if (mRet != PackageManager.INSTALL_SUCCEEDED) {
6384                return;
6385            }
6386
6387            mRet = targetArgs.copyApk(mContainerService, false);
6388            if (mRet != PackageManager.INSTALL_SUCCEEDED) {
6389                srcArgs.doPostCopy(uid);
6390                return;
6391            }
6392
6393            mRet = srcArgs.doPostCopy(uid);
6394            if (mRet != PackageManager.INSTALL_SUCCEEDED) {
6395                return;
6396            }
6397
6398            mRet = targetArgs.doPreInstall(mRet);
6399            if (mRet != PackageManager.INSTALL_SUCCEEDED) {
6400                return;
6401            }
6402
6403            if (DEBUG_SD_INSTALL) {
6404                StringBuilder builder = new StringBuilder();
6405                if (srcArgs != null) {
6406                    builder.append("src: ");
6407                    builder.append(srcArgs.getCodePath());
6408                }
6409                if (targetArgs != null) {
6410                    builder.append(" target : ");
6411                    builder.append(targetArgs.getCodePath());
6412                }
6413                Log.i(TAG, builder.toString());
6414            }
6415        }
6416
6417        @Override
6418        void handleReturnCode() {
6419            targetArgs.doPostInstall(mRet, uid);
6420            int currentStatus = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
6421            if (mRet == PackageManager.INSTALL_SUCCEEDED) {
6422                currentStatus = PackageManager.MOVE_SUCCEEDED;
6423            } else if (mRet == PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE){
6424                currentStatus = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
6425            }
6426            processPendingMove(this, currentStatus);
6427        }
6428
6429        @Override
6430        void handleServiceError() {
6431            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
6432        }
6433    }
6434
6435    /**
6436     * Used during creation of InstallArgs
6437     *
6438     * @param flags package installation flags
6439     * @return true if should be installed on external storage
6440     */
6441    private static boolean installOnSd(int flags) {
6442        if ((flags & PackageManager.INSTALL_INTERNAL) != 0) {
6443            return false;
6444        }
6445        if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) {
6446            return true;
6447        }
6448        return false;
6449    }
6450
6451    /**
6452     * Used during creation of InstallArgs
6453     *
6454     * @param flags package installation flags
6455     * @return true if should be installed as forward locked
6456     */
6457    private static boolean installForwardLocked(int flags) {
6458        return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
6459    }
6460
6461    private InstallArgs createInstallArgs(InstallParams params) {
6462        if (installOnSd(params.flags) || params.isForwardLocked()) {
6463            return new AsecInstallArgs(params);
6464        } else {
6465            return new FileInstallArgs(params);
6466        }
6467    }
6468
6469    private InstallArgs createInstallArgs(int flags, String fullCodePath, String fullResourcePath,
6470            String nativeLibraryPath) {
6471        final boolean isInAsec;
6472        if (installOnSd(flags)) {
6473            /* Apps on SD card are always in ASEC containers. */
6474            isInAsec = true;
6475        } else if (installForwardLocked(flags)
6476                && !fullCodePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
6477            /*
6478             * Forward-locked apps are only in ASEC containers if they're the
6479             * new style
6480             */
6481            isInAsec = true;
6482        } else {
6483            isInAsec = false;
6484        }
6485
6486        if (isInAsec) {
6487            return new AsecInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath,
6488                    installOnSd(flags), installForwardLocked(flags));
6489        } else {
6490            return new FileInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath);
6491        }
6492    }
6493
6494    // Used by package mover
6495    private InstallArgs createInstallArgs(Uri packageURI, int flags, String pkgName, String dataDir) {
6496        if (installOnSd(flags) || installForwardLocked(flags)) {
6497            String cid = getNextCodePath(packageURI.getPath(), pkgName, "/"
6498                    + AsecInstallArgs.RES_FILE_NAME);
6499            return new AsecInstallArgs(packageURI, cid, installOnSd(flags),
6500                    installForwardLocked(flags));
6501        } else {
6502            return new FileInstallArgs(packageURI, pkgName, dataDir);
6503        }
6504    }
6505
6506    static abstract class InstallArgs {
6507        final IPackageInstallObserver observer;
6508        // Always refers to PackageManager flags only
6509        final int flags;
6510        final Uri packageURI;
6511        final String installerPackageName;
6512        final ManifestDigest manifestDigest;
6513        final UserHandle user;
6514
6515        InstallArgs(Uri packageURI, IPackageInstallObserver observer, int flags,
6516                String installerPackageName, ManifestDigest manifestDigest,
6517                UserHandle user) {
6518            this.packageURI = packageURI;
6519            this.flags = flags;
6520            this.observer = observer;
6521            this.installerPackageName = installerPackageName;
6522            this.manifestDigest = manifestDigest;
6523            this.user = user;
6524        }
6525
6526        abstract void createCopyFile();
6527        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
6528        abstract int doPreInstall(int status);
6529        abstract boolean doRename(int status, String pkgName, String oldCodePath);
6530
6531        abstract int doPostInstall(int status, int uid);
6532        abstract String getCodePath();
6533        abstract String getResourcePath();
6534        abstract String getNativeLibraryPath();
6535        // Need installer lock especially for dex file removal.
6536        abstract void cleanUpResourcesLI();
6537        abstract boolean doPostDeleteLI(boolean delete);
6538        abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException;
6539
6540        /**
6541         * Called before the source arguments are copied. This is used mostly
6542         * for MoveParams when it needs to read the source file to put it in the
6543         * destination.
6544         */
6545        int doPreCopy() {
6546            return PackageManager.INSTALL_SUCCEEDED;
6547        }
6548
6549        /**
6550         * Called after the source arguments are copied. This is used mostly for
6551         * MoveParams when it needs to read the source file to put it in the
6552         * destination.
6553         *
6554         * @return
6555         */
6556        int doPostCopy(int uid) {
6557            return PackageManager.INSTALL_SUCCEEDED;
6558        }
6559
6560        protected boolean isFwdLocked() {
6561            return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
6562        }
6563    }
6564
6565    class FileInstallArgs extends InstallArgs {
6566        File installDir;
6567        String codeFileName;
6568        String resourceFileName;
6569        String libraryPath;
6570        boolean created = false;
6571
6572        FileInstallArgs(InstallParams params) {
6573            super(params.getPackageUri(), params.observer, params.flags,
6574                    params.installerPackageName, params.getManifestDigest(),
6575                    params.getUser());
6576        }
6577
6578        FileInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath) {
6579            super(null, null, 0, null, null, null);
6580            File codeFile = new File(fullCodePath);
6581            installDir = codeFile.getParentFile();
6582            codeFileName = fullCodePath;
6583            resourceFileName = fullResourcePath;
6584            libraryPath = nativeLibraryPath;
6585        }
6586
6587        FileInstallArgs(Uri packageURI, String pkgName, String dataDir) {
6588            super(packageURI, null, 0, null, null, null);
6589            installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir;
6590            String apkName = getNextCodePath(null, pkgName, ".apk");
6591            codeFileName = new File(installDir, apkName + ".apk").getPath();
6592            resourceFileName = getResourcePathFromCodePath();
6593            libraryPath = new File(dataDir, LIB_DIR_NAME).getPath();
6594        }
6595
6596        boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
6597            final long lowThreshold;
6598
6599            final DeviceStorageMonitorService dsm = (DeviceStorageMonitorService) ServiceManager
6600                    .getService(DeviceStorageMonitorService.SERVICE);
6601            if (dsm == null) {
6602                Log.w(TAG, "Couldn't get low memory threshold; no free limit imposed");
6603                lowThreshold = 0L;
6604            } else {
6605                if (dsm.isMemoryLow()) {
6606                    Log.w(TAG, "Memory is reported as being too low; aborting package install");
6607                    return false;
6608                }
6609
6610                lowThreshold = dsm.getMemoryLowThreshold();
6611            }
6612
6613            try {
6614                mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
6615                        Intent.FLAG_GRANT_READ_URI_PERMISSION);
6616                return imcs.checkInternalFreeStorage(packageURI, isFwdLocked(), lowThreshold);
6617            } finally {
6618                mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
6619            }
6620        }
6621
6622        String getCodePath() {
6623            return codeFileName;
6624        }
6625
6626        void createCopyFile() {
6627            installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir;
6628            codeFileName = createTempPackageFile(installDir).getPath();
6629            resourceFileName = getResourcePathFromCodePath();
6630            created = true;
6631        }
6632
6633        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
6634            if (temp) {
6635                // Generate temp file name
6636                createCopyFile();
6637            }
6638            // Get a ParcelFileDescriptor to write to the output file
6639            File codeFile = new File(codeFileName);
6640            if (!created) {
6641                try {
6642                    codeFile.createNewFile();
6643                    // Set permissions
6644                    if (!setPermissions()) {
6645                        // Failed setting permissions.
6646                        return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
6647                    }
6648                } catch (IOException e) {
6649                   Slog.w(TAG, "Failed to create file " + codeFile);
6650                   return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
6651                }
6652            }
6653            ParcelFileDescriptor out = null;
6654            try {
6655                out = ParcelFileDescriptor.open(codeFile, ParcelFileDescriptor.MODE_READ_WRITE);
6656            } catch (FileNotFoundException e) {
6657                Slog.e(TAG, "Failed to create file descriptor for : " + codeFileName);
6658                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
6659            }
6660            // Copy the resource now
6661            int ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
6662            try {
6663                mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
6664                        Intent.FLAG_GRANT_READ_URI_PERMISSION);
6665                ret = imcs.copyResource(packageURI, null, out);
6666            } finally {
6667                IoUtils.closeQuietly(out);
6668                mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
6669            }
6670
6671            if (isFwdLocked()) {
6672                final File destResourceFile = new File(getResourcePath());
6673
6674                // Copy the public files
6675                try {
6676                    PackageHelper.extractPublicFiles(codeFileName, destResourceFile);
6677                } catch (IOException e) {
6678                    Slog.e(TAG, "Couldn't create a new zip file for the public parts of a"
6679                            + " forward-locked app.");
6680                    destResourceFile.delete();
6681                    return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
6682                }
6683            }
6684            return ret;
6685        }
6686
6687        int doPreInstall(int status) {
6688            if (status != PackageManager.INSTALL_SUCCEEDED) {
6689                cleanUp();
6690            }
6691            return status;
6692        }
6693
6694        boolean doRename(int status, final String pkgName, String oldCodePath) {
6695            if (status != PackageManager.INSTALL_SUCCEEDED) {
6696                cleanUp();
6697                return false;
6698            } else {
6699                final File oldCodeFile = new File(getCodePath());
6700                final File oldResourceFile = new File(getResourcePath());
6701
6702                // Rename APK file based on packageName
6703                final String apkName = getNextCodePath(oldCodePath, pkgName, ".apk");
6704                final File newCodeFile = new File(installDir, apkName + ".apk");
6705                if (!oldCodeFile.renameTo(newCodeFile)) {
6706                    return false;
6707                }
6708                codeFileName = newCodeFile.getPath();
6709
6710                // Rename public resource file if it's forward-locked.
6711                final File newResFile = new File(getResourcePathFromCodePath());
6712                if (isFwdLocked() && !oldResourceFile.renameTo(newResFile)) {
6713                    return false;
6714                }
6715                resourceFileName = getResourcePathFromCodePath();
6716
6717                // Attempt to set permissions
6718                if (!setPermissions()) {
6719                    return false;
6720                }
6721
6722                if (!SELinux.restorecon(newCodeFile)) {
6723                    return false;
6724                }
6725
6726                return true;
6727            }
6728        }
6729
6730        int doPostInstall(int status, int uid) {
6731            if (status != PackageManager.INSTALL_SUCCEEDED) {
6732                cleanUp();
6733            }
6734            return status;
6735        }
6736
6737        String getResourcePath() {
6738            return resourceFileName;
6739        }
6740
6741        private String getResourcePathFromCodePath() {
6742            final String codePath = getCodePath();
6743            if (isFwdLocked()) {
6744                final StringBuilder sb = new StringBuilder();
6745
6746                sb.append(mAppInstallDir.getPath());
6747                sb.append('/');
6748                sb.append(getApkName(codePath));
6749                sb.append(".zip");
6750
6751                /*
6752                 * If our APK is a temporary file, mark the resource as a
6753                 * temporary file as well so it can be cleaned up after
6754                 * catastrophic failure.
6755                 */
6756                if (codePath.endsWith(".tmp")) {
6757                    sb.append(".tmp");
6758                }
6759
6760                return sb.toString();
6761            } else {
6762                return codePath;
6763            }
6764        }
6765
6766        @Override
6767        String getNativeLibraryPath() {
6768            return libraryPath;
6769        }
6770
6771        private boolean cleanUp() {
6772            boolean ret = true;
6773            String sourceDir = getCodePath();
6774            String publicSourceDir = getResourcePath();
6775            if (sourceDir != null) {
6776                File sourceFile = new File(sourceDir);
6777                if (!sourceFile.exists()) {
6778                    Slog.w(TAG, "Package source " + sourceDir + " does not exist.");
6779                    ret = false;
6780                }
6781                // Delete application's code and resources
6782                sourceFile.delete();
6783            }
6784            if (publicSourceDir != null && !publicSourceDir.equals(sourceDir)) {
6785                final File publicSourceFile = new File(publicSourceDir);
6786                if (!publicSourceFile.exists()) {
6787                    Slog.w(TAG, "Package public source " + publicSourceFile + " does not exist.");
6788                }
6789                if (publicSourceFile.exists()) {
6790                    publicSourceFile.delete();
6791                }
6792            }
6793            return ret;
6794        }
6795
6796        void cleanUpResourcesLI() {
6797            String sourceDir = getCodePath();
6798            if (cleanUp()) {
6799                int retCode = mInstaller.rmdex(sourceDir);
6800                if (retCode < 0) {
6801                    Slog.w(TAG, "Couldn't remove dex file for package: "
6802                            +  " at location "
6803                            + sourceDir + ", retcode=" + retCode);
6804                    // we don't consider this to be a failure of the core package deletion
6805                }
6806            }
6807        }
6808
6809        private boolean setPermissions() {
6810            // TODO Do this in a more elegant way later on. for now just a hack
6811            if (!isFwdLocked()) {
6812                final int filePermissions =
6813                    FileUtils.S_IRUSR|FileUtils.S_IWUSR|FileUtils.S_IRGRP
6814                    |FileUtils.S_IROTH;
6815                int retCode = FileUtils.setPermissions(getCodePath(), filePermissions, -1, -1);
6816                if (retCode != 0) {
6817                    Slog.e(TAG, "Couldn't set new package file permissions for " +
6818                            getCodePath()
6819                            + ". The return code was: " + retCode);
6820                    // TODO Define new internal error
6821                    return false;
6822                }
6823                return true;
6824            }
6825            return true;
6826        }
6827
6828        boolean doPostDeleteLI(boolean delete) {
6829            // XXX err, shouldn't we respect the delete flag?
6830            cleanUpResourcesLI();
6831            return true;
6832        }
6833    }
6834
6835    private boolean isAsecExternal(String cid) {
6836        final String asecPath = PackageHelper.getSdFilesystem(cid);
6837        return !asecPath.startsWith(mAsecInternalPath);
6838    }
6839
6840    /**
6841     * Extract the MountService "container ID" from the full code path of an
6842     * .apk.
6843     */
6844    static String cidFromCodePath(String fullCodePath) {
6845        int eidx = fullCodePath.lastIndexOf("/");
6846        String subStr1 = fullCodePath.substring(0, eidx);
6847        int sidx = subStr1.lastIndexOf("/");
6848        return subStr1.substring(sidx+1, eidx);
6849    }
6850
6851    class AsecInstallArgs extends InstallArgs {
6852        static final String RES_FILE_NAME = "pkg.apk";
6853        static final String PUBLIC_RES_FILE_NAME = "res.zip";
6854
6855        String cid;
6856        String packagePath;
6857        String resourcePath;
6858        String libraryPath;
6859
6860        AsecInstallArgs(InstallParams params) {
6861            super(params.getPackageUri(), params.observer, params.flags,
6862                    params.installerPackageName, params.getManifestDigest(),
6863                    params.getUser());
6864        }
6865
6866        AsecInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath,
6867                boolean isExternal, boolean isForwardLocked) {
6868            super(null, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0)
6869                    | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
6870                    null, null, null);
6871            // Extract cid from fullCodePath
6872            int eidx = fullCodePath.lastIndexOf("/");
6873            String subStr1 = fullCodePath.substring(0, eidx);
6874            int sidx = subStr1.lastIndexOf("/");
6875            cid = subStr1.substring(sidx+1, eidx);
6876            setCachePath(subStr1);
6877        }
6878
6879        AsecInstallArgs(String cid, boolean isForwardLocked) {
6880            super(null, null, (isAsecExternal(cid) ? PackageManager.INSTALL_EXTERNAL : 0)
6881                    | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
6882                    null, null, null);
6883            this.cid = cid;
6884            setCachePath(PackageHelper.getSdDir(cid));
6885        }
6886
6887        AsecInstallArgs(Uri packageURI, String cid, boolean isExternal, boolean isForwardLocked) {
6888            super(packageURI, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0)
6889                    | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
6890                    null, null, null);
6891            this.cid = cid;
6892        }
6893
6894        void createCopyFile() {
6895            cid = getTempContainerId();
6896        }
6897
6898        boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
6899            try {
6900                mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
6901                        Intent.FLAG_GRANT_READ_URI_PERMISSION);
6902                return imcs.checkExternalFreeStorage(packageURI, isFwdLocked());
6903            } finally {
6904                mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
6905            }
6906        }
6907
6908        private final boolean isExternal() {
6909            return (flags & PackageManager.INSTALL_EXTERNAL) != 0;
6910        }
6911
6912        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
6913            if (temp) {
6914                createCopyFile();
6915            } else {
6916                /*
6917                 * Pre-emptively destroy the container since it's destroyed if
6918                 * copying fails due to it existing anyway.
6919                 */
6920                PackageHelper.destroySdDir(cid);
6921            }
6922
6923            final String newCachePath;
6924            try {
6925                mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
6926                        Intent.FLAG_GRANT_READ_URI_PERMISSION);
6927                newCachePath = imcs.copyResourceToContainer(packageURI, cid, getEncryptKey(),
6928                        RES_FILE_NAME, PUBLIC_RES_FILE_NAME, isExternal(), isFwdLocked());
6929            } finally {
6930                mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
6931            }
6932
6933            if (newCachePath != null) {
6934                setCachePath(newCachePath);
6935                return PackageManager.INSTALL_SUCCEEDED;
6936            } else {
6937                return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
6938            }
6939        }
6940
6941        @Override
6942        String getCodePath() {
6943            return packagePath;
6944        }
6945
6946        @Override
6947        String getResourcePath() {
6948            return resourcePath;
6949        }
6950
6951        @Override
6952        String getNativeLibraryPath() {
6953            return libraryPath;
6954        }
6955
6956        int doPreInstall(int status) {
6957            if (status != PackageManager.INSTALL_SUCCEEDED) {
6958                // Destroy container
6959                PackageHelper.destroySdDir(cid);
6960            } else {
6961                boolean mounted = PackageHelper.isContainerMounted(cid);
6962                if (!mounted) {
6963                    String newCachePath = PackageHelper.mountSdDir(cid, getEncryptKey(),
6964                            Process.SYSTEM_UID);
6965                    if (newCachePath != null) {
6966                        setCachePath(newCachePath);
6967                    } else {
6968                        return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
6969                    }
6970                }
6971            }
6972            return status;
6973        }
6974
6975        boolean doRename(int status, final String pkgName,
6976                String oldCodePath) {
6977            String newCacheId = getNextCodePath(oldCodePath, pkgName, "/" + RES_FILE_NAME);
6978            String newCachePath = null;
6979            if (PackageHelper.isContainerMounted(cid)) {
6980                // Unmount the container
6981                if (!PackageHelper.unMountSdDir(cid)) {
6982                    Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
6983                    return false;
6984                }
6985            }
6986            if (!PackageHelper.renameSdDir(cid, newCacheId)) {
6987                Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
6988                        " which might be stale. Will try to clean up.");
6989                // Clean up the stale container and proceed to recreate.
6990                if (!PackageHelper.destroySdDir(newCacheId)) {
6991                    Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
6992                    return false;
6993                }
6994                // Successfully cleaned up stale container. Try to rename again.
6995                if (!PackageHelper.renameSdDir(cid, newCacheId)) {
6996                    Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
6997                            + " inspite of cleaning it up.");
6998                    return false;
6999                }
7000            }
7001            if (!PackageHelper.isContainerMounted(newCacheId)) {
7002                Slog.w(TAG, "Mounting container " + newCacheId);
7003                newCachePath = PackageHelper.mountSdDir(newCacheId,
7004                        getEncryptKey(), Process.SYSTEM_UID);
7005            } else {
7006                newCachePath = PackageHelper.getSdDir(newCacheId);
7007            }
7008            if (newCachePath == null) {
7009                Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
7010                return false;
7011            }
7012            Log.i(TAG, "Succesfully renamed " + cid +
7013                    " to " + newCacheId +
7014                    " at new path: " + newCachePath);
7015            cid = newCacheId;
7016            setCachePath(newCachePath);
7017            return true;
7018        }
7019
7020        private void setCachePath(String newCachePath) {
7021            File cachePath = new File(newCachePath);
7022            libraryPath = new File(cachePath, LIB_DIR_NAME).getPath();
7023            packagePath = new File(cachePath, RES_FILE_NAME).getPath();
7024
7025            if (isFwdLocked()) {
7026                resourcePath = new File(cachePath, PUBLIC_RES_FILE_NAME).getPath();
7027            } else {
7028                resourcePath = packagePath;
7029            }
7030        }
7031
7032        int doPostInstall(int status, int uid) {
7033            if (status != PackageManager.INSTALL_SUCCEEDED) {
7034                cleanUp();
7035            } else {
7036                final int groupOwner;
7037                final String protectedFile;
7038                if (isFwdLocked()) {
7039                    groupOwner = uid;
7040                    protectedFile = RES_FILE_NAME;
7041                } else {
7042                    groupOwner = -1;
7043                    protectedFile = null;
7044                }
7045
7046                if (uid < Process.FIRST_APPLICATION_UID
7047                        || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
7048                    Slog.e(TAG, "Failed to finalize " + cid);
7049                    PackageHelper.destroySdDir(cid);
7050                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
7051                }
7052
7053                boolean mounted = PackageHelper.isContainerMounted(cid);
7054                if (!mounted) {
7055                    PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
7056                }
7057            }
7058            return status;
7059        }
7060
7061        private void cleanUp() {
7062            if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
7063
7064            // Destroy secure container
7065            PackageHelper.destroySdDir(cid);
7066        }
7067
7068        void cleanUpResourcesLI() {
7069            String sourceFile = getCodePath();
7070            // Remove dex file
7071            int retCode = mInstaller.rmdex(sourceFile);
7072            if (retCode < 0) {
7073                Slog.w(TAG, "Couldn't remove dex file for package: "
7074                        + " at location "
7075                        + sourceFile.toString() + ", retcode=" + retCode);
7076                // we don't consider this to be a failure of the core package deletion
7077            }
7078            cleanUp();
7079        }
7080
7081        boolean matchContainer(String app) {
7082            if (cid.startsWith(app)) {
7083                return true;
7084            }
7085            return false;
7086        }
7087
7088        String getPackageName() {
7089            return getAsecPackageName(cid);
7090        }
7091
7092        boolean doPostDeleteLI(boolean delete) {
7093            boolean ret = false;
7094            boolean mounted = PackageHelper.isContainerMounted(cid);
7095            if (mounted) {
7096                // Unmount first
7097                ret = PackageHelper.unMountSdDir(cid);
7098            }
7099            if (ret && delete) {
7100                cleanUpResourcesLI();
7101            }
7102            return ret;
7103        }
7104
7105        @Override
7106        int doPreCopy() {
7107            if (isFwdLocked()) {
7108                if (!PackageHelper.fixSdPermissions(cid,
7109                        getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) {
7110                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
7111                }
7112            }
7113
7114            return PackageManager.INSTALL_SUCCEEDED;
7115        }
7116
7117        @Override
7118        int doPostCopy(int uid) {
7119            if (isFwdLocked()) {
7120                if (uid < Process.FIRST_APPLICATION_UID
7121                        || !PackageHelper.fixSdPermissions(cid, uid, RES_FILE_NAME)) {
7122                    Slog.e(TAG, "Failed to finalize " + cid);
7123                    PackageHelper.destroySdDir(cid);
7124                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
7125                }
7126            }
7127
7128            return PackageManager.INSTALL_SUCCEEDED;
7129        }
7130    };
7131
7132    static String getAsecPackageName(String packageCid) {
7133        int idx = packageCid.lastIndexOf("-");
7134        if (idx == -1) {
7135            return packageCid;
7136        }
7137        return packageCid.substring(0, idx);
7138    }
7139
7140    // Utility method used to create code paths based on package name and available index.
7141    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
7142        String idxStr = "";
7143        int idx = 1;
7144        // Fall back to default value of idx=1 if prefix is not
7145        // part of oldCodePath
7146        if (oldCodePath != null) {
7147            String subStr = oldCodePath;
7148            // Drop the suffix right away
7149            if (subStr.endsWith(suffix)) {
7150                subStr = subStr.substring(0, subStr.length() - suffix.length());
7151            }
7152            // If oldCodePath already contains prefix find out the
7153            // ending index to either increment or decrement.
7154            int sidx = subStr.lastIndexOf(prefix);
7155            if (sidx != -1) {
7156                subStr = subStr.substring(sidx + prefix.length());
7157                if (subStr != null) {
7158                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
7159                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
7160                    }
7161                    try {
7162                        idx = Integer.parseInt(subStr);
7163                        if (idx <= 1) {
7164                            idx++;
7165                        } else {
7166                            idx--;
7167                        }
7168                    } catch(NumberFormatException e) {
7169                    }
7170                }
7171            }
7172        }
7173        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
7174        return prefix + idxStr;
7175    }
7176
7177    // Utility method used to ignore ADD/REMOVE events
7178    // by directory observer.
7179    private static boolean ignoreCodePath(String fullPathStr) {
7180        String apkName = getApkName(fullPathStr);
7181        int idx = apkName.lastIndexOf(INSTALL_PACKAGE_SUFFIX);
7182        if (idx != -1 && ((idx+1) < apkName.length())) {
7183            // Make sure the package ends with a numeral
7184            String version = apkName.substring(idx+1);
7185            try {
7186                Integer.parseInt(version);
7187                return true;
7188            } catch (NumberFormatException e) {}
7189        }
7190        return false;
7191    }
7192
7193    // Utility method that returns the relative package path with respect
7194    // to the installation directory. Like say for /data/data/com.test-1.apk
7195    // string com.test-1 is returned.
7196    static String getApkName(String codePath) {
7197        if (codePath == null) {
7198            return null;
7199        }
7200        int sidx = codePath.lastIndexOf("/");
7201        int eidx = codePath.lastIndexOf(".");
7202        if (eidx == -1) {
7203            eidx = codePath.length();
7204        } else if (eidx == 0) {
7205            Slog.w(TAG, " Invalid code path, "+ codePath + " Not a valid apk name");
7206            return null;
7207        }
7208        return codePath.substring(sidx+1, eidx);
7209    }
7210
7211    class PackageInstalledInfo {
7212        String name;
7213        int uid;
7214        int[] users;
7215        PackageParser.Package pkg;
7216        int returnCode;
7217        PackageRemovedInfo removedInfo;
7218    }
7219
7220    /*
7221     * Install a non-existing package.
7222     */
7223    private void installNewPackageLI(PackageParser.Package pkg,
7224            int parseFlags, int scanMode, UserHandle user,
7225            String installerPackageName, PackageInstalledInfo res) {
7226        // Remember this for later, in case we need to rollback this install
7227        String pkgName = pkg.packageName;
7228
7229        boolean dataDirExists = getDataPathForPackage(pkg.packageName, 0).exists();
7230        synchronized(mPackages) {
7231            if (mSettings.mRenamedPackages.containsKey(pkgName)) {
7232                // A package with the same name is already installed, though
7233                // it has been renamed to an older name.  The package we
7234                // are trying to install should be installed as an update to
7235                // the existing one, but that has not been requested, so bail.
7236                Slog.w(TAG, "Attempt to re-install " + pkgName
7237                        + " without first uninstalling package running as "
7238                        + mSettings.mRenamedPackages.get(pkgName));
7239                res.returnCode = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
7240                return;
7241            }
7242            if (mPackages.containsKey(pkgName) || mAppDirs.containsKey(pkg.mPath)) {
7243                // Don't allow installation over an existing package with the same name.
7244                Slog.w(TAG, "Attempt to re-install " + pkgName
7245                        + " without first uninstalling.");
7246                res.returnCode = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
7247                return;
7248            }
7249        }
7250        mLastScanError = PackageManager.INSTALL_SUCCEEDED;
7251        PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanMode,
7252                System.currentTimeMillis(), user);
7253        if (newPackage == null) {
7254            Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath);
7255            if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
7256                res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK;
7257            }
7258        } else {
7259            updateSettingsLI(newPackage,
7260                    installerPackageName,
7261                    res);
7262            // delete the partially installed application. the data directory will have to be
7263            // restored if it was already existing
7264            if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
7265                // remove package from internal structures.  Note that we want deletePackageX to
7266                // delete the package data and cache directories that it created in
7267                // scanPackageLocked, unless those directories existed before we even tried to
7268                // install.
7269                deletePackageLI(pkgName, UserHandle.ALL, false,
7270                        dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0,
7271                                res.removedInfo, true);
7272            }
7273        }
7274    }
7275
7276    private void replacePackageLI(PackageParser.Package pkg,
7277            int parseFlags, int scanMode, UserHandle user,
7278            String installerPackageName, PackageInstalledInfo res) {
7279
7280        PackageParser.Package oldPackage;
7281        String pkgName = pkg.packageName;
7282        // First find the old package info and check signatures
7283        synchronized(mPackages) {
7284            oldPackage = mPackages.get(pkgName);
7285            if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
7286                    != PackageManager.SIGNATURE_MATCH) {
7287                Slog.w(TAG, "New package has a different signature: " + pkgName);
7288                res.returnCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
7289                return;
7290            }
7291        }
7292        boolean sysPkg = (isSystemApp(oldPackage));
7293        if (sysPkg) {
7294            replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanMode,
7295                    user, installerPackageName, res);
7296        } else {
7297            replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanMode,
7298                    user, installerPackageName, res);
7299        }
7300    }
7301
7302    private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage,
7303            PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user,
7304            String installerPackageName, PackageInstalledInfo res) {
7305        PackageParser.Package newPackage = null;
7306        String pkgName = deletedPackage.packageName;
7307        boolean deletedPkg = true;
7308        boolean updatedSettings = false;
7309
7310        long origUpdateTime;
7311        if (pkg.mExtras != null) {
7312            origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime;
7313        } else {
7314            origUpdateTime = 0;
7315        }
7316
7317        // First delete the existing package while retaining the data directory
7318        if (!deletePackageLI(pkgName, null, true, PackageManager.DELETE_KEEP_DATA,
7319                res.removedInfo, true)) {
7320            // If the existing package wasn't successfully deleted
7321            res.returnCode = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
7322            deletedPkg = false;
7323        } else {
7324            // Successfully deleted the old package. Now proceed with re-installation
7325            mLastScanError = PackageManager.INSTALL_SUCCEEDED;
7326            newPackage = scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_TIME,
7327                    System.currentTimeMillis(), user);
7328            if (newPackage == null) {
7329                Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath);
7330                if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
7331                    res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK;
7332                }
7333            } else {
7334                updateSettingsLI(newPackage,
7335                        installerPackageName,
7336                        res);
7337                updatedSettings = true;
7338            }
7339        }
7340
7341        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
7342            // remove package from internal structures.  Note that we want deletePackageX to
7343            // delete the package data and cache directories that it created in
7344            // scanPackageLocked, unless those directories existed before we even tried to
7345            // install.
7346            if(updatedSettings) {
7347                deletePackageLI(
7348                        pkgName, null, true,
7349                        PackageManager.DELETE_KEEP_DATA,
7350                                res.removedInfo, true);
7351            }
7352            // Since we failed to install the new package we need to restore the old
7353            // package that we deleted.
7354            if(deletedPkg) {
7355                File restoreFile = new File(deletedPackage.mPath);
7356                // Parse old package
7357                boolean oldOnSd = isExternal(deletedPackage);
7358                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
7359                        (isForwardLocked(deletedPackage) ? PackageParser.PARSE_FORWARD_LOCK : 0) |
7360                        (oldOnSd ? PackageParser.PARSE_ON_SDCARD : 0);
7361                int oldScanMode = (oldOnSd ? 0 : SCAN_MONITOR) | SCAN_UPDATE_SIGNATURE
7362                        | SCAN_UPDATE_TIME;
7363                if (scanPackageLI(restoreFile, oldParseFlags, oldScanMode,
7364                        origUpdateTime, user) == null) {
7365                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade");
7366                    return;
7367                }
7368                // Restore of old package succeeded. Update permissions.
7369                // writer
7370                synchronized (mPackages) {
7371                    updatePermissionsLPw(deletedPackage.packageName, deletedPackage,
7372                            UPDATE_PERMISSIONS_ALL);
7373                    // can downgrade to reader
7374                    mSettings.writeLPr();
7375                }
7376                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
7377            }
7378        }
7379    }
7380
7381    private void replaceSystemPackageLI(PackageParser.Package deletedPackage,
7382            PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user,
7383            String installerPackageName, PackageInstalledInfo res) {
7384        PackageParser.Package newPackage = null;
7385        boolean updatedSettings = false;
7386        parseFlags |= PackageManager.INSTALL_REPLACE_EXISTING |
7387                PackageParser.PARSE_IS_SYSTEM;
7388        String packageName = deletedPackage.packageName;
7389        res.returnCode = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
7390        if (packageName == null) {
7391            Slog.w(TAG, "Attempt to delete null packageName.");
7392            return;
7393        }
7394        PackageParser.Package oldPkg;
7395        PackageSetting oldPkgSetting;
7396        // reader
7397        synchronized (mPackages) {
7398            oldPkg = mPackages.get(packageName);
7399            oldPkgSetting = mSettings.mPackages.get(packageName);
7400            if((oldPkg == null) || (oldPkg.applicationInfo == null) ||
7401                    (oldPkgSetting == null)) {
7402                Slog.w(TAG, "Couldn't find package:"+packageName+" information");
7403                return;
7404            }
7405        }
7406
7407        killApplication(packageName, oldPkg.applicationInfo.uid);
7408
7409        res.removedInfo.uid = oldPkg.applicationInfo.uid;
7410        res.removedInfo.removedPackage = packageName;
7411        // Remove existing system package
7412        removePackageLI(oldPkg, true);
7413        // writer
7414        synchronized (mPackages) {
7415            if (!mSettings.disableSystemPackageLPw(packageName) && deletedPackage != null) {
7416                // We didn't need to disable the .apk as a current system package,
7417                // which means we are replacing another update that is already
7418                // installed.  We need to make sure to delete the older one's .apk.
7419                res.removedInfo.args = createInstallArgs(0,
7420                        deletedPackage.applicationInfo.sourceDir,
7421                        deletedPackage.applicationInfo.publicSourceDir,
7422                        deletedPackage.applicationInfo.nativeLibraryDir);
7423            } else {
7424                res.removedInfo.args = null;
7425            }
7426        }
7427
7428        // Successfully disabled the old package. Now proceed with re-installation
7429        mLastScanError = PackageManager.INSTALL_SUCCEEDED;
7430        pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
7431        newPackage = scanPackageLI(pkg, parseFlags, scanMode, 0, user);
7432        if (newPackage == null) {
7433            Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath);
7434            if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
7435                res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK;
7436            }
7437        } else {
7438            if (newPackage.mExtras != null) {
7439                final PackageSetting newPkgSetting = (PackageSetting)newPackage.mExtras;
7440                newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime;
7441                newPkgSetting.lastUpdateTime = System.currentTimeMillis();
7442            }
7443            updateSettingsLI(newPackage, installerPackageName, res);
7444            updatedSettings = true;
7445        }
7446
7447        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
7448            // Re installation failed. Restore old information
7449            // Remove new pkg information
7450            if (newPackage != null) {
7451                removePackageLI(newPackage, true);
7452            }
7453            // Add back the old system package
7454            scanPackageLI(oldPkg, parseFlags, SCAN_MONITOR | SCAN_UPDATE_SIGNATURE, 0, user);
7455            // Restore the old system information in Settings
7456            synchronized(mPackages) {
7457                if (updatedSettings) {
7458                    mSettings.enableSystemPackageLPw(packageName);
7459                    mSettings.setInstallerPackageName(packageName,
7460                            oldPkgSetting.installerPackageName);
7461                }
7462                mSettings.writeLPr();
7463            }
7464        }
7465    }
7466
7467    // Utility method used to move dex files during install.
7468    private int moveDexFilesLI(PackageParser.Package newPackage) {
7469        int retCode;
7470        if ((newPackage.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
7471            retCode = mInstaller.movedex(newPackage.mScanPath, newPackage.mPath);
7472            if (retCode != 0) {
7473                if (mNoDexOpt) {
7474                    /*
7475                     * If we're in an engineering build, programs are lazily run
7476                     * through dexopt. If the .dex file doesn't exist yet, it
7477                     * will be created when the program is run next.
7478                     */
7479                    Slog.i(TAG, "dex file doesn't exist, skipping move: " + newPackage.mPath);
7480                } else {
7481                    Slog.e(TAG, "Couldn't rename dex file: " + newPackage.mPath);
7482                    return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
7483                }
7484            }
7485        }
7486        return PackageManager.INSTALL_SUCCEEDED;
7487    }
7488
7489    private void updateSettingsLI(PackageParser.Package newPackage,
7490            String installerPackageName, PackageInstalledInfo res) {
7491        String pkgName = newPackage.packageName;
7492        synchronized (mPackages) {
7493            //write settings. the installStatus will be incomplete at this stage.
7494            //note that the new package setting would have already been
7495            //added to mPackages. It hasn't been persisted yet.
7496            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
7497            mSettings.writeLPr();
7498        }
7499
7500        if ((res.returnCode = moveDexFilesLI(newPackage))
7501                != PackageManager.INSTALL_SUCCEEDED) {
7502            // Discontinue if moving dex files failed.
7503            return;
7504        }
7505
7506        Log.d(TAG, "New package installed in " + newPackage.mPath);
7507
7508        synchronized (mPackages) {
7509            updatePermissionsLPw(newPackage.packageName, newPackage,
7510                    UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
7511                            ? UPDATE_PERMISSIONS_ALL : 0));
7512            res.name = pkgName;
7513            PackageSetting ps = mSettings.mPackages.get(pkgName);
7514            if (ps != null) {
7515                res.users = ps.getInstalledUsers(sUserManager.getUserIds());
7516            }
7517            res.uid = newPackage.applicationInfo.uid;
7518            res.pkg = newPackage;
7519            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
7520            mSettings.setInstallerPackageName(pkgName, installerPackageName);
7521            res.returnCode = PackageManager.INSTALL_SUCCEEDED;
7522            //to update install status
7523            mSettings.writeLPr();
7524        }
7525    }
7526
7527    private void installPackageLI(InstallArgs args,
7528            boolean newInstall, PackageInstalledInfo res) {
7529        int pFlags = args.flags;
7530        String installerPackageName = args.installerPackageName;
7531        File tmpPackageFile = new File(args.getCodePath());
7532        boolean forwardLocked = ((pFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
7533        boolean onSd = ((pFlags & PackageManager.INSTALL_EXTERNAL) != 0);
7534        boolean replace = false;
7535        int scanMode = (onSd ? 0 : SCAN_MONITOR) | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE
7536                | (newInstall ? SCAN_NEW_INSTALL : 0);
7537        // Result object to be returned
7538        res.returnCode = PackageManager.INSTALL_SUCCEEDED;
7539
7540        // Retrieve PackageSettings and parse package
7541        int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
7542                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
7543                | (onSd ? PackageParser.PARSE_ON_SDCARD : 0);
7544        PackageParser pp = new PackageParser(tmpPackageFile.getPath());
7545        pp.setSeparateProcesses(mSeparateProcesses);
7546        final PackageParser.Package pkg = pp.parsePackage(tmpPackageFile,
7547                null, mMetrics, parseFlags);
7548        if (pkg == null) {
7549            res.returnCode = pp.getParseError();
7550            return;
7551        }
7552        String pkgName = res.name = pkg.packageName;
7553        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
7554            if ((pFlags&PackageManager.INSTALL_ALLOW_TEST) == 0) {
7555                res.returnCode = PackageManager.INSTALL_FAILED_TEST_ONLY;
7556                return;
7557            }
7558        }
7559        if (GET_CERTIFICATES && !pp.collectCertificates(pkg, parseFlags)) {
7560            res.returnCode = pp.getParseError();
7561            return;
7562        }
7563
7564        /* If the installer passed in a manifest digest, compare it now. */
7565        if (args.manifestDigest != null) {
7566            if (DEBUG_INSTALL) {
7567                final String parsedManifest = pkg.manifestDigest == null ? "null"
7568                        : pkg.manifestDigest.toString();
7569                Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. "
7570                        + parsedManifest);
7571            }
7572
7573            if (!args.manifestDigest.equals(pkg.manifestDigest)) {
7574                res.returnCode = PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
7575                return;
7576            }
7577        } else if (DEBUG_INSTALL) {
7578            final String parsedManifest = pkg.manifestDigest == null
7579                    ? "null" : pkg.manifestDigest.toString();
7580            Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest);
7581        }
7582
7583        // Get rid of all references to package scan path via parser.
7584        pp = null;
7585        String oldCodePath = null;
7586        boolean systemApp = false;
7587        synchronized (mPackages) {
7588            // Check if installing already existing package
7589            if ((pFlags&PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
7590                String oldName = mSettings.mRenamedPackages.get(pkgName);
7591                if (pkg.mOriginalPackages != null
7592                        && pkg.mOriginalPackages.contains(oldName)
7593                        && mPackages.containsKey(oldName)) {
7594                    // This package is derived from an original package,
7595                    // and this device has been updating from that original
7596                    // name.  We must continue using the original name, so
7597                    // rename the new package here.
7598                    pkg.setPackageName(oldName);
7599                    pkgName = pkg.packageName;
7600                    replace = true;
7601                } else if (mPackages.containsKey(pkgName)) {
7602                    // This package, under its official name, already exists
7603                    // on the device; we should replace it.
7604                    replace = true;
7605                }
7606            }
7607            PackageSetting ps = mSettings.mPackages.get(pkgName);
7608            if (ps != null) {
7609                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
7610                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
7611                    systemApp = (ps.pkg.applicationInfo.flags &
7612                            ApplicationInfo.FLAG_SYSTEM) != 0;
7613                }
7614            }
7615        }
7616
7617        if (systemApp && onSd) {
7618            // Disable updates to system apps on sdcard
7619            Slog.w(TAG, "Cannot install updates to system apps on sdcard");
7620            res.returnCode = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
7621            return;
7622        }
7623
7624        if (!args.doRename(res.returnCode, pkgName, oldCodePath)) {
7625            res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
7626            return;
7627        }
7628        // Set application objects path explicitly after the rename
7629        setApplicationInfoPaths(pkg, args.getCodePath(), args.getResourcePath());
7630        pkg.applicationInfo.nativeLibraryDir = args.getNativeLibraryPath();
7631        if (replace) {
7632            replacePackageLI(pkg, parseFlags, scanMode, args.user,
7633                    installerPackageName, res);
7634        } else {
7635            installNewPackageLI(pkg, parseFlags, scanMode, args.user,
7636                    installerPackageName,res);
7637        }
7638        synchronized (mPackages) {
7639            PackageSetting ps = mSettings.mPackages.get(pkgName);
7640            if (ps != null) {
7641                res.users = ps.getInstalledUsers(sUserManager.getUserIds());
7642            }
7643        }
7644    }
7645
7646    private static boolean isForwardLocked(PackageParser.Package pkg) {
7647        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
7648    }
7649
7650
7651    private boolean isForwardLocked(PackageSetting ps) {
7652        return (ps.pkgFlags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
7653    }
7654
7655    private static boolean isExternal(PackageParser.Package pkg) {
7656        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
7657    }
7658
7659    private static boolean isExternal(PackageSetting ps) {
7660        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
7661    }
7662
7663    private static boolean isSystemApp(PackageParser.Package pkg) {
7664        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
7665    }
7666
7667    private static boolean isSystemApp(ApplicationInfo info) {
7668        return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
7669    }
7670
7671    private static boolean isSystemApp(PackageSetting ps) {
7672        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
7673    }
7674
7675    private static boolean isUpdatedSystemApp(PackageParser.Package pkg) {
7676        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
7677    }
7678
7679    private int packageFlagsToInstallFlags(PackageSetting ps) {
7680        int installFlags = 0;
7681        if (isExternal(ps)) {
7682            installFlags |= PackageManager.INSTALL_EXTERNAL;
7683        }
7684        if (isForwardLocked(ps)) {
7685            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
7686        }
7687        return installFlags;
7688    }
7689
7690    private void deleteTempPackageFiles() {
7691        FilenameFilter filter = new FilenameFilter() {
7692            public boolean accept(File dir, String name) {
7693                return name.startsWith("vmdl") && name.endsWith(".tmp");
7694            }
7695        };
7696        String tmpFilesList[] = mAppInstallDir.list(filter);
7697        if(tmpFilesList == null) {
7698            return;
7699        }
7700        for(int i = 0; i < tmpFilesList.length; i++) {
7701            File tmpFile = new File(mAppInstallDir, tmpFilesList[i]);
7702            tmpFile.delete();
7703        }
7704    }
7705
7706    private File createTempPackageFile(File installDir) {
7707        File tmpPackageFile;
7708        try {
7709            tmpPackageFile = File.createTempFile("vmdl", ".tmp", installDir);
7710        } catch (IOException e) {
7711            Slog.e(TAG, "Couldn't create temp file for downloaded package file.");
7712            return null;
7713        }
7714        try {
7715            FileUtils.setPermissions(
7716                    tmpPackageFile.getCanonicalPath(), FileUtils.S_IRUSR|FileUtils.S_IWUSR,
7717                    -1, -1);
7718            if (!SELinux.restorecon(tmpPackageFile)) {
7719                return null;
7720            }
7721        } catch (IOException e) {
7722            Slog.e(TAG, "Trouble getting the canoncical path for a temp file.");
7723            return null;
7724        }
7725        return tmpPackageFile;
7726    }
7727
7728    public void deletePackage(final String packageName,
7729                              final IPackageDeleteObserver observer,
7730                              final int flags) {
7731        mContext.enforceCallingOrSelfPermission(
7732                android.Manifest.permission.DELETE_PACKAGES, null);
7733        // Queue up an async operation since the package deletion may take a little while.
7734        final int uid = Binder.getCallingUid();
7735        mHandler.post(new Runnable() {
7736            public void run() {
7737                mHandler.removeCallbacks(this);
7738                final int returnCode = deletePackageX(packageName, uid, flags);
7739                if (observer != null) {
7740                    try {
7741                        observer.packageDeleted(packageName, returnCode);
7742                    } catch (RemoteException e) {
7743                        Log.i(TAG, "Observer no longer exists.");
7744                    } //end catch
7745                } //end if
7746            } //end run
7747        });
7748    }
7749
7750    /**
7751     *  This method is an internal method that could be get invoked either
7752     *  to delete an installed package or to clean up a failed installation.
7753     *  After deleting an installed package, a broadcast is sent to notify any
7754     *  listeners that the package has been installed. For cleaning up a failed
7755     *  installation, the broadcast is not necessary since the package's
7756     *  installation wouldn't have sent the initial broadcast either
7757     *  The key steps in deleting a package are
7758     *  deleting the package information in internal structures like mPackages,
7759     *  deleting the packages base directories through installd
7760     *  updating mSettings to reflect current status
7761     *  persisting settings for later use
7762     *  sending a broadcast if necessary
7763     */
7764    private int deletePackageX(String packageName, int uid, int flags) {
7765        final PackageRemovedInfo info = new PackageRemovedInfo();
7766        final boolean res;
7767
7768        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
7769                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
7770        try {
7771            if (dpm != null && dpm.packageHasActiveAdmins(packageName)) {
7772                Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
7773                return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
7774            }
7775        } catch (RemoteException e) {
7776        }
7777
7778        synchronized (mInstallLock) {
7779            res = deletePackageLI(packageName,
7780                    (flags & PackageManager.DELETE_ALL_USERS) != 0
7781                            ? UserHandle.ALL : new UserHandle(UserHandle.getUserId(uid)),
7782                    true, flags | REMOVE_CHATTY, info, true);
7783        }
7784
7785        if (res) {
7786            boolean systemUpdate = info.isRemovedPackageSystemUpdate;
7787            info.sendBroadcast(true, systemUpdate);
7788
7789            // If the removed package was a system update, the old system packaged
7790            // was re-enabled; we need to broadcast this information
7791            if (systemUpdate) {
7792                Bundle extras = new Bundle(1);
7793                extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0
7794                        ? info.removedAppId : info.uid);
7795                extras.putBoolean(Intent.EXTRA_REPLACING, true);
7796
7797                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
7798                        extras, null, null, null);
7799                sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
7800                        extras, null, null, null);
7801                sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
7802                        null, packageName, null, null);
7803            }
7804        }
7805        // Force a gc here.
7806        Runtime.getRuntime().gc();
7807        // Delete the resources here after sending the broadcast to let
7808        // other processes clean up before deleting resources.
7809        if (info.args != null) {
7810            synchronized (mInstallLock) {
7811                info.args.doPostDeleteLI(true);
7812            }
7813        }
7814
7815        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
7816    }
7817
7818    static class PackageRemovedInfo {
7819        String removedPackage;
7820        int uid = -1;
7821        int removedAppId = -1;
7822        int[] removedUsers = null;
7823        boolean isRemovedPackageSystemUpdate = false;
7824        // Clean up resources deleted packages.
7825        InstallArgs args = null;
7826
7827        void sendBroadcast(boolean fullRemove, boolean replacing) {
7828            Bundle extras = new Bundle(1);
7829            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
7830            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove);
7831            if (replacing) {
7832                extras.putBoolean(Intent.EXTRA_REPLACING, true);
7833            }
7834            if (removedPackage != null) {
7835                sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
7836                        extras, null, null, removedUsers);
7837                if (fullRemove && !replacing) {
7838                    sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage,
7839                            extras, null, null, removedUsers);
7840                }
7841            }
7842            if (removedAppId >= 0) {
7843                sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null,
7844                        removedUsers);
7845            }
7846        }
7847    }
7848
7849    /*
7850     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
7851     * flag is not set, the data directory is removed as well.
7852     * make sure this flag is set for partially installed apps. If not its meaningless to
7853     * delete a partially installed application.
7854     */
7855    private void removePackageDataLI(PackageParser.Package p, PackageRemovedInfo outInfo,
7856            int flags, boolean writeSettings) {
7857        String packageName = p.packageName;
7858        removePackageLI(p, (flags&REMOVE_CHATTY) != 0);
7859        // Retrieve object to delete permissions for shared user later on
7860        final PackageSetting deletedPs;
7861        // reader
7862        synchronized (mPackages) {
7863            deletedPs = mSettings.mPackages.get(packageName);
7864            if (outInfo != null) {
7865                outInfo.removedPackage = packageName;
7866                outInfo.removedUsers = deletedPs != null
7867                        ? deletedPs.getInstalledUsers(sUserManager.getUserIds()) : null;
7868            }
7869        }
7870        if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
7871            removeDataDirsLI(packageName);
7872            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
7873        }
7874        // writer
7875        synchronized (mPackages) {
7876            if (deletedPs != null) {
7877                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
7878                    if (outInfo != null) {
7879                        outInfo.removedAppId = mSettings.removePackageLPw(packageName);
7880                    }
7881                    if (deletedPs != null) {
7882                        updatePermissionsLPw(deletedPs.name, null, 0);
7883                        if (deletedPs.sharedUser != null) {
7884                            // remove permissions associated with package
7885                            mSettings.updateSharedUserPermsLPw(deletedPs, mGlobalGids);
7886                        }
7887                    }
7888                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
7889                }
7890            }
7891            // can downgrade to reader
7892            if (writeSettings) {
7893                // Save settings now
7894                mSettings.writeLPr();
7895            }
7896        }
7897    }
7898
7899    /*
7900     * Tries to delete system package.
7901     */
7902    private boolean deleteSystemPackageLI(PackageParser.Package p,
7903            int flags, PackageRemovedInfo outInfo, boolean writeSettings) {
7904        ApplicationInfo applicationInfo = p.applicationInfo;
7905        //applicable for non-partially installed applications only
7906        if (applicationInfo == null) {
7907            Slog.w(TAG, "Package " + p.packageName + " has no applicationInfo.");
7908            return false;
7909        }
7910        PackageSetting ps = null;
7911        // Confirm if the system package has been updated
7912        // An updated system app can be deleted. This will also have to restore
7913        // the system pkg from system partition
7914        // reader
7915        synchronized (mPackages) {
7916            ps = mSettings.getDisabledSystemPkgLPr(p.packageName);
7917        }
7918        if (ps == null) {
7919            Slog.w(TAG, "Attempt to delete unknown system package "+ p.packageName);
7920            return false;
7921        } else {
7922            Log.i(TAG, "Deleting system pkg from data partition");
7923        }
7924        // Delete the updated package
7925        outInfo.isRemovedPackageSystemUpdate = true;
7926        if (ps.versionCode < p.mVersionCode) {
7927            // Delete data for downgrades
7928            flags &= ~PackageManager.DELETE_KEEP_DATA;
7929        } else {
7930            // Preserve data by setting flag
7931            flags |= PackageManager.DELETE_KEEP_DATA;
7932        }
7933        boolean ret = deleteInstalledPackageLI(p, true, flags, outInfo,
7934                writeSettings);
7935        if (!ret) {
7936            return false;
7937        }
7938        // writer
7939        synchronized (mPackages) {
7940            // Reinstate the old system package
7941            mSettings.enableSystemPackageLPw(p.packageName);
7942            // Remove any native libraries from the upgraded package.
7943            NativeLibraryHelper.removeNativeBinariesLI(p.applicationInfo.nativeLibraryDir);
7944        }
7945        // Install the system package
7946        PackageParser.Package newPkg = scanPackageLI(ps.codePath,
7947                PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM,
7948                SCAN_MONITOR | SCAN_NO_PATHS, 0, null);
7949
7950        if (newPkg == null) {
7951            Slog.w(TAG, "Failed to restore system package:"+p.packageName+" with error:" + mLastScanError);
7952            return false;
7953        }
7954        // writer
7955        synchronized (mPackages) {
7956            updatePermissionsLPw(newPkg.packageName, newPkg,
7957                    UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
7958            // can downgrade to reader here
7959            if (writeSettings) {
7960                mSettings.writeLPr();
7961            }
7962        }
7963        return true;
7964    }
7965
7966    private boolean deleteInstalledPackageLI(PackageParser.Package p,
7967            boolean deleteCodeAndResources, int flags, PackageRemovedInfo outInfo,
7968            boolean writeSettings) {
7969        ApplicationInfo applicationInfo = p.applicationInfo;
7970        if (applicationInfo == null) {
7971            Slog.w(TAG, "Package " + p.packageName + " has no applicationInfo.");
7972            return false;
7973        }
7974        if (outInfo != null) {
7975            outInfo.uid = applicationInfo.uid;
7976        }
7977
7978        // Delete package data from internal structures and also remove data if flag is set
7979        removePackageDataLI(p, outInfo, flags, writeSettings);
7980
7981        // Delete application code and resources
7982        if (deleteCodeAndResources) {
7983            // TODO can pick up from PackageSettings as well
7984            int installFlags = isExternal(p) ? PackageManager.INSTALL_EXTERNAL : 0;
7985            installFlags |= isForwardLocked(p) ? PackageManager.INSTALL_FORWARD_LOCK : 0;
7986            outInfo.args = createInstallArgs(installFlags, applicationInfo.sourceDir,
7987                    applicationInfo.publicSourceDir, applicationInfo.nativeLibraryDir);
7988        }
7989        return true;
7990    }
7991
7992    /*
7993     * This method handles package deletion in general
7994     */
7995    private boolean deletePackageLI(String packageName, UserHandle user,
7996            boolean deleteCodeAndResources, int flags, PackageRemovedInfo outInfo,
7997            boolean writeSettings) {
7998        if (packageName == null) {
7999            Slog.w(TAG, "Attempt to delete null packageName.");
8000            return false;
8001        }
8002        PackageParser.Package p;
8003        boolean dataOnly = false;
8004        int removeUser = -1;
8005        int appId = -1;
8006        synchronized (mPackages) {
8007            p = mPackages.get(packageName);
8008            if (p == null) {
8009                //this retrieves partially installed apps
8010                dataOnly = true;
8011                PackageSetting ps = mSettings.mPackages.get(packageName);
8012                if (ps == null) {
8013                    Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
8014                    return false;
8015                }
8016                p = ps.pkg;
8017            }
8018            if (p == null) {
8019                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
8020                return false;
8021            }
8022            final PackageSetting ps = (PackageSetting)p.mExtras;
8023            if (!isSystemApp(p) && ps != null && user != null
8024                    && user.getIdentifier() != UserHandle.USER_ALL) {
8025                // The caller is asking that the package only be deleted for a single
8026                // user.  To do this, we just mark its uninstalled state and delete
8027                // its data.
8028                ps.setUserState(user.getIdentifier(),
8029                        COMPONENT_ENABLED_STATE_DEFAULT,
8030                        false, //installed
8031                        true,  //stopped
8032                        true,  //notLaunched
8033                        null, null);
8034                if (ps.isAnyInstalled(sUserManager.getUserIds())) {
8035                    // Other user still have this package installed, so all
8036                    // we need to do is clear this user's data and save that
8037                    // it is uninstalled.
8038                    removeUser = user.getIdentifier();
8039                    appId = ps.appId;
8040                    mSettings.writePackageRestrictionsLPr(removeUser);
8041                } else {
8042                    // We need to set it back to 'installed' so the uninstall
8043                    // broadcasts will be sent correctly.
8044                    ps.setInstalled(true, user.getIdentifier());
8045                }
8046            }
8047        }
8048
8049        if (removeUser >= 0) {
8050            // From above, we determined that we are deleting this only
8051            // for a single user.  Continue the work here.
8052            if (outInfo != null) {
8053                outInfo.removedPackage = packageName;
8054                outInfo.removedAppId = appId;
8055                outInfo.removedUsers = new int[] {removeUser};
8056            }
8057            mInstaller.clearUserData(packageName, removeUser);
8058            schedulePackageCleaning(packageName, removeUser, false);
8059            return true;
8060        }
8061
8062        if (dataOnly) {
8063            // Delete application data first
8064            removePackageDataLI(p, outInfo, flags, writeSettings);
8065            return true;
8066        }
8067        // At this point the package should have ApplicationInfo associated with it
8068        if (p.applicationInfo == null) {
8069            Slog.w(TAG, "Package " + p.packageName + " has no applicationInfo.");
8070            return false;
8071        }
8072        boolean ret = false;
8073        if (isSystemApp(p)) {
8074            Log.i(TAG, "Removing system package:"+p.packageName);
8075            // When an updated system application is deleted we delete the existing resources as well and
8076            // fall back to existing code in system partition
8077            ret = deleteSystemPackageLI(p, flags, outInfo, writeSettings);
8078        } else {
8079            Log.i(TAG, "Removing non-system package:"+p.packageName);
8080            // Kill application pre-emptively especially for apps on sd.
8081            killApplication(packageName, p.applicationInfo.uid);
8082            ret = deleteInstalledPackageLI(p, deleteCodeAndResources, flags, outInfo,
8083                    writeSettings);
8084        }
8085        return ret;
8086    }
8087
8088    private final class ClearStorageConnection implements ServiceConnection {
8089        IMediaContainerService mContainerService;
8090
8091        @Override
8092        public void onServiceConnected(ComponentName name, IBinder service) {
8093            synchronized (this) {
8094                mContainerService = IMediaContainerService.Stub.asInterface(service);
8095                notifyAll();
8096            }
8097        }
8098
8099        @Override
8100        public void onServiceDisconnected(ComponentName name) {
8101        }
8102    }
8103
8104    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
8105        final boolean mounted;
8106        if (Environment.isExternalStorageEmulated()) {
8107            mounted = true;
8108        } else {
8109            final String status = Environment.getExternalStorageState();
8110
8111            mounted = status.equals(Environment.MEDIA_MOUNTED)
8112                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
8113        }
8114
8115        if (!mounted) {
8116            return;
8117        }
8118
8119        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
8120        int[] users;
8121        if (userId == UserHandle.USER_ALL) {
8122            users = sUserManager.getUserIds();
8123        } else {
8124            users = new int[] { userId };
8125        }
8126        for (int curUser : users) {
8127            ClearStorageConnection conn = new ClearStorageConnection();
8128            if (mContext.bindService(containerIntent, conn, Context.BIND_AUTO_CREATE, curUser)) {
8129                try {
8130                    long timeout = SystemClock.uptimeMillis() + 5000;
8131                    synchronized (conn) {
8132                        long now = SystemClock.uptimeMillis();
8133                        while (conn.mContainerService == null && now < timeout) {
8134                            try {
8135                                conn.wait(timeout - now);
8136                            } catch (InterruptedException e) {
8137                            }
8138                        }
8139                    }
8140                    if (conn.mContainerService == null) {
8141                        return;
8142                    }
8143                    final File externalCacheDir = Environment
8144                            .getExternalStorageAppCacheDirectory(packageName);
8145                    try {
8146                        conn.mContainerService.clearDirectory(externalCacheDir.toString());
8147                    } catch (RemoteException e) {
8148                    }
8149                    if (allData) {
8150                        final File externalDataDir = Environment
8151                                .getExternalStorageAppDataDirectory(packageName);
8152                        try {
8153                            conn.mContainerService.clearDirectory(externalDataDir.toString());
8154                        } catch (RemoteException e) {
8155                        }
8156                        final File externalMediaDir = Environment
8157                                .getExternalStorageAppMediaDirectory(packageName);
8158                        try {
8159                            conn.mContainerService.clearDirectory(externalMediaDir.toString());
8160                        } catch (RemoteException e) {
8161                        }
8162                    }
8163                } finally {
8164                    mContext.unbindService(conn);
8165                }
8166            }
8167        }
8168    }
8169
8170    @Override
8171    public void clearApplicationUserData(final String packageName,
8172            final IPackageDataObserver observer, final int userId) {
8173        mContext.enforceCallingOrSelfPermission(
8174                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
8175        checkValidCaller(Binder.getCallingUid(), userId);
8176        // Queue up an async operation since the package deletion may take a little while.
8177        mHandler.post(new Runnable() {
8178            public void run() {
8179                mHandler.removeCallbacks(this);
8180                final boolean succeeded;
8181                synchronized (mInstallLock) {
8182                    succeeded = clearApplicationUserDataLI(packageName, userId);
8183                }
8184                clearExternalStorageDataSync(packageName, userId, true);
8185                if (succeeded) {
8186                    // invoke DeviceStorageMonitor's update method to clear any notifications
8187                    DeviceStorageMonitorService dsm = (DeviceStorageMonitorService)
8188                            ServiceManager.getService(DeviceStorageMonitorService.SERVICE);
8189                    if (dsm != null) {
8190                        dsm.updateMemory();
8191                    }
8192                }
8193                if(observer != null) {
8194                    try {
8195                        observer.onRemoveCompleted(packageName, succeeded);
8196                    } catch (RemoteException e) {
8197                        Log.i(TAG, "Observer no longer exists.");
8198                    }
8199                } //end if observer
8200            } //end run
8201        });
8202    }
8203
8204    private boolean clearApplicationUserDataLI(String packageName, int userId) {
8205        if (packageName == null) {
8206            Slog.w(TAG, "Attempt to delete null packageName.");
8207            return false;
8208        }
8209        PackageParser.Package p;
8210        boolean dataOnly = false;
8211        synchronized (mPackages) {
8212            p = mPackages.get(packageName);
8213            if(p == null) {
8214                dataOnly = true;
8215                PackageSetting ps = mSettings.mPackages.get(packageName);
8216                if((ps == null) || (ps.pkg == null)) {
8217                    Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
8218                    return false;
8219                }
8220                p = ps.pkg;
8221            }
8222        }
8223
8224        if (!dataOnly) {
8225            //need to check this only for fully installed applications
8226            if (p == null) {
8227                Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
8228                return false;
8229            }
8230            final ApplicationInfo applicationInfo = p.applicationInfo;
8231            if (applicationInfo == null) {
8232                Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
8233                return false;
8234            }
8235        }
8236        int retCode = mInstaller.clearUserData(packageName, userId);
8237        if (retCode < 0) {
8238            Slog.w(TAG, "Couldn't remove cache files for package: "
8239                    + packageName);
8240            return false;
8241        }
8242        return true;
8243    }
8244
8245    public void deleteApplicationCacheFiles(final String packageName,
8246            final IPackageDataObserver observer) {
8247        mContext.enforceCallingOrSelfPermission(
8248                android.Manifest.permission.DELETE_CACHE_FILES, null);
8249        // Queue up an async operation since the package deletion may take a little while.
8250        final int userId = UserHandle.getCallingUserId();
8251        mHandler.post(new Runnable() {
8252            public void run() {
8253                mHandler.removeCallbacks(this);
8254                final boolean succeded;
8255                synchronized (mInstallLock) {
8256                    succeded = deleteApplicationCacheFilesLI(packageName, userId);
8257                }
8258                clearExternalStorageDataSync(packageName, userId, false);
8259                if(observer != null) {
8260                    try {
8261                        observer.onRemoveCompleted(packageName, succeded);
8262                    } catch (RemoteException e) {
8263                        Log.i(TAG, "Observer no longer exists.");
8264                    }
8265                } //end if observer
8266            } //end run
8267        });
8268    }
8269
8270    private boolean deleteApplicationCacheFilesLI(String packageName, int userId) {
8271        if (packageName == null) {
8272            Slog.w(TAG, "Attempt to delete null packageName.");
8273            return false;
8274        }
8275        PackageParser.Package p;
8276        synchronized (mPackages) {
8277            p = mPackages.get(packageName);
8278        }
8279        if (p == null) {
8280            Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
8281            return false;
8282        }
8283        final ApplicationInfo applicationInfo = p.applicationInfo;
8284        if (applicationInfo == null) {
8285            Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
8286            return false;
8287        }
8288        // TODO: Pass userId to deleteCacheFiles
8289        int retCode = mInstaller.deleteCacheFiles(packageName);
8290        if (retCode < 0) {
8291            Slog.w(TAG, "Couldn't remove cache files for package: "
8292                       + packageName);
8293            return false;
8294        }
8295        return true;
8296    }
8297
8298    public void getPackageSizeInfo(final String packageName, int userHandle,
8299            final IPackageStatsObserver observer) {
8300        mContext.enforceCallingOrSelfPermission(
8301                android.Manifest.permission.GET_PACKAGE_SIZE, null);
8302
8303        PackageStats stats = new PackageStats(packageName, userHandle);
8304
8305        /*
8306         * Queue up an async operation since the package measurement may take a
8307         * little while.
8308         */
8309        Message msg = mHandler.obtainMessage(INIT_COPY);
8310        msg.obj = new MeasureParams(stats, observer);
8311        mHandler.sendMessage(msg);
8312    }
8313
8314    private boolean getPackageSizeInfoLI(String packageName, int userHandle,
8315            PackageStats pStats) {
8316        if (packageName == null) {
8317            Slog.w(TAG, "Attempt to get size of null packageName.");
8318            return false;
8319        }
8320        PackageParser.Package p;
8321        boolean dataOnly = false;
8322        String asecPath = null;
8323        synchronized (mPackages) {
8324            p = mPackages.get(packageName);
8325            if(p == null) {
8326                dataOnly = true;
8327                PackageSetting ps = mSettings.mPackages.get(packageName);
8328                if((ps == null) || (ps.pkg == null)) {
8329                    Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
8330                    return false;
8331                }
8332                p = ps.pkg;
8333            }
8334            if (p != null && (isExternal(p) || isForwardLocked(p))) {
8335                String secureContainerId = cidFromCodePath(p.applicationInfo.sourceDir);
8336                if (secureContainerId != null) {
8337                    asecPath = PackageHelper.getSdFilesystem(secureContainerId);
8338                }
8339            }
8340        }
8341        String publicSrcDir = null;
8342        if(!dataOnly) {
8343            final ApplicationInfo applicationInfo = p.applicationInfo;
8344            if (applicationInfo == null) {
8345                Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
8346                return false;
8347            }
8348            if (isForwardLocked(p)) {
8349                publicSrcDir = applicationInfo.publicSourceDir;
8350            }
8351        }
8352        int res = mInstaller.getSizeInfo(packageName, userHandle, p.mPath, publicSrcDir,
8353                asecPath, pStats);
8354        if (res < 0) {
8355            return false;
8356        }
8357
8358        // Fix-up for forward-locked applications in ASEC containers.
8359        if (!isExternal(p)) {
8360            pStats.codeSize += pStats.externalCodeSize;
8361            pStats.externalCodeSize = 0L;
8362        }
8363
8364        return true;
8365    }
8366
8367
8368    public void addPackageToPreferred(String packageName) {
8369        Slog.w(TAG, "addPackageToPreferred: this is now a no-op");
8370    }
8371
8372    public void removePackageFromPreferred(String packageName) {
8373        Slog.w(TAG, "removePackageFromPreferred: this is now a no-op");
8374    }
8375
8376    public List<PackageInfo> getPreferredPackages(int flags) {
8377        return new ArrayList<PackageInfo>();
8378    }
8379
8380    private int getUidTargetSdkVersionLockedLPr(int uid) {
8381        Object obj = mSettings.getUserIdLPr(uid);
8382        if (obj instanceof SharedUserSetting) {
8383            final SharedUserSetting sus = (SharedUserSetting) obj;
8384            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
8385            final Iterator<PackageSetting> it = sus.packages.iterator();
8386            while (it.hasNext()) {
8387                final PackageSetting ps = it.next();
8388                if (ps.pkg != null) {
8389                    int v = ps.pkg.applicationInfo.targetSdkVersion;
8390                    if (v < vers) vers = v;
8391                }
8392            }
8393            return vers;
8394        } else if (obj instanceof PackageSetting) {
8395            final PackageSetting ps = (PackageSetting) obj;
8396            if (ps.pkg != null) {
8397                return ps.pkg.applicationInfo.targetSdkVersion;
8398            }
8399        }
8400        return Build.VERSION_CODES.CUR_DEVELOPMENT;
8401    }
8402
8403    public void addPreferredActivity(IntentFilter filter, int match,
8404            ComponentName[] set, ComponentName activity, int userId) {
8405        // writer
8406        int callingUid = Binder.getCallingUid();
8407        checkValidCaller(callingUid, userId);
8408        synchronized (mPackages) {
8409            if (mContext.checkCallingOrSelfPermission(
8410                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
8411                    != PackageManager.PERMISSION_GRANTED) {
8412                if (getUidTargetSdkVersionLockedLPr(callingUid)
8413                        < Build.VERSION_CODES.FROYO) {
8414                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
8415                            + callingUid);
8416                    return;
8417                }
8418                mContext.enforceCallingOrSelfPermission(
8419                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
8420            }
8421
8422            Slog.i(TAG, "Adding preferred activity " + activity + " for user " + userId + " :");
8423            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
8424            mSettings.mPreferredActivities.addFilter(
8425                    new PreferredActivity(filter, match, set, activity, userId));
8426            scheduleWriteSettingsLocked();
8427        }
8428    }
8429
8430    public void replacePreferredActivity(IntentFilter filter, int match,
8431            ComponentName[] set, ComponentName activity) {
8432        if (filter.countActions() != 1) {
8433            throw new IllegalArgumentException(
8434                    "replacePreferredActivity expects filter to have only 1 action.");
8435        }
8436        if (filter.countCategories() != 1) {
8437            throw new IllegalArgumentException(
8438                    "replacePreferredActivity expects filter to have only 1 category.");
8439        }
8440        if (filter.countDataAuthorities() != 0
8441                || filter.countDataPaths() != 0
8442                || filter.countDataSchemes() != 0
8443                || filter.countDataTypes() != 0) {
8444            throw new IllegalArgumentException(
8445                    "replacePreferredActivity expects filter to have no data authorities, " +
8446                    "paths, schemes or types.");
8447        }
8448        synchronized (mPackages) {
8449            if (mContext.checkCallingOrSelfPermission(
8450                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
8451                    != PackageManager.PERMISSION_GRANTED) {
8452                if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
8453                        < Build.VERSION_CODES.FROYO) {
8454                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
8455                            + Binder.getCallingUid());
8456                    return;
8457                }
8458                mContext.enforceCallingOrSelfPermission(
8459                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
8460            }
8461
8462            final int callingUserId = UserHandle.getCallingUserId();
8463            ArrayList<PreferredActivity> removed = null;
8464            Iterator<PreferredActivity> it = mSettings.mPreferredActivities.filterIterator();
8465            String action = filter.getAction(0);
8466            String category = filter.getCategory(0);
8467            while (it.hasNext()) {
8468                PreferredActivity pa = it.next();
8469                if (pa.mUserId != callingUserId) continue;
8470                if (pa.getAction(0).equals(action) && pa.getCategory(0).equals(category)) {
8471                    if (removed == null) {
8472                        removed = new ArrayList<PreferredActivity>();
8473                    }
8474                    removed.add(pa);
8475                    Log.i(TAG, "Removing preferred activity " + pa.mPref.mComponent + ":");
8476                    filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
8477                }
8478            }
8479            if (removed != null) {
8480                for (int i=0; i<removed.size(); i++) {
8481                    PreferredActivity pa = removed.get(i);
8482                    mSettings.mPreferredActivities.removeFilter(pa);
8483                }
8484            }
8485            addPreferredActivity(filter, match, set, activity, callingUserId);
8486        }
8487    }
8488
8489    public void clearPackagePreferredActivities(String packageName) {
8490        final int uid = Binder.getCallingUid();
8491        // writer
8492        synchronized (mPackages) {
8493            PackageParser.Package pkg = mPackages.get(packageName);
8494            if (pkg == null || pkg.applicationInfo.uid != uid) {
8495                if (mContext.checkCallingOrSelfPermission(
8496                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
8497                        != PackageManager.PERMISSION_GRANTED) {
8498                    if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
8499                            < Build.VERSION_CODES.FROYO) {
8500                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
8501                                + Binder.getCallingUid());
8502                        return;
8503                    }
8504                    mContext.enforceCallingOrSelfPermission(
8505                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
8506                }
8507            }
8508
8509            if (clearPackagePreferredActivitiesLPw(packageName, UserHandle.getCallingUserId())) {
8510                scheduleWriteSettingsLocked();
8511            }
8512        }
8513    }
8514
8515    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
8516    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
8517        ArrayList<PreferredActivity> removed = null;
8518        Iterator<PreferredActivity> it = mSettings.mPreferredActivities.filterIterator();
8519        while (it.hasNext()) {
8520            PreferredActivity pa = it.next();
8521            if (userId != UserHandle.USER_ALL && pa.mUserId != userId) {
8522                continue;
8523            }
8524            if (pa.mPref.mComponent.getPackageName().equals(packageName)) {
8525                if (removed == null) {
8526                    removed = new ArrayList<PreferredActivity>();
8527                }
8528                removed.add(pa);
8529            }
8530        }
8531        if (removed != null) {
8532            for (int i=0; i<removed.size(); i++) {
8533                PreferredActivity pa = removed.get(i);
8534                mSettings.mPreferredActivities.removeFilter(pa);
8535            }
8536            return true;
8537        }
8538        return false;
8539    }
8540
8541    public int getPreferredActivities(List<IntentFilter> outFilters,
8542            List<ComponentName> outActivities, String packageName) {
8543
8544        int num = 0;
8545        final int userId = UserHandle.getCallingUserId();
8546        // reader
8547        synchronized (mPackages) {
8548            final Iterator<PreferredActivity> it = mSettings.mPreferredActivities.filterIterator();
8549            while (it.hasNext()) {
8550                final PreferredActivity pa = it.next();
8551                if (pa.mUserId != userId) {
8552                    continue;
8553                }
8554                if (packageName == null
8555                        || pa.mPref.mComponent.getPackageName().equals(packageName)) {
8556                    if (outFilters != null) {
8557                        outFilters.add(new IntentFilter(pa));
8558                    }
8559                    if (outActivities != null) {
8560                        outActivities.add(pa.mPref.mComponent);
8561                    }
8562                }
8563            }
8564        }
8565
8566        return num;
8567    }
8568
8569    @Override
8570    public void setApplicationEnabledSetting(String appPackageName,
8571            int newState, int flags, int userId) {
8572        if (!sUserManager.exists(userId)) return;
8573        setEnabledSetting(appPackageName, null, newState, flags, userId);
8574    }
8575
8576    @Override
8577    public void setComponentEnabledSetting(ComponentName componentName,
8578            int newState, int flags, int userId) {
8579        if (!sUserManager.exists(userId)) return;
8580        setEnabledSetting(componentName.getPackageName(),
8581                componentName.getClassName(), newState, flags, userId);
8582    }
8583
8584    private void setEnabledSetting(
8585            final String packageName, String className, int newState, final int flags, int userId) {
8586        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
8587              || newState == COMPONENT_ENABLED_STATE_ENABLED
8588              || newState == COMPONENT_ENABLED_STATE_DISABLED
8589              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER)) {
8590            throw new IllegalArgumentException("Invalid new component state: "
8591                    + newState);
8592        }
8593        PackageSetting pkgSetting;
8594        final int uid = Binder.getCallingUid();
8595        final int permission = mContext.checkCallingPermission(
8596                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
8597        checkValidCaller(uid, userId);
8598        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
8599        boolean sendNow = false;
8600        boolean isApp = (className == null);
8601        String componentName = isApp ? packageName : className;
8602        int packageUid = -1;
8603        ArrayList<String> components;
8604
8605        // writer
8606        synchronized (mPackages) {
8607            pkgSetting = mSettings.mPackages.get(packageName);
8608            if (pkgSetting == null) {
8609                if (className == null) {
8610                    throw new IllegalArgumentException(
8611                            "Unknown package: " + packageName);
8612                }
8613                throw new IllegalArgumentException(
8614                        "Unknown component: " + packageName
8615                        + "/" + className);
8616            }
8617            // Allow root and verify that userId is not being specified by a different user
8618            if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) {
8619                throw new SecurityException(
8620                        "Permission Denial: attempt to change component state from pid="
8621                        + Binder.getCallingPid()
8622                        + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
8623            }
8624            if (className == null) {
8625                // We're dealing with an application/package level state change
8626                if (pkgSetting.getEnabled(userId) == newState) {
8627                    // Nothing to do
8628                    return;
8629                }
8630                pkgSetting.setEnabled(newState, userId);
8631                // pkgSetting.pkg.mSetEnabled = newState;
8632            } else {
8633                // We're dealing with a component level state change
8634                // First, verify that this is a valid class name.
8635                PackageParser.Package pkg = pkgSetting.pkg;
8636                if (pkg == null || !pkg.hasComponentClassName(className)) {
8637                    if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) {
8638                        throw new IllegalArgumentException("Component class " + className
8639                                + " does not exist in " + packageName);
8640                    } else {
8641                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
8642                                + className + " does not exist in " + packageName);
8643                    }
8644                }
8645                switch (newState) {
8646                case COMPONENT_ENABLED_STATE_ENABLED:
8647                    if (!pkgSetting.enableComponentLPw(className, userId)) {
8648                        return;
8649                    }
8650                    break;
8651                case COMPONENT_ENABLED_STATE_DISABLED:
8652                    if (!pkgSetting.disableComponentLPw(className, userId)) {
8653                        return;
8654                    }
8655                    break;
8656                case COMPONENT_ENABLED_STATE_DEFAULT:
8657                    if (!pkgSetting.restoreComponentLPw(className, userId)) {
8658                        return;
8659                    }
8660                    break;
8661                default:
8662                    Slog.e(TAG, "Invalid new component state: " + newState);
8663                    return;
8664                }
8665            }
8666            mSettings.writePackageRestrictionsLPr(userId);
8667            packageUid = UserHandle.getUid(userId, pkgSetting.appId);
8668            components = mPendingBroadcasts.get(packageName);
8669            final boolean newPackage = components == null;
8670            if (newPackage) {
8671                components = new ArrayList<String>();
8672            }
8673            if (!components.contains(componentName)) {
8674                components.add(componentName);
8675            }
8676            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
8677                sendNow = true;
8678                // Purge entry from pending broadcast list if another one exists already
8679                // since we are sending one right away.
8680                mPendingBroadcasts.remove(packageName);
8681            } else {
8682                if (newPackage) {
8683                    mPendingBroadcasts.put(packageName, components);
8684                }
8685                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
8686                    // Schedule a message
8687                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
8688                }
8689            }
8690        }
8691
8692        long callingId = Binder.clearCallingIdentity();
8693        try {
8694            if (sendNow) {
8695                sendPackageChangedBroadcast(packageName,
8696                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
8697            }
8698        } finally {
8699            Binder.restoreCallingIdentity(callingId);
8700        }
8701    }
8702
8703    private void sendPackageChangedBroadcast(String packageName,
8704            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
8705        if (DEBUG_INSTALL)
8706            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
8707                    + componentNames);
8708        Bundle extras = new Bundle(4);
8709        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
8710        String nameList[] = new String[componentNames.size()];
8711        componentNames.toArray(nameList);
8712        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
8713        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
8714        extras.putInt(Intent.EXTRA_UID, packageUid);
8715        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, null, null,
8716                new int[] {UserHandle.getUserId(packageUid)});
8717    }
8718
8719    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
8720        if (!sUserManager.exists(userId)) return;
8721        final int uid = Binder.getCallingUid();
8722        final int permission = mContext.checkCallingOrSelfPermission(
8723                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
8724        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
8725        checkValidCaller(uid, userId);
8726        // writer
8727        synchronized (mPackages) {
8728            if (mSettings.setPackageStoppedStateLPw(packageName, stopped, allowedByPermission,
8729                    uid, userId)) {
8730                scheduleWritePackageRestrictionsLocked(userId);
8731            }
8732        }
8733    }
8734
8735    public String getInstallerPackageName(String packageName) {
8736        // reader
8737        synchronized (mPackages) {
8738            return mSettings.getInstallerPackageNameLPr(packageName);
8739        }
8740    }
8741
8742    @Override
8743    public int getApplicationEnabledSetting(String packageName, int userId) {
8744        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
8745        int uid = Binder.getCallingUid();
8746        checkValidCaller(uid, userId);
8747        // reader
8748        synchronized (mPackages) {
8749            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
8750        }
8751    }
8752
8753    @Override
8754    public int getComponentEnabledSetting(ComponentName componentName, int userId) {
8755        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
8756        int uid = Binder.getCallingUid();
8757        checkValidCaller(uid, userId);
8758        // reader
8759        synchronized (mPackages) {
8760            return mSettings.getComponentEnabledSettingLPr(componentName, userId);
8761        }
8762    }
8763
8764    public void enterSafeMode() {
8765        enforceSystemOrRoot("Only the system can request entering safe mode");
8766
8767        if (!mSystemReady) {
8768            mSafeMode = true;
8769        }
8770    }
8771
8772    public void systemReady() {
8773        mSystemReady = true;
8774
8775        // Read the compatibilty setting when the system is ready.
8776        boolean compatibilityModeEnabled = android.provider.Settings.System.getInt(
8777                mContext.getContentResolver(),
8778                android.provider.Settings.System.COMPATIBILITY_MODE, 1) == 1;
8779        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
8780        if (DEBUG_SETTINGS) {
8781            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
8782        }
8783    }
8784
8785    public boolean isSafeMode() {
8786        return mSafeMode;
8787    }
8788
8789    public boolean hasSystemUidErrors() {
8790        return mHasSystemUidErrors;
8791    }
8792
8793    static String arrayToString(int[] array) {
8794        StringBuffer buf = new StringBuffer(128);
8795        buf.append('[');
8796        if (array != null) {
8797            for (int i=0; i<array.length; i++) {
8798                if (i > 0) buf.append(", ");
8799                buf.append(array[i]);
8800            }
8801        }
8802        buf.append(']');
8803        return buf.toString();
8804    }
8805
8806    static class DumpState {
8807        public static final int DUMP_LIBS = 1 << 0;
8808
8809        public static final int DUMP_FEATURES = 1 << 1;
8810
8811        public static final int DUMP_RESOLVERS = 1 << 2;
8812
8813        public static final int DUMP_PERMISSIONS = 1 << 3;
8814
8815        public static final int DUMP_PACKAGES = 1 << 4;
8816
8817        public static final int DUMP_SHARED_USERS = 1 << 5;
8818
8819        public static final int DUMP_MESSAGES = 1 << 6;
8820
8821        public static final int DUMP_PROVIDERS = 1 << 7;
8822
8823        public static final int DUMP_VERIFIERS = 1 << 8;
8824
8825        public static final int DUMP_PREFERRED = 1 << 9;
8826
8827        public static final int DUMP_PREFERRED_XML = 1 << 10;
8828
8829        public static final int OPTION_SHOW_FILTERS = 1 << 0;
8830
8831        private int mTypes;
8832
8833        private int mOptions;
8834
8835        private boolean mTitlePrinted;
8836
8837        private SharedUserSetting mSharedUser;
8838
8839        public boolean isDumping(int type) {
8840            if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
8841                return true;
8842            }
8843
8844            return (mTypes & type) != 0;
8845        }
8846
8847        public void setDump(int type) {
8848            mTypes |= type;
8849        }
8850
8851        public boolean isOptionEnabled(int option) {
8852            return (mOptions & option) != 0;
8853        }
8854
8855        public void setOptionEnabled(int option) {
8856            mOptions |= option;
8857        }
8858
8859        public boolean onTitlePrinted() {
8860            final boolean printed = mTitlePrinted;
8861            mTitlePrinted = true;
8862            return printed;
8863        }
8864
8865        public boolean getTitlePrinted() {
8866            return mTitlePrinted;
8867        }
8868
8869        public void setTitlePrinted(boolean enabled) {
8870            mTitlePrinted = enabled;
8871        }
8872
8873        public SharedUserSetting getSharedUser() {
8874            return mSharedUser;
8875        }
8876
8877        public void setSharedUser(SharedUserSetting user) {
8878            mSharedUser = user;
8879        }
8880    }
8881
8882    @Override
8883    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8884        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
8885                != PackageManager.PERMISSION_GRANTED) {
8886            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8887                    + Binder.getCallingPid()
8888                    + ", uid=" + Binder.getCallingUid()
8889                    + " without permission "
8890                    + android.Manifest.permission.DUMP);
8891            return;
8892        }
8893
8894        DumpState dumpState = new DumpState();
8895
8896        String packageName = null;
8897
8898        int opti = 0;
8899        while (opti < args.length) {
8900            String opt = args[opti];
8901            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8902                break;
8903            }
8904            opti++;
8905            if ("-a".equals(opt)) {
8906                // Right now we only know how to print all.
8907            } else if ("-h".equals(opt)) {
8908                pw.println("Package manager dump options:");
8909                pw.println("  [-h] [-f] [cmd] ...");
8910                pw.println("    -f: print details of intent filters");
8911                pw.println("    -h: print this help");
8912                pw.println("  cmd may be one of:");
8913                pw.println("    l[ibraries]: list known shared libraries");
8914                pw.println("    f[ibraries]: list device features");
8915                pw.println("    r[esolvers]: dump intent resolvers");
8916                pw.println("    perm[issions]: dump permissions");
8917                pw.println("    pref[erred]: print preferred package settings");
8918                pw.println("    preferred-xml: print preferred package settings as xml");
8919                pw.println("    prov[iders]: dump content providers");
8920                pw.println("    p[ackages]: dump installed packages");
8921                pw.println("    s[hared-users]: dump shared user IDs");
8922                pw.println("    m[essages]: print collected runtime messages");
8923                pw.println("    v[erifiers]: print package verifier info");
8924                pw.println("    <package.name>: info about given package");
8925                return;
8926            } else if ("-f".equals(opt)) {
8927                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
8928            } else {
8929                pw.println("Unknown argument: " + opt + "; use -h for help");
8930            }
8931        }
8932
8933        // Is the caller requesting to dump a particular piece of data?
8934        if (opti < args.length) {
8935            String cmd = args[opti];
8936            opti++;
8937            // Is this a package name?
8938            if ("android".equals(cmd) || cmd.contains(".")) {
8939                packageName = cmd;
8940            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
8941                dumpState.setDump(DumpState.DUMP_LIBS);
8942            } else if ("f".equals(cmd) || "features".equals(cmd)) {
8943                dumpState.setDump(DumpState.DUMP_FEATURES);
8944            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
8945                dumpState.setDump(DumpState.DUMP_RESOLVERS);
8946            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
8947                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
8948            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
8949                dumpState.setDump(DumpState.DUMP_PREFERRED);
8950            } else if ("preferred-xml".equals(cmd)) {
8951                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
8952            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
8953                dumpState.setDump(DumpState.DUMP_PACKAGES);
8954            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
8955                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
8956            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
8957                dumpState.setDump(DumpState.DUMP_PROVIDERS);
8958            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
8959                dumpState.setDump(DumpState.DUMP_MESSAGES);
8960            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
8961                dumpState.setDump(DumpState.DUMP_VERIFIERS);
8962            }
8963        }
8964
8965        // reader
8966        synchronized (mPackages) {
8967            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
8968                if (dumpState.onTitlePrinted())
8969                    pw.println(" ");
8970                pw.println("Verifiers:");
8971                pw.print("  Required: ");
8972                pw.print(mRequiredVerifierPackage);
8973                pw.print(" (uid=");
8974                pw.print(getPackageUid(mRequiredVerifierPackage, 0));
8975                pw.println(")");
8976            }
8977
8978            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
8979                if (dumpState.onTitlePrinted())
8980                    pw.println(" ");
8981                pw.println("Libraries:");
8982                final Iterator<String> it = mSharedLibraries.keySet().iterator();
8983                while (it.hasNext()) {
8984                    String name = it.next();
8985                    pw.print("  ");
8986                    pw.print(name);
8987                    pw.print(" -> ");
8988                    pw.println(mSharedLibraries.get(name));
8989                }
8990            }
8991
8992            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
8993                if (dumpState.onTitlePrinted())
8994                    pw.println(" ");
8995                pw.println("Features:");
8996                Iterator<String> it = mAvailableFeatures.keySet().iterator();
8997                while (it.hasNext()) {
8998                    String name = it.next();
8999                    pw.print("  ");
9000                    pw.println(name);
9001                }
9002            }
9003
9004            if (dumpState.isDumping(DumpState.DUMP_RESOLVERS)) {
9005                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
9006                        : "Activity Resolver Table:", "  ", packageName,
9007                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
9008                    dumpState.setTitlePrinted(true);
9009                }
9010                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
9011                        : "Receiver Resolver Table:", "  ", packageName,
9012                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
9013                    dumpState.setTitlePrinted(true);
9014                }
9015                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
9016                        : "Service Resolver Table:", "  ", packageName,
9017                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
9018                    dumpState.setTitlePrinted(true);
9019                }
9020            }
9021
9022            if (dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
9023                if (mSettings.mPreferredActivities.dump(pw,
9024                        dumpState.getTitlePrinted() ? "\nPreferred Activities:"
9025                            : "Preferred Activities:", "  ",
9026                        packageName, dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
9027                    dumpState.setTitlePrinted(true);
9028                }
9029            }
9030
9031            if (dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
9032                pw.flush();
9033                FileOutputStream fout = new FileOutputStream(fd);
9034                BufferedOutputStream str = new BufferedOutputStream(fout);
9035                XmlSerializer serializer = new FastXmlSerializer();
9036                try {
9037                    serializer.setOutput(str, "utf-8");
9038                    serializer.startDocument(null, true);
9039                    serializer.setFeature(
9040                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
9041                    mSettings.writePreferredActivitiesLPr(serializer);
9042                    serializer.endDocument();
9043                    serializer.flush();
9044                } catch (IllegalArgumentException e) {
9045                    pw.println("Failed writing: " + e);
9046                } catch (IllegalStateException e) {
9047                    pw.println("Failed writing: " + e);
9048                } catch (IOException e) {
9049                    pw.println("Failed writing: " + e);
9050                }
9051            }
9052
9053            if (dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
9054                mSettings.dumpPermissionsLPr(pw, packageName, dumpState);
9055            }
9056
9057            if (dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
9058                boolean printedSomething = false;
9059                for (PackageParser.Provider p : mProvidersByComponent.values()) {
9060                    if (packageName != null && !packageName.equals(p.info.packageName)) {
9061                        continue;
9062                    }
9063                    if (!printedSomething) {
9064                        if (dumpState.onTitlePrinted())
9065                            pw.println(" ");
9066                        pw.println("Registered ContentProviders:");
9067                        printedSomething = true;
9068                    }
9069                    pw.print("  "); pw.print(p.getComponentShortName()); pw.println(":");
9070                    pw.print("    "); pw.println(p.toString());
9071                }
9072                printedSomething = false;
9073                for (Map.Entry<String, PackageParser.Provider> entry : mProviders.entrySet()) {
9074                    PackageParser.Provider p = entry.getValue();
9075                    if (packageName != null && !packageName.equals(p.info.packageName)) {
9076                        continue;
9077                    }
9078                    if (!printedSomething) {
9079                        if (dumpState.onTitlePrinted())
9080                            pw.println(" ");
9081                        pw.println("ContentProvider Authorities:");
9082                        printedSomething = true;
9083                    }
9084                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
9085                    pw.print("    "); pw.println(p.toString());
9086                    if (p.info != null && p.info.applicationInfo != null) {
9087                        final String appInfo = p.info.applicationInfo.toString();
9088                        pw.print("      applicationInfo="); pw.println(appInfo);
9089                    }
9090                }
9091            }
9092
9093            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
9094                mSettings.dumpPackagesLPr(pw, packageName, dumpState);
9095            }
9096
9097            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
9098                mSettings.dumpSharedUsersLPr(pw, packageName, dumpState);
9099            }
9100
9101            if (dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
9102                if (dumpState.onTitlePrinted())
9103                    pw.println(" ");
9104                mSettings.dumpReadMessagesLPr(pw, dumpState);
9105
9106                pw.println(" ");
9107                pw.println("Package warning messages:");
9108                final File fname = getSettingsProblemFile();
9109                FileInputStream in = null;
9110                try {
9111                    in = new FileInputStream(fname);
9112                    final int avail = in.available();
9113                    final byte[] data = new byte[avail];
9114                    in.read(data);
9115                    pw.print(new String(data));
9116                } catch (FileNotFoundException e) {
9117                } catch (IOException e) {
9118                } finally {
9119                    if (in != null) {
9120                        try {
9121                            in.close();
9122                        } catch (IOException e) {
9123                        }
9124                    }
9125                }
9126            }
9127        }
9128    }
9129
9130    // ------- apps on sdcard specific code -------
9131    static final boolean DEBUG_SD_INSTALL = false;
9132
9133    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
9134
9135    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
9136
9137    private boolean mMediaMounted = false;
9138
9139    private String getEncryptKey() {
9140        try {
9141            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
9142                    SD_ENCRYPTION_KEYSTORE_NAME);
9143            if (sdEncKey == null) {
9144                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
9145                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
9146                if (sdEncKey == null) {
9147                    Slog.e(TAG, "Failed to create encryption keys");
9148                    return null;
9149                }
9150            }
9151            return sdEncKey;
9152        } catch (NoSuchAlgorithmException nsae) {
9153            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
9154            return null;
9155        } catch (IOException ioe) {
9156            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
9157            return null;
9158        }
9159
9160    }
9161
9162    /* package */static String getTempContainerId() {
9163        int tmpIdx = 1;
9164        String list[] = PackageHelper.getSecureContainerList();
9165        if (list != null) {
9166            for (final String name : list) {
9167                // Ignore null and non-temporary container entries
9168                if (name == null || !name.startsWith(mTempContainerPrefix)) {
9169                    continue;
9170                }
9171
9172                String subStr = name.substring(mTempContainerPrefix.length());
9173                try {
9174                    int cid = Integer.parseInt(subStr);
9175                    if (cid >= tmpIdx) {
9176                        tmpIdx = cid + 1;
9177                    }
9178                } catch (NumberFormatException e) {
9179                }
9180            }
9181        }
9182        return mTempContainerPrefix + tmpIdx;
9183    }
9184
9185    /*
9186     * Update media status on PackageManager.
9187     */
9188    public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
9189        int callingUid = Binder.getCallingUid();
9190        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9191            throw new SecurityException("Media status can only be updated by the system");
9192        }
9193        // reader; this apparently protects mMediaMounted, but should probably
9194        // be a different lock in that case.
9195        synchronized (mPackages) {
9196            Log.i(TAG, "Updating external media status from "
9197                    + (mMediaMounted ? "mounted" : "unmounted") + " to "
9198                    + (mediaStatus ? "mounted" : "unmounted"));
9199            if (DEBUG_SD_INSTALL)
9200                Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
9201                        + ", mMediaMounted=" + mMediaMounted);
9202            if (mediaStatus == mMediaMounted) {
9203                final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
9204                        : 0, -1);
9205                mHandler.sendMessage(msg);
9206                return;
9207            }
9208            mMediaMounted = mediaStatus;
9209        }
9210        // Queue up an async operation since the package installation may take a
9211        // little while.
9212        mHandler.post(new Runnable() {
9213            public void run() {
9214                updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
9215            }
9216        });
9217    }
9218
9219    /**
9220     * Called by MountService when the initial ASECs to scan are available.
9221     * Should block until all the ASEC containers are finished being scanned.
9222     */
9223    public void scanAvailableAsecs() {
9224        updateExternalMediaStatusInner(true, false, false);
9225    }
9226
9227    /*
9228     * Collect information of applications on external media, map them against
9229     * existing containers and update information based on current mount status.
9230     * Please note that we always have to report status if reportStatus has been
9231     * set to true especially when unloading packages.
9232     */
9233    private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
9234            boolean externalStorage) {
9235        // Collection of uids
9236        int uidArr[] = null;
9237        // Collection of stale containers
9238        HashSet<String> removeCids = new HashSet<String>();
9239        // Collection of packages on external media with valid containers.
9240        HashMap<AsecInstallArgs, String> processCids = new HashMap<AsecInstallArgs, String>();
9241        // Get list of secure containers.
9242        final String list[] = PackageHelper.getSecureContainerList();
9243        if (list == null || list.length == 0) {
9244            Log.i(TAG, "No secure containers on sdcard");
9245        } else {
9246            // Process list of secure containers and categorize them
9247            // as active or stale based on their package internal state.
9248            int uidList[] = new int[list.length];
9249            int num = 0;
9250            // reader
9251            synchronized (mPackages) {
9252                for (String cid : list) {
9253                    if (DEBUG_SD_INSTALL)
9254                        Log.i(TAG, "Processing container " + cid);
9255                    String pkgName = getAsecPackageName(cid);
9256                    if (pkgName == null) {
9257                        if (DEBUG_SD_INSTALL)
9258                            Log.i(TAG, "Container : " + cid + " stale");
9259                        removeCids.add(cid);
9260                        continue;
9261                    }
9262                    if (DEBUG_SD_INSTALL)
9263                        Log.i(TAG, "Looking for pkg : " + pkgName);
9264
9265                    final PackageSetting ps = mSettings.mPackages.get(pkgName);
9266                    if (ps == null) {
9267                        Log.i(TAG, "Deleting container with no matching settings " + cid);
9268                        removeCids.add(cid);
9269                        continue;
9270                    }
9271
9272                    /*
9273                     * Skip packages that are not external if we're unmounting
9274                     * external storage.
9275                     */
9276                    if (externalStorage && !isMounted && !isExternal(ps)) {
9277                        continue;
9278                    }
9279
9280                    final AsecInstallArgs args = new AsecInstallArgs(cid, isForwardLocked(ps));
9281                    // The package status is changed only if the code path
9282                    // matches between settings and the container id.
9283                    if (ps.codePathString != null && ps.codePathString.equals(args.getCodePath())) {
9284                        if (DEBUG_SD_INSTALL) {
9285                            Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
9286                                    + " at code path: " + ps.codePathString);
9287                        }
9288
9289                        // We do have a valid package installed on sdcard
9290                        processCids.put(args, ps.codePathString);
9291                        final int uid = ps.appId;
9292                        if (uid != -1) {
9293                            uidList[num++] = uid;
9294                        }
9295                    } else {
9296                        Log.i(TAG, "Deleting stale container for " + cid);
9297                        removeCids.add(cid);
9298                    }
9299                }
9300            }
9301
9302            if (num > 0) {
9303                // Sort uid list
9304                Arrays.sort(uidList, 0, num);
9305                // Throw away duplicates
9306                uidArr = new int[num];
9307                uidArr[0] = uidList[0];
9308                int di = 0;
9309                for (int i = 1; i < num; i++) {
9310                    if (uidList[i - 1] != uidList[i]) {
9311                        uidArr[di++] = uidList[i];
9312                    }
9313                }
9314            }
9315        }
9316        // Process packages with valid entries.
9317        if (isMounted) {
9318            if (DEBUG_SD_INSTALL)
9319                Log.i(TAG, "Loading packages");
9320            loadMediaPackages(processCids, uidArr, removeCids);
9321            startCleaningPackages(-1);
9322        } else {
9323            if (DEBUG_SD_INSTALL)
9324                Log.i(TAG, "Unloading packages");
9325            unloadMediaPackages(processCids, uidArr, reportStatus);
9326        }
9327    }
9328
9329   private void sendResourcesChangedBroadcast(boolean mediaStatus, ArrayList<String> pkgList,
9330            int uidArr[], IIntentReceiver finishedReceiver) {
9331        int size = pkgList.size();
9332        if (size > 0) {
9333            // Send broadcasts here
9334            Bundle extras = new Bundle();
9335            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList
9336                    .toArray(new String[size]));
9337            if (uidArr != null) {
9338                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
9339            }
9340            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
9341                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
9342            sendPackageBroadcast(action, null, extras, null, finishedReceiver, null);
9343        }
9344    }
9345
9346   /*
9347     * Look at potentially valid container ids from processCids If package
9348     * information doesn't match the one on record or package scanning fails,
9349     * the cid is added to list of removeCids. We currently don't delete stale
9350     * containers.
9351     */
9352   private void loadMediaPackages(HashMap<AsecInstallArgs, String> processCids, int uidArr[],
9353            HashSet<String> removeCids) {
9354        ArrayList<String> pkgList = new ArrayList<String>();
9355        Set<AsecInstallArgs> keys = processCids.keySet();
9356        boolean doGc = false;
9357        for (AsecInstallArgs args : keys) {
9358            String codePath = processCids.get(args);
9359            if (DEBUG_SD_INSTALL)
9360                Log.i(TAG, "Loading container : " + args.cid);
9361            int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
9362            try {
9363                // Make sure there are no container errors first.
9364                if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
9365                    Slog.e(TAG, "Failed to mount cid : " + args.cid
9366                            + " when installing from sdcard");
9367                    continue;
9368                }
9369                // Check code path here.
9370                if (codePath == null || !codePath.equals(args.getCodePath())) {
9371                    Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
9372                            + " does not match one in settings " + codePath);
9373                    continue;
9374                }
9375                // Parse package
9376                int parseFlags = mDefParseFlags;
9377                if (args.isExternal()) {
9378                    parseFlags |= PackageParser.PARSE_ON_SDCARD;
9379                }
9380                if (args.isFwdLocked()) {
9381                    parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
9382                }
9383
9384                doGc = true;
9385                synchronized (mInstallLock) {
9386                    final PackageParser.Package pkg = scanPackageLI(new File(codePath), parseFlags,
9387                            0, 0, null);
9388                    // Scan the package
9389                    if (pkg != null) {
9390                        /*
9391                         * TODO why is the lock being held? doPostInstall is
9392                         * called in other places without the lock. This needs
9393                         * to be straightened out.
9394                         */
9395                        // writer
9396                        synchronized (mPackages) {
9397                            retCode = PackageManager.INSTALL_SUCCEEDED;
9398                            pkgList.add(pkg.packageName);
9399                            // Post process args
9400                            args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
9401                                    pkg.applicationInfo.uid);
9402                        }
9403                    } else {
9404                        Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
9405                    }
9406                }
9407
9408            } finally {
9409                if (retCode != PackageManager.INSTALL_SUCCEEDED) {
9410                    // Don't destroy container here. Wait till gc clears things
9411                    // up.
9412                    removeCids.add(args.cid);
9413                }
9414            }
9415        }
9416        // writer
9417        synchronized (mPackages) {
9418            // If the platform SDK has changed since the last time we booted,
9419            // we need to re-grant app permission to catch any new ones that
9420            // appear. This is really a hack, and means that apps can in some
9421            // cases get permissions that the user didn't initially explicitly
9422            // allow... it would be nice to have some better way to handle
9423            // this situation.
9424            final boolean regrantPermissions = mSettings.mExternalSdkPlatform != mSdkVersion;
9425            if (regrantPermissions)
9426                Slog.i(TAG, "Platform changed from " + mSettings.mExternalSdkPlatform + " to "
9427                        + mSdkVersion + "; regranting permissions for external storage");
9428            mSettings.mExternalSdkPlatform = mSdkVersion;
9429
9430            // Make sure group IDs have been assigned, and any permission
9431            // changes in other apps are accounted for
9432            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
9433                    | (regrantPermissions
9434                            ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
9435                            : 0));
9436            // can downgrade to reader
9437            // Persist settings
9438            mSettings.writeLPr();
9439        }
9440        // Send a broadcast to let everyone know we are done processing
9441        if (pkgList.size() > 0) {
9442            sendResourcesChangedBroadcast(true, pkgList, uidArr, null);
9443        }
9444        // Force gc to avoid any stale parser references that we might have.
9445        if (doGc) {
9446            Runtime.getRuntime().gc();
9447        }
9448        // List stale containers and destroy stale temporary containers.
9449        if (removeCids != null) {
9450            for (String cid : removeCids) {
9451                if (cid.startsWith(mTempContainerPrefix)) {
9452                    Log.i(TAG, "Destroying stale temporary container " + cid);
9453                    PackageHelper.destroySdDir(cid);
9454                } else {
9455                    Log.w(TAG, "Container " + cid + " is stale");
9456               }
9457           }
9458        }
9459    }
9460
9461   /*
9462     * Utility method to unload a list of specified containers
9463     */
9464    private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
9465        // Just unmount all valid containers.
9466        for (AsecInstallArgs arg : cidArgs) {
9467            synchronized (mInstallLock) {
9468                arg.doPostDeleteLI(false);
9469           }
9470       }
9471   }
9472
9473    /*
9474     * Unload packages mounted on external media. This involves deleting package
9475     * data from internal structures, sending broadcasts about diabled packages,
9476     * gc'ing to free up references, unmounting all secure containers
9477     * corresponding to packages on external media, and posting a
9478     * UPDATED_MEDIA_STATUS message if status has been requested. Please note
9479     * that we always have to post this message if status has been requested no
9480     * matter what.
9481     */
9482    private void unloadMediaPackages(HashMap<AsecInstallArgs, String> processCids, int uidArr[],
9483            final boolean reportStatus) {
9484        if (DEBUG_SD_INSTALL)
9485            Log.i(TAG, "unloading media packages");
9486        ArrayList<String> pkgList = new ArrayList<String>();
9487        ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
9488        final Set<AsecInstallArgs> keys = processCids.keySet();
9489        for (AsecInstallArgs args : keys) {
9490            String pkgName = args.getPackageName();
9491            if (DEBUG_SD_INSTALL)
9492                Log.i(TAG, "Trying to unload pkg : " + pkgName);
9493            // Delete package internally
9494            PackageRemovedInfo outInfo = new PackageRemovedInfo();
9495            synchronized (mInstallLock) {
9496                boolean res = deletePackageLI(pkgName, null, false,
9497                        PackageManager.DELETE_KEEP_DATA, outInfo, false);
9498                if (res) {
9499                    pkgList.add(pkgName);
9500                } else {
9501                    Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
9502                    failedList.add(args);
9503                }
9504            }
9505        }
9506
9507        // reader
9508        synchronized (mPackages) {
9509            // We didn't update the settings after removing each package;
9510            // write them now for all packages.
9511            mSettings.writeLPr();
9512        }
9513
9514        // We have to absolutely send UPDATED_MEDIA_STATUS only
9515        // after confirming that all the receivers processed the ordered
9516        // broadcast when packages get disabled, force a gc to clean things up.
9517        // and unload all the containers.
9518        if (pkgList.size() > 0) {
9519            sendResourcesChangedBroadcast(false, pkgList, uidArr, new IIntentReceiver.Stub() {
9520                public void performReceive(Intent intent, int resultCode, String data,
9521                        Bundle extras, boolean ordered, boolean sticky) throws RemoteException {
9522                    Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
9523                            reportStatus ? 1 : 0, 1, keys);
9524                    mHandler.sendMessage(msg);
9525                }
9526            });
9527        } else {
9528            Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
9529                    keys);
9530            mHandler.sendMessage(msg);
9531        }
9532    }
9533
9534    /** Binder call */
9535    @Override
9536    public void movePackage(final String packageName, final IPackageMoveObserver observer,
9537            final int flags) {
9538        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
9539        UserHandle user = new UserHandle(UserHandle.getCallingUserId());
9540        int returnCode = PackageManager.MOVE_SUCCEEDED;
9541        int currFlags = 0;
9542        int newFlags = 0;
9543        // reader
9544        synchronized (mPackages) {
9545            PackageParser.Package pkg = mPackages.get(packageName);
9546            if (pkg == null) {
9547                returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
9548            } else {
9549                // Disable moving fwd locked apps and system packages
9550                if (pkg.applicationInfo != null && isSystemApp(pkg)) {
9551                    Slog.w(TAG, "Cannot move system application");
9552                    returnCode = PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
9553                } else if (pkg.mOperationPending) {
9554                    Slog.w(TAG, "Attempt to move package which has pending operations");
9555                    returnCode = PackageManager.MOVE_FAILED_OPERATION_PENDING;
9556                } else {
9557                    // Find install location first
9558                    if ((flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0
9559                            && (flags & PackageManager.MOVE_INTERNAL) != 0) {
9560                        Slog.w(TAG, "Ambigous flags specified for move location.");
9561                        returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
9562                    } else {
9563                        newFlags = (flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 ? PackageManager.INSTALL_EXTERNAL
9564                                : PackageManager.INSTALL_INTERNAL;
9565                        currFlags = isExternal(pkg) ? PackageManager.INSTALL_EXTERNAL
9566                                : PackageManager.INSTALL_INTERNAL;
9567
9568                        if (newFlags == currFlags) {
9569                            Slog.w(TAG, "No move required. Trying to move to same location");
9570                            returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
9571                        } else {
9572                            if (isForwardLocked(pkg)) {
9573                                currFlags |= PackageManager.INSTALL_FORWARD_LOCK;
9574                                newFlags |= PackageManager.INSTALL_FORWARD_LOCK;
9575                            }
9576                        }
9577                    }
9578                    if (returnCode == PackageManager.MOVE_SUCCEEDED) {
9579                        pkg.mOperationPending = true;
9580                    }
9581                }
9582            }
9583
9584            /*
9585             * TODO this next block probably shouldn't be inside the lock. We
9586             * can't guarantee these won't change after this is fired off
9587             * anyway.
9588             */
9589            if (returnCode != PackageManager.MOVE_SUCCEEDED) {
9590                processPendingMove(new MoveParams(null, observer, 0, packageName,
9591                        null, -1, user),
9592                        returnCode);
9593            } else {
9594                Message msg = mHandler.obtainMessage(INIT_COPY);
9595                InstallArgs srcArgs = createInstallArgs(currFlags, pkg.applicationInfo.sourceDir,
9596                        pkg.applicationInfo.publicSourceDir, pkg.applicationInfo.nativeLibraryDir);
9597                MoveParams mp = new MoveParams(srcArgs, observer, newFlags, packageName,
9598                        pkg.applicationInfo.dataDir, pkg.applicationInfo.uid, user);
9599                msg.obj = mp;
9600                mHandler.sendMessage(msg);
9601            }
9602        }
9603    }
9604
9605    private void processPendingMove(final MoveParams mp, final int currentStatus) {
9606        // Queue up an async operation since the package deletion may take a
9607        // little while.
9608        mHandler.post(new Runnable() {
9609            public void run() {
9610                // TODO fix this; this does nothing.
9611                mHandler.removeCallbacks(this);
9612                int returnCode = currentStatus;
9613                if (currentStatus == PackageManager.MOVE_SUCCEEDED) {
9614                    int uidArr[] = null;
9615                    ArrayList<String> pkgList = null;
9616                    synchronized (mPackages) {
9617                        PackageParser.Package pkg = mPackages.get(mp.packageName);
9618                        if (pkg == null) {
9619                            Slog.w(TAG, " Package " + mp.packageName
9620                                    + " doesn't exist. Aborting move");
9621                            returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
9622                        } else if (!mp.srcArgs.getCodePath().equals(pkg.applicationInfo.sourceDir)) {
9623                            Slog.w(TAG, "Package " + mp.packageName + " code path changed from "
9624                                    + mp.srcArgs.getCodePath() + " to "
9625                                    + pkg.applicationInfo.sourceDir
9626                                    + " Aborting move and returning error");
9627                            returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
9628                        } else {
9629                            uidArr = new int[] {
9630                                pkg.applicationInfo.uid
9631                            };
9632                            pkgList = new ArrayList<String>();
9633                            pkgList.add(mp.packageName);
9634                        }
9635                    }
9636                    if (returnCode == PackageManager.MOVE_SUCCEEDED) {
9637                        // Send resources unavailable broadcast
9638                        sendResourcesChangedBroadcast(false, pkgList, uidArr, null);
9639                        // Update package code and resource paths
9640                        synchronized (mInstallLock) {
9641                            synchronized (mPackages) {
9642                                PackageParser.Package pkg = mPackages.get(mp.packageName);
9643                                // Recheck for package again.
9644                                if (pkg == null) {
9645                                    Slog.w(TAG, " Package " + mp.packageName
9646                                            + " doesn't exist. Aborting move");
9647                                    returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
9648                                } else if (!mp.srcArgs.getCodePath().equals(
9649                                        pkg.applicationInfo.sourceDir)) {
9650                                    Slog.w(TAG, "Package " + mp.packageName
9651                                            + " code path changed from " + mp.srcArgs.getCodePath()
9652                                            + " to " + pkg.applicationInfo.sourceDir
9653                                            + " Aborting move and returning error");
9654                                    returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
9655                                } else {
9656                                    final String oldCodePath = pkg.mPath;
9657                                    final String newCodePath = mp.targetArgs.getCodePath();
9658                                    final String newResPath = mp.targetArgs.getResourcePath();
9659                                    final String newNativePath = mp.targetArgs
9660                                            .getNativeLibraryPath();
9661
9662                                    try {
9663                                        final File newNativeDir = new File(newNativePath);
9664
9665                                        final String libParentDir = newNativeDir.getParentFile()
9666                                                .getCanonicalPath();
9667                                        if (newNativeDir.getParentFile().getCanonicalPath()
9668                                                .equals(pkg.applicationInfo.dataDir)) {
9669                                            if (mInstaller
9670                                                    .unlinkNativeLibraryDirectory(pkg.applicationInfo.dataDir) < 0) {
9671                                                returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
9672                                            } else {
9673                                                NativeLibraryHelper.copyNativeBinariesIfNeededLI(
9674                                                        new File(newCodePath), newNativeDir);
9675                                            }
9676                                        } else {
9677                                            if (mInstaller.linkNativeLibraryDirectory(
9678                                                    pkg.applicationInfo.dataDir, newNativePath) < 0) {
9679                                                returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
9680                                            }
9681                                        }
9682                                    } catch (IOException e) {
9683                                        returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
9684                                    }
9685
9686
9687                                    if (returnCode == PackageManager.MOVE_SUCCEEDED) {
9688                                        pkg.mPath = newCodePath;
9689                                        // Move dex files around
9690                                        if (moveDexFilesLI(pkg) != PackageManager.INSTALL_SUCCEEDED) {
9691                                            // Moving of dex files failed. Set
9692                                            // error code and abort move.
9693                                            pkg.mPath = pkg.mScanPath;
9694                                            returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
9695                                        }
9696                                    }
9697
9698                                    if (returnCode == PackageManager.MOVE_SUCCEEDED) {
9699                                        pkg.mScanPath = newCodePath;
9700                                        pkg.applicationInfo.sourceDir = newCodePath;
9701                                        pkg.applicationInfo.publicSourceDir = newResPath;
9702                                        pkg.applicationInfo.nativeLibraryDir = newNativePath;
9703                                        PackageSetting ps = (PackageSetting) pkg.mExtras;
9704                                        ps.codePath = new File(pkg.applicationInfo.sourceDir);
9705                                        ps.codePathString = ps.codePath.getPath();
9706                                        ps.resourcePath = new File(
9707                                                pkg.applicationInfo.publicSourceDir);
9708                                        ps.resourcePathString = ps.resourcePath.getPath();
9709                                        ps.nativeLibraryPathString = newNativePath;
9710                                        // Set the application info flag
9711                                        // correctly.
9712                                        if ((mp.flags & PackageManager.INSTALL_EXTERNAL) != 0) {
9713                                            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE;
9714                                        } else {
9715                                            pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_EXTERNAL_STORAGE;
9716                                        }
9717                                        ps.setFlags(pkg.applicationInfo.flags);
9718                                        mAppDirs.remove(oldCodePath);
9719                                        mAppDirs.put(newCodePath, pkg);
9720                                        // Persist settings
9721                                        mSettings.writeLPr();
9722                                    }
9723                                }
9724                            }
9725                        }
9726                        // Send resources available broadcast
9727                        sendResourcesChangedBroadcast(true, pkgList, uidArr, null);
9728                    }
9729                }
9730                if (returnCode != PackageManager.MOVE_SUCCEEDED) {
9731                    // Clean up failed installation
9732                    if (mp.targetArgs != null) {
9733                        mp.targetArgs.doPostInstall(PackageManager.INSTALL_FAILED_INTERNAL_ERROR,
9734                                -1);
9735                    }
9736                } else {
9737                    // Force a gc to clear things up.
9738                    Runtime.getRuntime().gc();
9739                    // Delete older code
9740                    synchronized (mInstallLock) {
9741                        mp.srcArgs.doPostDeleteLI(true);
9742                    }
9743                }
9744
9745                // Allow more operations on this file if we didn't fail because
9746                // an operation was already pending for this package.
9747                if (returnCode != PackageManager.MOVE_FAILED_OPERATION_PENDING) {
9748                    synchronized (mPackages) {
9749                        PackageParser.Package pkg = mPackages.get(mp.packageName);
9750                        if (pkg != null) {
9751                            pkg.mOperationPending = false;
9752                       }
9753                   }
9754                }
9755
9756                IPackageMoveObserver observer = mp.observer;
9757                if (observer != null) {
9758                    try {
9759                        observer.packageMoved(mp.packageName, returnCode);
9760                    } catch (RemoteException e) {
9761                        Log.i(TAG, "Observer no longer exists.");
9762                    }
9763                }
9764            }
9765        });
9766    }
9767
9768    public boolean setInstallLocation(int loc) {
9769        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
9770                null);
9771        if (getInstallLocation() == loc) {
9772            return true;
9773        }
9774        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
9775                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
9776            android.provider.Settings.System.putInt(mContext.getContentResolver(),
9777                    android.provider.Settings.Secure.DEFAULT_INSTALL_LOCATION, loc);
9778            return true;
9779        }
9780        return false;
9781   }
9782
9783    public int getInstallLocation() {
9784        return android.provider.Settings.System.getInt(mContext.getContentResolver(),
9785                android.provider.Settings.Secure.DEFAULT_INSTALL_LOCATION,
9786                PackageHelper.APP_INSTALL_AUTO);
9787    }
9788
9789    /** Called by UserManagerService */
9790    void cleanUpUserLILPw(int userHandle) {
9791        // Disable all the packages for the user first
9792        Set<Entry<String, PackageSetting>> entries = mSettings.mPackages.entrySet();
9793        for (Entry<String, PackageSetting> entry : entries) {
9794            entry.getValue().removeUser(userHandle);
9795        }
9796        if (mDirtyUsers.remove(userHandle));
9797        mSettings.removeUserLPr(userHandle);
9798        if (mInstaller != null) {
9799            // Technically, we shouldn't be doing this with the package lock
9800            // held.  However, this is very rare, and there is already so much
9801            // other disk I/O going on, that we'll let it slide for now.
9802            mInstaller.removeUserDataDirs(userHandle);
9803        }
9804    }
9805
9806    /** Called by UserManagerService */
9807    void createNewUserLILPw(int userHandle, File path) {
9808        if (mInstaller != null) {
9809            path.mkdir();
9810            FileUtils.setPermissions(path.toString(), FileUtils.S_IRWXU | FileUtils.S_IRWXG
9811                    | FileUtils.S_IXOTH, -1, -1);
9812            for (PackageSetting ps : mSettings.mPackages.values()) {
9813                // Only system apps are initially installed.
9814                ps.setInstalled((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0, userHandle);
9815                // Need to create a data directory for all apps under this user.
9816                mInstaller.createUserData(ps.name,
9817                        UserHandle.getUid(userHandle, ps.appId), userHandle);
9818            }
9819            mSettings.writePackageRestrictionsLPr(userHandle);
9820        }
9821    }
9822
9823    @Override
9824    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
9825        mContext.enforceCallingOrSelfPermission(
9826                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
9827                "Only package verification agents can read the verifier device identity");
9828
9829        synchronized (mPackages) {
9830            return mSettings.getVerifierDeviceIdentityLPw();
9831        }
9832    }
9833
9834    @Override
9835    public void setPermissionEnforced(String permission, boolean enforced) {
9836        mContext.enforceCallingOrSelfPermission(GRANT_REVOKE_PERMISSIONS, null);
9837        if (READ_EXTERNAL_STORAGE.equals(permission)) {
9838            synchronized (mPackages) {
9839                if (mSettings.mReadExternalStorageEnforced == null
9840                        || mSettings.mReadExternalStorageEnforced != enforced) {
9841                    mSettings.mReadExternalStorageEnforced = enforced;
9842                    mSettings.writeLPr();
9843
9844                    // kill any non-foreground processes so we restart them and
9845                    // grant/revoke the GID.
9846                    final IActivityManager am = ActivityManagerNative.getDefault();
9847                    if (am != null) {
9848                        final long token = Binder.clearCallingIdentity();
9849                        try {
9850                            am.killProcessesBelowForeground("setPermissionEnforcement");
9851                        } catch (RemoteException e) {
9852                        } finally {
9853                            Binder.restoreCallingIdentity(token);
9854                        }
9855                    }
9856                }
9857            }
9858        } else {
9859            throw new IllegalArgumentException("No selective enforcement for " + permission);
9860        }
9861    }
9862
9863    @Override
9864    public boolean isPermissionEnforced(String permission) {
9865        synchronized (mPackages) {
9866            return isPermissionEnforcedLocked(permission);
9867        }
9868    }
9869
9870    private boolean isPermissionEnforcedLocked(String permission) {
9871        if (READ_EXTERNAL_STORAGE.equals(permission)) {
9872            if (mSettings.mReadExternalStorageEnforced != null) {
9873                return mSettings.mReadExternalStorageEnforced;
9874            } else {
9875                // if user hasn't defined, fall back to secure default
9876                return Secure.getInt(mContext.getContentResolver(),
9877                        Secure.READ_EXTERNAL_STORAGE_ENFORCED_DEFAULT, 0) != 0;
9878            }
9879        } else {
9880            return true;
9881        }
9882    }
9883
9884    public boolean isStorageLow() {
9885        final long token = Binder.clearCallingIdentity();
9886        try {
9887            final DeviceStorageMonitorService dsm = (DeviceStorageMonitorService) ServiceManager
9888                    .getService(DeviceStorageMonitorService.SERVICE);
9889            return dsm.isMemoryLow();
9890        } finally {
9891            Binder.restoreCallingIdentity(token);
9892        }
9893    }
9894}
9895