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