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