101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn/*
201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn * Copyright (C) 2010 The Android Open Source Project
301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn *
401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn * you may not use this file except in compliance with the License.
601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn * You may obtain a copy of the License at
701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn *
801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn *
1001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn * Unless required by applicable law or agreed to in writing, software
1101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
1201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn * See the License for the specific language governing permissions and
1401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn * limitations under the License.
1501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn */
1601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
1701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornpackage android.app;
1801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
1901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport com.android.internal.util.ArrayUtils;
2001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
2101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport android.content.BroadcastReceiver;
2201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport android.content.ComponentName;
2301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport android.content.Context;
2401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport android.content.IIntentReceiver;
2501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport android.content.Intent;
2601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport android.content.ServiceConnection;
2701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport android.content.pm.ApplicationInfo;
2801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport android.content.pm.IPackageManager;
2901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport android.content.pm.PackageManager;
3001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport android.content.res.AssetManager;
3101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport android.content.res.CompatibilityInfo;
3201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport android.content.res.Resources;
3301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport android.os.Bundle;
3401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport android.os.Handler;
3501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport android.os.IBinder;
3601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport android.os.Process;
3701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport android.os.RemoteException;
38624d50f00dc3d672d676a2fbb405c61dfc875b28Brad Fitzpatrickimport android.os.StrictMode;
391ded0b1f6af65c2f95f8327f7f3df4cee1bf2346Dianne Hackbornimport android.os.Trace;
40f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackbornimport android.os.UserHandle;
4101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport android.util.AndroidRuntimeException;
4201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport android.util.Slog;
435fd2169eabd77e6bfafaf456e58051a3bafb2bcaDianne Hackbornimport android.view.CompatibilityInfoHolder;
44a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brownimport android.view.Display;
4501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
4601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport java.io.File;
4701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport java.io.IOException;
4801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport java.io.InputStream;
4901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport java.lang.ref.WeakReference;
5001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport java.net.URL;
5101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport java.util.Enumeration;
5201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport java.util.HashMap;
5301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport java.util.Iterator;
5401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
5501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornfinal class IntentReceiverLeaked extends AndroidRuntimeException {
5601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    public IntentReceiverLeaked(String msg) {
5701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        super(msg);
5801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    }
5901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn}
6001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
6101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornfinal class ServiceConnectionLeaked extends AndroidRuntimeException {
6201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    public ServiceConnectionLeaked(String msg) {
6301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        super(msg);
6401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    }
6501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn}
6601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
6701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn/**
6801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn * Local state maintained about a currently loaded .apk.
6901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn * @hide
7001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn */
715fd2169eabd77e6bfafaf456e58051a3bafb2bcaDianne Hackbornpublic final class LoadedApk {
7201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
73742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    private static final String TAG = "LoadedApk";
74742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
7501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    private final ActivityThread mActivityThread;
7601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    private final ApplicationInfo mApplicationInfo;
7701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    final String mPackageName;
7801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    private final String mAppDir;
7901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    private final String mResDir;
8001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    private final String[] mSharedLibraries;
8101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    private final String mDataDir;
8285387d7ba36e56b291cbde87acb5a5b2200fe01cKenny Root    private final String mLibDir;
8301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    private final File mDataDirFile;
8401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    private final ClassLoader mBaseClassLoader;
8501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    private final boolean mSecurityViolation;
8601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    private final boolean mIncludeCode;
875fd2169eabd77e6bfafaf456e58051a3bafb2bcaDianne Hackborn    public final CompatibilityInfoHolder mCompatibilityInfo = new CompatibilityInfoHolder();
8801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    Resources mResources;
8901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    private ClassLoader mClassLoader;
9001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    private Application mApplication;
9101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
9201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    private final HashMap<Context, HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>> mReceivers
9301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        = new HashMap<Context, HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>>();
9401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    private final HashMap<Context, HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>> mUnregisteredReceivers
9501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    = new HashMap<Context, HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>>();
9601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    private final HashMap<Context, HashMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices
9701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        = new HashMap<Context, HashMap<ServiceConnection, LoadedApk.ServiceDispatcher>>();
9801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    private final HashMap<Context, HashMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mUnboundServices
9901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        = new HashMap<Context, HashMap<ServiceConnection, LoadedApk.ServiceDispatcher>>();
10001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
10101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    int mClientCount = 0;
10201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
10301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    Application getApplication() {
10401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        return mApplication;
10501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    }
10601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
1072f0b17573d4324832f7a20402a3d2b5920bc4866Dianne Hackborn    /**
1082f0b17573d4324832f7a20402a3d2b5920bc4866Dianne Hackborn     * Create information about a new .apk
1092f0b17573d4324832f7a20402a3d2b5920bc4866Dianne Hackborn     *
1102f0b17573d4324832f7a20402a3d2b5920bc4866Dianne Hackborn     * NOTE: This constructor is called with ActivityThread's lock held,
1112f0b17573d4324832f7a20402a3d2b5920bc4866Dianne Hackborn     * so MUST NOT call back out to the activity manager.
1122f0b17573d4324832f7a20402a3d2b5920bc4866Dianne Hackborn     */
11301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    public LoadedApk(ActivityThread activityThread, ApplicationInfo aInfo,
114e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn            CompatibilityInfo compatInfo,
11501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            ActivityThread mainThread, ClassLoader baseLoader,
11601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            boolean securityViolation, boolean includeCode) {
11701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        mActivityThread = activityThread;
11801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        mApplicationInfo = aInfo;
11901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        mPackageName = aInfo.packageName;
12001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        mAppDir = aInfo.sourceDir;
121742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        final int myUid = Process.myUid();
122742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        mResDir = aInfo.uid == myUid ? aInfo.sourceDir
12301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                : aInfo.publicSourceDir;
124f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn        if (!UserHandle.isSameUser(aInfo.uid, myUid) && !Process.isIsolated()) {
125f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn            aInfo.dataDir = PackageManager.getDataDirForUser(UserHandle.getUserId(myUid),
126742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                    mPackageName);
127742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        }
12801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        mSharedLibraries = aInfo.sharedLibraryFiles;
12901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        mDataDir = aInfo.dataDir;
13001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        mDataDirFile = mDataDir != null ? new File(mDataDir) : null;
13185387d7ba36e56b291cbde87acb5a5b2200fe01cKenny Root        mLibDir = aInfo.nativeLibraryDir;
13201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        mBaseClassLoader = baseLoader;
13301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        mSecurityViolation = securityViolation;
13401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        mIncludeCode = includeCode;
1355fd2169eabd77e6bfafaf456e58051a3bafb2bcaDianne Hackborn        mCompatibilityInfo.set(compatInfo);
13601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
13701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        if (mAppDir == null) {
13801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            if (ActivityThread.mSystemContext == null) {
13901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                ActivityThread.mSystemContext =
14001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    ContextImpl.createSystemContext(mainThread);
14101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                ActivityThread.mSystemContext.getResources().updateConfiguration(
14201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                         mainThread.getConfiguration(),
143a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown                         mainThread.getDisplayMetricsLocked(
144a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown                                 Display.DEFAULT_DISPLAY, compatInfo),
145e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn                         compatInfo);
14601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                //Slog.i(TAG, "Created system resources "
14701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                //        + mSystemContext.getResources() + ": "
14801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                //        + mSystemContext.getResources().getConfiguration());
14901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
15001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            mClassLoader = ActivityThread.mSystemContext.getClassLoader();
15101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            mResources = ActivityThread.mSystemContext.getResources();
15201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
15301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    }
15401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
15501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    public LoadedApk(ActivityThread activityThread, String name,
156e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn            Context systemContext, ApplicationInfo info, CompatibilityInfo compatInfo) {
15701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        mActivityThread = activityThread;
15801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        mApplicationInfo = info != null ? info : new ApplicationInfo();
15901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        mApplicationInfo.packageName = name;
16001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        mPackageName = name;
16101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        mAppDir = null;
16201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        mResDir = null;
16301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        mSharedLibraries = null;
16401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        mDataDir = null;
16501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        mDataDirFile = null;
16685387d7ba36e56b291cbde87acb5a5b2200fe01cKenny Root        mLibDir = null;
16701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        mBaseClassLoader = null;
16801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        mSecurityViolation = false;
16901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        mIncludeCode = true;
17001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        mClassLoader = systemContext.getClassLoader();
17101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        mResources = systemContext.getResources();
1725fd2169eabd77e6bfafaf456e58051a3bafb2bcaDianne Hackborn        mCompatibilityInfo.set(compatInfo);
17301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    }
17401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
17501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    public String getPackageName() {
17601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        return mPackageName;
17701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    }
17801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
17901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    public ApplicationInfo getApplicationInfo() {
18001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        return mApplicationInfo;
18101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    }
18201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
18301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    public boolean isSecurityViolation() {
18401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        return mSecurityViolation;
18501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    }
18601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
18701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    /**
18801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * Gets the array of shared libraries that are listed as
18901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * used by the given package.
19001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     *
19101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * @param packageName the name of the package (note: not its
19201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * file name)
19301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * @return null-ok; the array of shared libraries, each one
19401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * a fully-qualified path
19501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     */
19601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    private static String[] getLibrariesFor(String packageName) {
19701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        ApplicationInfo ai = null;
19801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        try {
19901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            ai = ActivityThread.getPackageManager().getApplicationInfo(packageName,
200f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn                    PackageManager.GET_SHARED_LIBRARY_FILES, UserHandle.myUserId());
20101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        } catch (RemoteException e) {
20201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            throw new AssertionError(e);
20301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
20401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
20501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        if (ai == null) {
20601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            return null;
20701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
20801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
20901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        return ai.sharedLibraryFiles;
21001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    }
21101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
21201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    /**
21301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * Combines two arrays (of library names) such that they are
21401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * concatenated in order but are devoid of duplicates. The
21501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * result is a single string with the names of the libraries
21601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * separated by colons, or <code>null</code> if both lists
21701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * were <code>null</code> or empty.
21801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     *
21901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * @param list1 null-ok; the first list
22001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * @param list2 null-ok; the second list
22101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * @return null-ok; the combination
22201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     */
22301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    private static String combineLibs(String[] list1, String[] list2) {
22401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        StringBuilder result = new StringBuilder(300);
22501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        boolean first = true;
22601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
22701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        if (list1 != null) {
22801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            for (String s : list1) {
22901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                if (first) {
23001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    first = false;
23101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                } else {
23201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    result.append(':');
23301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
23401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                result.append(s);
23501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
23601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
23701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
23801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        // Only need to check for duplicates if list1 was non-empty.
23901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        boolean dupCheck = !first;
24001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
24101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        if (list2 != null) {
24201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            for (String s : list2) {
24301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                if (dupCheck && ArrayUtils.contains(list1, s)) {
24401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    continue;
24501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
24601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
24701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                if (first) {
24801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    first = false;
24901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                } else {
25001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    result.append(':');
25101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
25201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                result.append(s);
25301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
25401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
25501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
25601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        return result.toString();
25701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    }
25801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
25901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    public ClassLoader getClassLoader() {
26001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        synchronized (this) {
26101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            if (mClassLoader != null) {
26201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                return mClassLoader;
26301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
26401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
26501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            if (mIncludeCode && !mPackageName.equals("android")) {
26601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                String zip = mAppDir;
267d893a890c92e174c1a4bf0075b0acc4749a0eaa8Brian Carlstrom                String libraryPath = mLibDir;
26801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
26901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                /*
27001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                 * The following is a bit of a hack to inject
27101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                 * instrumentation into the system: If the app
27201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                 * being started matches one of the instrumentation names,
27301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                 * then we combine both the "instrumentation" and
27401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                 * "instrumented" app into the path, along with the
27501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                 * concatenation of both apps' shared library lists.
27601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                 */
27701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
27801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                String instrumentationAppDir =
27901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        mActivityThread.mInstrumentationAppDir;
280d893a890c92e174c1a4bf0075b0acc4749a0eaa8Brian Carlstrom                String instrumentationAppLibraryDir =
281d893a890c92e174c1a4bf0075b0acc4749a0eaa8Brian Carlstrom                        mActivityThread.mInstrumentationAppLibraryDir;
28201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                String instrumentationAppPackage =
28301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        mActivityThread.mInstrumentationAppPackage;
28401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                String instrumentedAppDir =
28501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        mActivityThread.mInstrumentedAppDir;
286d893a890c92e174c1a4bf0075b0acc4749a0eaa8Brian Carlstrom                String instrumentedAppLibraryDir =
287d893a890c92e174c1a4bf0075b0acc4749a0eaa8Brian Carlstrom                        mActivityThread.mInstrumentedAppLibraryDir;
28801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                String[] instrumentationLibs = null;
28901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
29001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                if (mAppDir.equals(instrumentationAppDir)
29101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        || mAppDir.equals(instrumentedAppDir)) {
29201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    zip = instrumentationAppDir + ":" + instrumentedAppDir;
293d893a890c92e174c1a4bf0075b0acc4749a0eaa8Brian Carlstrom                    libraryPath = instrumentationAppLibraryDir + ":" + instrumentedAppLibraryDir;
29401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    if (! instrumentedAppDir.equals(instrumentationAppDir)) {
29501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        instrumentationLibs =
29601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                            getLibrariesFor(instrumentationAppPackage);
29701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    }
29801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
29901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
30001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                if ((mSharedLibraries != null) ||
30101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        (instrumentationLibs != null)) {
30201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    zip =
30301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        combineLibs(mSharedLibraries, instrumentationLibs)
30401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        + ':' + zip;
30501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
30601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
30701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                /*
30801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                 * With all the combination done (if necessary, actually
30901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                 * create the class loader.
31001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                 */
31101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
31285387d7ba36e56b291cbde87acb5a5b2200fe01cKenny Root                if (ActivityThread.localLOGV)
313d893a890c92e174c1a4bf0075b0acc4749a0eaa8Brian Carlstrom                    Slog.v(ActivityThread.TAG, "Class path: " + zip + ", JNI path: " + libraryPath);
31401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
315624d50f00dc3d672d676a2fbb405c61dfc875b28Brad Fitzpatrick                // Temporarily disable logging of disk reads on the Looper thread
316624d50f00dc3d672d676a2fbb405c61dfc875b28Brad Fitzpatrick                // as this is early and necessary.
317624d50f00dc3d672d676a2fbb405c61dfc875b28Brad Fitzpatrick                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
318624d50f00dc3d672d676a2fbb405c61dfc875b28Brad Fitzpatrick
31901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                mClassLoader =
32001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    ApplicationLoaders.getDefault().getClassLoader(
321d893a890c92e174c1a4bf0075b0acc4749a0eaa8Brian Carlstrom                        zip, libraryPath, mBaseClassLoader);
32201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                initializeJavaContextClassLoader();
323624d50f00dc3d672d676a2fbb405c61dfc875b28Brad Fitzpatrick
324624d50f00dc3d672d676a2fbb405c61dfc875b28Brad Fitzpatrick                StrictMode.setThreadPolicy(oldPolicy);
32501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            } else {
32601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                if (mBaseClassLoader == null) {
32701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    mClassLoader = ClassLoader.getSystemClassLoader();
32801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                } else {
32901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    mClassLoader = mBaseClassLoader;
33001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
33101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
33201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            return mClassLoader;
33301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
33401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    }
33501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
33601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    /**
33701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * Setup value for Thread.getContextClassLoader(). If the
33801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * package will not run in in a VM with other packages, we set
33901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * the Java context ClassLoader to the
34001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * PackageInfo.getClassLoader value. However, if this VM can
34101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * contain multiple packages, we intead set the Java context
34201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * ClassLoader to a proxy that will warn about the use of Java
34301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * context ClassLoaders and then fall through to use the
34401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * system ClassLoader.
34501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     *
34601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * <p> Note that this is similar to but not the same as the
34701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * android.content.Context.getClassLoader(). While both
34801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * context class loaders are typically set to the
34901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * PathClassLoader used to load the package archive in the
35001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * single application per VM case, a single Android process
35101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * may contain several Contexts executing on one thread with
35201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * their own logical ClassLoaders while the Java context
35301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * ClassLoader is a thread local. This is why in the case when
35401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * we have multiple packages per VM we do not set the Java
35501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * context ClassLoader to an arbitrary but instead warn the
35601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * user to set their own if we detect that they are using a
35701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     * Java library that expects it to be set.
35801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn     */
35901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    private void initializeJavaContextClassLoader() {
36001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        IPackageManager pm = ActivityThread.getPackageManager();
36101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        android.content.pm.PackageInfo pi;
36201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        try {
363f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn            pi = pm.getPackageInfo(mPackageName, 0, UserHandle.myUserId());
36401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        } catch (RemoteException e) {
36501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            throw new AssertionError(e);
36601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
36701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        /*
36801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn         * Two possible indications that this package could be
36901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn         * sharing its virtual machine with other packages:
37001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn         *
37101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn         * 1.) the sharedUserId attribute is set in the manifest,
37201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn         *     indicating a request to share a VM with other
37301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn         *     packages with the same sharedUserId.
37401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn         *
37501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn         * 2.) the application element of the manifest has an
37601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn         *     attribute specifying a non-default process name,
37701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn         *     indicating the desire to run in another packages VM.
37801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn         */
37901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        boolean sharedUserIdSet = (pi.sharedUserId != null);
38001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        boolean processNameNotDefault =
38101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            (pi.applicationInfo != null &&
38201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn             !mPackageName.equals(pi.applicationInfo.processName));
38301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        boolean sharable = (sharedUserIdSet || processNameNotDefault);
38401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        ClassLoader contextClassLoader =
38501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            (sharable)
38601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            ? new WarningContextClassLoader()
38701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            : mClassLoader;
38801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        Thread.currentThread().setContextClassLoader(contextClassLoader);
38901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    }
39001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
39101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    private static class WarningContextClassLoader extends ClassLoader {
39201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
39301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        private static boolean warned = false;
39401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
39501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        private void warn(String methodName) {
39601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            if (warned) {
39701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                return;
39801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
39901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            warned = true;
40001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            Thread.currentThread().setContextClassLoader(getParent());
40101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            Slog.w(ActivityThread.TAG, "ClassLoader." + methodName + ": " +
40201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                  "The class loader returned by " +
40301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                  "Thread.getContextClassLoader() may fail for processes " +
40401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                  "that host multiple applications. You should explicitly " +
40501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                  "specify a context class loader. For example: " +
40601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                  "Thread.setContextClassLoader(getClass().getClassLoader());");
40701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
40801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
40901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        @Override public URL getResource(String resName) {
41001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            warn("getResource");
41101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            return getParent().getResource(resName);
41201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
41301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
41401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        @Override public Enumeration<URL> getResources(String resName) throws IOException {
41501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            warn("getResources");
41601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            return getParent().getResources(resName);
41701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
41801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
41901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        @Override public InputStream getResourceAsStream(String resName) {
42001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            warn("getResourceAsStream");
42101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            return getParent().getResourceAsStream(resName);
42201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
42301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
42401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        @Override public Class<?> loadClass(String className) throws ClassNotFoundException {
42501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            warn("loadClass");
42601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            return getParent().loadClass(className);
42701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
42801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
42901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        @Override public void setClassAssertionStatus(String cname, boolean enable) {
43001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            warn("setClassAssertionStatus");
43101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            getParent().setClassAssertionStatus(cname, enable);
43201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
43301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
43401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        @Override public void setPackageAssertionStatus(String pname, boolean enable) {
43501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            warn("setPackageAssertionStatus");
43601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            getParent().setPackageAssertionStatus(pname, enable);
43701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
43801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
43901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        @Override public void setDefaultAssertionStatus(boolean enable) {
44001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            warn("setDefaultAssertionStatus");
44101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            getParent().setDefaultAssertionStatus(enable);
44201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
44301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
44401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        @Override public void clearAssertionStatus() {
44501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            warn("clearAssertionStatus");
44601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            getParent().clearAssertionStatus();
44701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
44801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    }
44901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
45001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    public String getAppDir() {
45101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        return mAppDir;
45201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    }
45301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
454d893a890c92e174c1a4bf0075b0acc4749a0eaa8Brian Carlstrom    public String getLibDir() {
455d893a890c92e174c1a4bf0075b0acc4749a0eaa8Brian Carlstrom        return mLibDir;
456d893a890c92e174c1a4bf0075b0acc4749a0eaa8Brian Carlstrom    }
457d893a890c92e174c1a4bf0075b0acc4749a0eaa8Brian Carlstrom
45801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    public String getResDir() {
45901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        return mResDir;
46001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    }
46101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
46201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    public String getDataDir() {
46301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        return mDataDir;
46401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    }
46501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
46601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    public File getDataDirFile() {
46701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        return mDataDirFile;
46801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    }
46901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
47001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    public AssetManager getAssets(ActivityThread mainThread) {
47101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        return getResources(mainThread).getAssets();
47201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    }
47301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
47401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    public Resources getResources(ActivityThread mainThread) {
47501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        if (mResources == null) {
476a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown            mResources = mainThread.getTopLevelResources(mResDir,
477a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown                    Display.DEFAULT_DISPLAY, null, this);
47801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
47901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        return mResources;
48001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    }
48101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
48201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    public Application makeApplication(boolean forceDefaultAppClass,
48301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            Instrumentation instrumentation) {
48401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        if (mApplication != null) {
48501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            return mApplication;
48601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
48701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
48801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        Application app = null;
48901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
49001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        String appClass = mApplicationInfo.className;
49101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        if (forceDefaultAppClass || (appClass == null)) {
49201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            appClass = "android.app.Application";
49301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
49401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
49501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        try {
49601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            java.lang.ClassLoader cl = getClassLoader();
49701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            ContextImpl appContext = new ContextImpl();
49801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            appContext.init(this, null, mActivityThread);
49901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            app = mActivityThread.mInstrumentation.newApplication(
50001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    cl, appClass, appContext);
50101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            appContext.setOuterContext(app);
50201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        } catch (Exception e) {
50301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            if (!mActivityThread.mInstrumentation.onException(app, e)) {
50401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                throw new RuntimeException(
50501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    "Unable to instantiate application " + appClass
50601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    + ": " + e.toString(), e);
50701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
50801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
50901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        mActivityThread.mAllApplications.add(app);
51001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        mApplication = app;
51101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
51201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        if (instrumentation != null) {
51301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            try {
51401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                instrumentation.callApplicationOnCreate(app);
51501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            } catch (Exception e) {
51601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                if (!instrumentation.onException(app, e)) {
51701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    throw new RuntimeException(
51801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        "Unable to create application " + app.getClass().getName()
51901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        + ": " + e.toString(), e);
52001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
52101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
52201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
52301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
52401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        return app;
52501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    }
52601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
52701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    public void removeContextRegistrations(Context context,
52801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            String who, String what) {
529d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey        final boolean reportRegistrationLeaks = StrictMode.vmRegistrationLeaksEnabled();
53001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> rmap =
53101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            mReceivers.remove(context);
53201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        if (rmap != null) {
53301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            Iterator<LoadedApk.ReceiverDispatcher> it = rmap.values().iterator();
53401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            while (it.hasNext()) {
53501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                LoadedApk.ReceiverDispatcher rd = it.next();
53601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                IntentReceiverLeaked leak = new IntentReceiverLeaked(
53701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        what + " " + who + " has leaked IntentReceiver "
53801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        + rd.getIntentReceiver() + " that was " +
53901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        "originally registered here. Are you missing a " +
54001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        "call to unregisterReceiver()?");
54101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                leak.setStackTrace(rd.getLocation().getStackTrace());
54201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                Slog.e(ActivityThread.TAG, leak.getMessage(), leak);
543d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey                if (reportRegistrationLeaks) {
544d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey                    StrictMode.onIntentReceiverLeaked(leak);
545d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey                }
54601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                try {
54701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    ActivityManagerNative.getDefault().unregisterReceiver(
54801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                            rd.getIIntentReceiver());
54901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                } catch (RemoteException e) {
55001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    // system crashed, nothing we can do
55101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
55201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
55301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
55401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        mUnregisteredReceivers.remove(context);
55501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        //Slog.i(TAG, "Receiver registrations: " + mReceivers);
55601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        HashMap<ServiceConnection, LoadedApk.ServiceDispatcher> smap =
55701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            mServices.remove(context);
55801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        if (smap != null) {
55901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            Iterator<LoadedApk.ServiceDispatcher> it = smap.values().iterator();
56001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            while (it.hasNext()) {
56101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                LoadedApk.ServiceDispatcher sd = it.next();
56201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                ServiceConnectionLeaked leak = new ServiceConnectionLeaked(
56301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        what + " " + who + " has leaked ServiceConnection "
56401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        + sd.getServiceConnection() + " that was originally bound here");
56501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                leak.setStackTrace(sd.getLocation().getStackTrace());
56601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                Slog.e(ActivityThread.TAG, leak.getMessage(), leak);
567d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey                if (reportRegistrationLeaks) {
568d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey                    StrictMode.onServiceConnectionLeaked(leak);
569d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey                }
57001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                try {
57101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    ActivityManagerNative.getDefault().unbindService(
57201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                            sd.getIServiceConnection());
57301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                } catch (RemoteException e) {
57401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    // system crashed, nothing we can do
57501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
57601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                sd.doForget();
57701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
57801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
57901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        mUnboundServices.remove(context);
58001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        //Slog.i(TAG, "Service registrations: " + mServices);
58101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    }
58201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
58301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r,
58401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            Context context, Handler handler,
58501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            Instrumentation instrumentation, boolean registered) {
58601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        synchronized (mReceivers) {
58701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            LoadedApk.ReceiverDispatcher rd = null;
58801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null;
58901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            if (registered) {
59001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                map = mReceivers.get(context);
59101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                if (map != null) {
59201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    rd = map.get(r);
59301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
59401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
59501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            if (rd == null) {
59601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                rd = new ReceiverDispatcher(r, context, handler,
59701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        instrumentation, registered);
59801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                if (registered) {
59901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    if (map == null) {
60001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        map = new HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
60101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        mReceivers.put(context, map);
60201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    }
60301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    map.put(r, rd);
60401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
60501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            } else {
60601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                rd.validate(context, handler);
60701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
608c2d9c8e20bea92bd8c1bd0954b0a393c1bb8fec0Dianne Hackborn            rd.mForgotten = false;
60901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            return rd.getIIntentReceiver();
61001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
61101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    }
61201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
61301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    public IIntentReceiver forgetReceiverDispatcher(Context context,
61401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            BroadcastReceiver r) {
61501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        synchronized (mReceivers) {
61601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = mReceivers.get(context);
61701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            LoadedApk.ReceiverDispatcher rd = null;
61801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            if (map != null) {
61901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                rd = map.get(r);
62001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                if (rd != null) {
62101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    map.remove(r);
62201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    if (map.size() == 0) {
62301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        mReceivers.remove(context);
62401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    }
62501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    if (r.getDebugUnregister()) {
62601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> holder
62701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                                = mUnregisteredReceivers.get(context);
62801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        if (holder == null) {
62901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                            holder = new HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
63001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                            mUnregisteredReceivers.put(context, holder);
63101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        }
63201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        RuntimeException ex = new IllegalArgumentException(
63301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                                "Originally unregistered here:");
63401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        ex.fillInStackTrace();
63501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        rd.setUnregisterLocation(ex);
63601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        holder.put(r, rd);
63701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    }
638c2d9c8e20bea92bd8c1bd0954b0a393c1bb8fec0Dianne Hackborn                    rd.mForgotten = true;
63901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    return rd.getIIntentReceiver();
64001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
64101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
64201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> holder
64301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    = mUnregisteredReceivers.get(context);
64401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            if (holder != null) {
64501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                rd = holder.get(r);
64601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                if (rd != null) {
64701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    RuntimeException ex = rd.getUnregisterLocation();
64801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    throw new IllegalArgumentException(
64901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                            "Unregistering Receiver " + r
65001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                            + " that was already unregistered", ex);
65101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
65201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
65301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            if (context == null) {
65401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                throw new IllegalStateException("Unbinding Receiver " + r
65501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        + " from Context that is no longer in use: " + context);
65601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            } else {
65701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                throw new IllegalArgumentException("Receiver not registered: " + r);
65801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
65901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
66001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
66101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    }
66201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
66301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    static final class ReceiverDispatcher {
66401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
66501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        final static class InnerReceiver extends IIntentReceiver.Stub {
66601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            final WeakReference<LoadedApk.ReceiverDispatcher> mDispatcher;
66701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            final LoadedApk.ReceiverDispatcher mStrongRef;
66801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
66901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {
67001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd);
67101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                mStrongRef = strong ? rd : null;
67201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
67320e809870d8ac1e5b848f2daf51b2272ef89bdfcDianne Hackborn            public void performReceive(Intent intent, int resultCode, String data,
67420e809870d8ac1e5b848f2daf51b2272ef89bdfcDianne Hackborn                    Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
67501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                LoadedApk.ReceiverDispatcher rd = mDispatcher.get();
67601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                if (ActivityThread.DEBUG_BROADCAST) {
67701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    int seq = intent.getIntExtra("seq", -1);
67801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    Slog.i(ActivityThread.TAG, "Receiving broadcast " + intent.getAction() + " seq=" + seq
67901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                            + " to " + (rd != null ? rd.mReceiver : null));
68001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
68101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                if (rd != null) {
68201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    rd.performReceive(intent, resultCode, data, extras,
68320e809870d8ac1e5b848f2daf51b2272ef89bdfcDianne Hackborn                            ordered, sticky, sendingUser);
68401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                } else {
68501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    // The activity manager dispatched a broadcast to a registered
68601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    // receiver in this process, but before it could be delivered the
68701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    // receiver was unregistered.  Acknowledge the broadcast on its
68801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    // behalf so that the system's broadcast sequence can continue.
68901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
69001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                            "Finishing broadcast to unregistered receiver");
69101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    IActivityManager mgr = ActivityManagerNative.getDefault();
69201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    try {
6939ecebbfbf768fd63e9a6c9a09c86d81c7737ee2dDianne Hackborn                        if (extras != null) {
6949ecebbfbf768fd63e9a6c9a09c86d81c7737ee2dDianne Hackborn                            extras.setAllowFds(false);
6959ecebbfbf768fd63e9a6c9a09c86d81c7737ee2dDianne Hackborn                        }
69601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        mgr.finishReceiver(this, resultCode, data, extras, false);
69701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    } catch (RemoteException e) {
69801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        Slog.w(ActivityThread.TAG, "Couldn't finish broadcast to unregistered receiver");
69901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    }
70001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
70101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
70201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
70301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
70401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        final IIntentReceiver.Stub mIIntentReceiver;
70501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        final BroadcastReceiver mReceiver;
70601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        final Context mContext;
70701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        final Handler mActivityThread;
70801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        final Instrumentation mInstrumentation;
70901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        final boolean mRegistered;
71001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        final IntentReceiverLeaked mLocation;
71101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        RuntimeException mUnregisterLocation;
712c2d9c8e20bea92bd8c1bd0954b0a393c1bb8fec0Dianne Hackborn        boolean mForgotten;
71301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
714e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn        final class Args extends BroadcastReceiver.PendingResult implements Runnable {
71501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            private Intent mCurIntent;
716e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn            private final boolean mOrdered;
717e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn
718e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn            public Args(Intent intent, int resultCode, String resultData, Bundle resultExtras,
71920e809870d8ac1e5b848f2daf51b2272ef89bdfcDianne Hackborn                    boolean ordered, boolean sticky, int sendingUser) {
720e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn                super(resultCode, resultData, resultExtras,
721e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn                        mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED,
72220e809870d8ac1e5b848f2daf51b2272ef89bdfcDianne Hackborn                        ordered, sticky, mIIntentReceiver.asBinder(), sendingUser);
723e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn                mCurIntent = intent;
724e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn                mOrdered = ordered;
725e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn            }
726e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn
72701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            public void run() {
728e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn                final BroadcastReceiver receiver = mReceiver;
729e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn                final boolean ordered = mOrdered;
730e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn
73101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                if (ActivityThread.DEBUG_BROADCAST) {
73201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    int seq = mCurIntent.getIntExtra("seq", -1);
73301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    Slog.i(ActivityThread.TAG, "Dispatching broadcast " + mCurIntent.getAction()
73401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                            + " seq=" + seq + " to " + mReceiver);
73501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    Slog.i(ActivityThread.TAG, "  mRegistered=" + mRegistered
736e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn                            + " mOrderedHint=" + ordered);
73701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
73801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
739e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn                final IActivityManager mgr = ActivityManagerNative.getDefault();
740e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn                final Intent intent = mCurIntent;
74101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                mCurIntent = null;
74201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
743c2d9c8e20bea92bd8c1bd0954b0a393c1bb8fec0Dianne Hackborn                if (receiver == null || mForgotten) {
744e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn                    if (mRegistered && ordered) {
745e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn                        if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
746e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn                                "Finishing null broadcast to " + mReceiver);
747e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn                        sendFinished(mgr);
74801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    }
74901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    return;
75001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
75101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
7521ded0b1f6af65c2f95f8327f7f3df4cee1bf2346Dianne Hackborn                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveReg");
75301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                try {
75401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    ClassLoader cl =  mReceiver.getClass().getClassLoader();
75501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    intent.setExtrasClassLoader(cl);
756e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn                    setExtrasClassLoader(cl);
757e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn                    receiver.setPendingResult(this);
75801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    receiver.onReceive(mContext, intent);
75901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                } catch (Exception e) {
760e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn                    if (mRegistered && ordered) {
761e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn                        if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
762e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn                                "Finishing failed broadcast to " + mReceiver);
763e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn                        sendFinished(mgr);
76401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    }
76501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    if (mInstrumentation == null ||
76601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                            !mInstrumentation.onException(mReceiver, e)) {
7671ded0b1f6af65c2f95f8327f7f3df4cee1bf2346Dianne Hackborn                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
76801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        throw new RuntimeException(
76901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                            "Error receiving broadcast " + intent
77001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                            + " in " + mReceiver, e);
77101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    }
77201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
773e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn
774e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn                if (receiver.getPendingResult() != null) {
775e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn                    finish();
77601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
7771ded0b1f6af65c2f95f8327f7f3df4cee1bf2346Dianne Hackborn                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
77801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
77901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
78001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
78101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        ReceiverDispatcher(BroadcastReceiver receiver, Context context,
78201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                Handler activityThread, Instrumentation instrumentation,
78301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                boolean registered) {
78401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            if (activityThread == null) {
78501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                throw new NullPointerException("Handler must not be null");
78601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
78701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
78801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            mIIntentReceiver = new InnerReceiver(this, !registered);
78901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            mReceiver = receiver;
79001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            mContext = context;
79101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            mActivityThread = activityThread;
79201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            mInstrumentation = instrumentation;
79301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            mRegistered = registered;
79401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            mLocation = new IntentReceiverLeaked(null);
79501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            mLocation.fillInStackTrace();
79601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
79701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
79801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        void validate(Context context, Handler activityThread) {
79901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            if (mContext != context) {
80001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                throw new IllegalStateException(
80101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    "Receiver " + mReceiver +
80201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    " registered with differing Context (was " +
80301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    mContext + " now " + context + ")");
80401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
80501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            if (mActivityThread != activityThread) {
80601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                throw new IllegalStateException(
80701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    "Receiver " + mReceiver +
80801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    " registered with differing handler (was " +
80901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    mActivityThread + " now " + activityThread + ")");
81001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
81101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
81201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
81301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        IntentReceiverLeaked getLocation() {
81401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            return mLocation;
81501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
81601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
81701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        BroadcastReceiver getIntentReceiver() {
81801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            return mReceiver;
81901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
82001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
82101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        IIntentReceiver getIIntentReceiver() {
82201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            return mIIntentReceiver;
82301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
82401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
82501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        void setUnregisterLocation(RuntimeException ex) {
82601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            mUnregisterLocation = ex;
82701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
82801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
82901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        RuntimeException getUnregisterLocation() {
83001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            return mUnregisterLocation;
83101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
83201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
83320e809870d8ac1e5b848f2daf51b2272ef89bdfcDianne Hackborn        public void performReceive(Intent intent, int resultCode, String data,
83420e809870d8ac1e5b848f2daf51b2272ef89bdfcDianne Hackborn                Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
83501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            if (ActivityThread.DEBUG_BROADCAST) {
83601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                int seq = intent.getIntExtra("seq", -1);
83701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                Slog.i(ActivityThread.TAG, "Enqueueing broadcast " + intent.getAction() + " seq=" + seq
83801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        + " to " + mReceiver);
83901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
84020e809870d8ac1e5b848f2daf51b2272ef89bdfcDianne Hackborn            Args args = new Args(intent, resultCode, data, extras, ordered,
84120e809870d8ac1e5b848f2daf51b2272ef89bdfcDianne Hackborn                    sticky, sendingUser);
84201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            if (!mActivityThread.post(args)) {
84301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                if (mRegistered && ordered) {
84401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    IActivityManager mgr = ActivityManagerNative.getDefault();
845e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn                    if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
846e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn                            "Finishing sync broadcast to " + mReceiver);
847e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn                    args.sendFinished(mgr);
84801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
84901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
85001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
85101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
85201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    }
85301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
85401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    public final IServiceConnection getServiceDispatcher(ServiceConnection c,
85501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            Context context, Handler handler, int flags) {
85601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        synchronized (mServices) {
85701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            LoadedApk.ServiceDispatcher sd = null;
85801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            HashMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
85901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            if (map != null) {
86001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                sd = map.get(c);
86101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
86201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            if (sd == null) {
86301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                sd = new ServiceDispatcher(c, context, handler, flags);
86401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                if (map == null) {
86501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    map = new HashMap<ServiceConnection, LoadedApk.ServiceDispatcher>();
86601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    mServices.put(context, map);
86701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
86801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                map.put(c, sd);
86901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            } else {
87001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                sd.validate(context, handler);
87101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
87201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            return sd.getIServiceConnection();
87301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
87401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    }
87501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
87601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    public final IServiceConnection forgetServiceDispatcher(Context context,
87701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            ServiceConnection c) {
87801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        synchronized (mServices) {
87901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            HashMap<ServiceConnection, LoadedApk.ServiceDispatcher> map
88001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    = mServices.get(context);
88101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            LoadedApk.ServiceDispatcher sd = null;
88201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            if (map != null) {
88301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                sd = map.get(c);
88401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                if (sd != null) {
88501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    map.remove(c);
88601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    sd.doForget();
88701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    if (map.size() == 0) {
88801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        mServices.remove(context);
88901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    }
89001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    if ((sd.getFlags()&Context.BIND_DEBUG_UNBIND) != 0) {
89101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        HashMap<ServiceConnection, LoadedApk.ServiceDispatcher> holder
89201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                                = mUnboundServices.get(context);
89301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        if (holder == null) {
89401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                            holder = new HashMap<ServiceConnection, LoadedApk.ServiceDispatcher>();
89501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                            mUnboundServices.put(context, holder);
89601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        }
89701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        RuntimeException ex = new IllegalArgumentException(
89801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                                "Originally unbound here:");
89901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        ex.fillInStackTrace();
90001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        sd.setUnbindLocation(ex);
90101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        holder.put(c, sd);
90201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    }
90301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    return sd.getIServiceConnection();
90401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
90501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
90601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            HashMap<ServiceConnection, LoadedApk.ServiceDispatcher> holder
90701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    = mUnboundServices.get(context);
90801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            if (holder != null) {
90901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                sd = holder.get(c);
91001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                if (sd != null) {
91101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    RuntimeException ex = sd.getUnbindLocation();
91201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    throw new IllegalArgumentException(
91301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                            "Unbinding Service " + c
91401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                            + " that was already unbound", ex);
91501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
91601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
91701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            if (context == null) {
91801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                throw new IllegalStateException("Unbinding Service " + c
91901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        + " from Context that is no longer in use: " + context);
92001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            } else {
92101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                throw new IllegalArgumentException("Service not registered: " + c);
92201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
92301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
92401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    }
92501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
92601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    static final class ServiceDispatcher {
92701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        private final ServiceDispatcher.InnerConnection mIServiceConnection;
92801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        private final ServiceConnection mConnection;
92901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        private final Context mContext;
93001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        private final Handler mActivityThread;
93101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        private final ServiceConnectionLeaked mLocation;
93201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        private final int mFlags;
93301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
93401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        private RuntimeException mUnbindLocation;
93501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
93601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        private boolean mDied;
9375a6ef737edbf57577443ac056613afe6cb121519Dianne Hackborn        private boolean mForgotten;
93801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
93901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        private static class ConnectionInfo {
94001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            IBinder binder;
94101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            IBinder.DeathRecipient deathMonitor;
94201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
94301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
94401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        private static class InnerConnection extends IServiceConnection.Stub {
94501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;
94601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
94701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            InnerConnection(LoadedApk.ServiceDispatcher sd) {
94801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
94901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
95001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
95101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            public void connected(ComponentName name, IBinder service) throws RemoteException {
95201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                LoadedApk.ServiceDispatcher sd = mDispatcher.get();
95301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                if (sd != null) {
95401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    sd.connected(name, service);
95501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
95601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
95701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
95801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
95901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        private final HashMap<ComponentName, ServiceDispatcher.ConnectionInfo> mActiveConnections
96001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            = new HashMap<ComponentName, ServiceDispatcher.ConnectionInfo>();
96101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
96201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        ServiceDispatcher(ServiceConnection conn,
96301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                Context context, Handler activityThread, int flags) {
96401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            mIServiceConnection = new InnerConnection(this);
96501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            mConnection = conn;
96601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            mContext = context;
96701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            mActivityThread = activityThread;
96801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            mLocation = new ServiceConnectionLeaked(null);
96901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            mLocation.fillInStackTrace();
97001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            mFlags = flags;
97101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
97201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
97301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        void validate(Context context, Handler activityThread) {
97401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            if (mContext != context) {
97501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                throw new RuntimeException(
97601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    "ServiceConnection " + mConnection +
97701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    " registered with differing Context (was " +
97801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    mContext + " now " + context + ")");
97901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
98001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            if (mActivityThread != activityThread) {
98101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                throw new RuntimeException(
98201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    "ServiceConnection " + mConnection +
98301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    " registered with differing handler (was " +
98401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    mActivityThread + " now " + activityThread + ")");
98501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
98601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
98701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
98801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        void doForget() {
98901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            synchronized(this) {
99001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                Iterator<ServiceDispatcher.ConnectionInfo> it = mActiveConnections.values().iterator();
99101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                while (it.hasNext()) {
99201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    ServiceDispatcher.ConnectionInfo ci = it.next();
99301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    ci.binder.unlinkToDeath(ci.deathMonitor, 0);
99401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
99501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                mActiveConnections.clear();
9965a6ef737edbf57577443ac056613afe6cb121519Dianne Hackborn                mForgotten = true;
99701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
99801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
99901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
100001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        ServiceConnectionLeaked getLocation() {
100101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            return mLocation;
100201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
100301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
100401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        ServiceConnection getServiceConnection() {
100501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            return mConnection;
100601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
100701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
100801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        IServiceConnection getIServiceConnection() {
100901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            return mIServiceConnection;
101001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
101101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
101201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        int getFlags() {
101301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            return mFlags;
101401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
101501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
101601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        void setUnbindLocation(RuntimeException ex) {
101701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            mUnbindLocation = ex;
101801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
101901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
102001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        RuntimeException getUnbindLocation() {
102101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            return mUnbindLocation;
102201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
102301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
102401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        public void connected(ComponentName name, IBinder service) {
102501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            if (mActivityThread != null) {
102601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                mActivityThread.post(new RunConnection(name, service, 0));
102701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            } else {
102801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                doConnected(name, service);
102901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
103001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
103101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
103201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        public void death(ComponentName name, IBinder service) {
103301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            ServiceDispatcher.ConnectionInfo old;
103401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
103501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            synchronized (this) {
103601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                mDied = true;
103701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                old = mActiveConnections.remove(name);
103801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                if (old == null || old.binder != service) {
103901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    // Death for someone different than who we last
104001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    // reported...  just ignore it.
104101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    return;
104201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
104301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                old.binder.unlinkToDeath(old.deathMonitor, 0);
104401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
104501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
104601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            if (mActivityThread != null) {
104701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                mActivityThread.post(new RunConnection(name, service, 1));
104801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            } else {
104901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                doDeath(name, service);
105001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
105101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
105201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
105301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        public void doConnected(ComponentName name, IBinder service) {
105401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            ServiceDispatcher.ConnectionInfo old;
105501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            ServiceDispatcher.ConnectionInfo info;
105601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
105701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            synchronized (this) {
10585a6ef737edbf57577443ac056613afe6cb121519Dianne Hackborn                if (mForgotten) {
10595a6ef737edbf57577443ac056613afe6cb121519Dianne Hackborn                    // We unbound before receiving the connection; ignore
10605a6ef737edbf57577443ac056613afe6cb121519Dianne Hackborn                    // any connection received.
10615a6ef737edbf57577443ac056613afe6cb121519Dianne Hackborn                    return;
10625a6ef737edbf57577443ac056613afe6cb121519Dianne Hackborn                }
106301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                old = mActiveConnections.get(name);
106401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                if (old != null && old.binder == service) {
106501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    // Huh, already have this one.  Oh well!
106601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    return;
106701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
106801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
106901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                if (service != null) {
107001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    // A new service is being connected... set it all up.
107101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    mDied = false;
107201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    info = new ConnectionInfo();
107301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    info.binder = service;
107401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    info.deathMonitor = new DeathMonitor(name, service);
107501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    try {
107601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        service.linkToDeath(info.deathMonitor, 0);
107701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        mActiveConnections.put(name, info);
107801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    } catch (RemoteException e) {
107901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        // This service was dead before we got it...  just
108001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        // don't do anything with it.
108101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        mActiveConnections.remove(name);
108201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                        return;
108301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    }
108401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
108501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                } else {
108601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    // The named service is being disconnected... clean up.
108701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    mActiveConnections.remove(name);
108801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
108901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
109001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                if (old != null) {
109101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    old.binder.unlinkToDeath(old.deathMonitor, 0);
109201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
109301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
109401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
109501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            // If there was an old service, it is not disconnected.
109601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            if (old != null) {
109701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                mConnection.onServiceDisconnected(name);
109801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
109901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            // If there is a new service, it is now connected.
110001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            if (service != null) {
110101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                mConnection.onServiceConnected(name, service);
110201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
110301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
110401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
110501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        public void doDeath(ComponentName name, IBinder service) {
110601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            mConnection.onServiceDisconnected(name);
110701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
110801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
110901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        private final class RunConnection implements Runnable {
111001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            RunConnection(ComponentName name, IBinder service, int command) {
111101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                mName = name;
111201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                mService = service;
111301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                mCommand = command;
111401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
111501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
111601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            public void run() {
111701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                if (mCommand == 0) {
111801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    doConnected(mName, mService);
111901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                } else if (mCommand == 1) {
112001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                    doDeath(mName, mService);
112101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                }
112201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
112301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
112401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            final ComponentName mName;
112501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            final IBinder mService;
112601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            final int mCommand;
112701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
112801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
112901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        private final class DeathMonitor implements IBinder.DeathRecipient
113001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        {
113101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            DeathMonitor(ComponentName name, IBinder service) {
113201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                mName = name;
113301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                mService = service;
113401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
113501e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
113601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            public void binderDied() {
113701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn                death(mName, mService);
113801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            }
113901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn
114001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            final ComponentName mName;
114101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn            final IBinder mService;
114201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn        }
114301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn    }
114401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn}
1145