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