Loading core/java/android/app/ActivityThread.java +54 −58 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ import android.os.SystemProperties; import android.os.Trace; import android.os.UserHandle; import android.util.AndroidRuntimeException; import android.util.ArrayMap; import android.util.DisplayMetrics; import android.util.EventLog; import android.util.Log; Loading Loading @@ -103,8 +104,6 @@ import java.lang.ref.WeakReference; import java.net.InetAddress; import java.security.Security; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; Loading Loading @@ -164,15 +163,15 @@ public final class ActivityThread { final ApplicationThread mAppThread = new ApplicationThread(); final Looper mLooper = Looper.myLooper(); final H mH = new H(); final HashMap<IBinder, ActivityClientRecord> mActivities = new HashMap<IBinder, ActivityClientRecord>(); final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<IBinder, ActivityClientRecord>(); // List of new activities (via ActivityRecord.nextIdle) that should // be reported when next we idle. ActivityClientRecord mNewActivities = null; // Number of activities that are currently visible on-screen. int mNumVisibleActivities = 0; final HashMap<IBinder, Service> mServices = new HashMap<IBinder, Service>(); final ArrayMap<IBinder, Service> mServices = new ArrayMap<IBinder, Service>(); AppBindData mBoundApplication; Profiler mProfiler; int mCurDefaultDisplayDpi; Loading @@ -183,7 +182,7 @@ public final class ActivityThread { final ArrayList<Application> mAllApplications = new ArrayList<Application>(); // set of instantiated backup agents, keyed by package name final HashMap<String, BackupAgent> mBackupAgents = new HashMap<String, BackupAgent>(); final ArrayMap<String, BackupAgent> mBackupAgents = new ArrayMap<String, BackupAgent>(); /** Reference to singleton {@link ActivityThread} */ private static ActivityThread sCurrentActivityThread; Instrumentation mInstrumentation; Loading @@ -203,10 +202,10 @@ public final class ActivityThread { // which means this lock gets held while the activity and window managers // holds their own lock. Thus you MUST NEVER call back into the activity manager // or window manager or anything that depends on them while holding this lock. final HashMap<String, WeakReference<LoadedApk>> mPackages = new HashMap<String, WeakReference<LoadedApk>>(); final HashMap<String, WeakReference<LoadedApk>> mResourcePackages = new HashMap<String, WeakReference<LoadedApk>>(); final ArrayMap<String, WeakReference<LoadedApk>> mPackages = new ArrayMap<String, WeakReference<LoadedApk>>(); final ArrayMap<String, WeakReference<LoadedApk>> mResourcePackages = new ArrayMap<String, WeakReference<LoadedApk>>(); final ArrayList<ActivityClientRecord> mRelaunchingActivities = new ArrayList<ActivityClientRecord>(); Configuration mPendingConfiguration = null; Loading Loading @@ -238,17 +237,17 @@ public final class ActivityThread { } // The lock of mProviderMap protects the following variables. final HashMap<ProviderKey, ProviderClientRecord> mProviderMap = new HashMap<ProviderKey, ProviderClientRecord>(); final HashMap<IBinder, ProviderRefCount> mProviderRefCountMap = new HashMap<IBinder, ProviderRefCount>(); final HashMap<IBinder, ProviderClientRecord> mLocalProviders = new HashMap<IBinder, ProviderClientRecord>(); final HashMap<ComponentName, ProviderClientRecord> mLocalProvidersByName = new HashMap<ComponentName, ProviderClientRecord>(); final HashMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners = new HashMap<Activity, ArrayList<OnActivityPausedListener>>(); final ArrayMap<ProviderKey, ProviderClientRecord> mProviderMap = new ArrayMap<ProviderKey, ProviderClientRecord>(); final ArrayMap<IBinder, ProviderRefCount> mProviderRefCountMap = new ArrayMap<IBinder, ProviderRefCount>(); final ArrayMap<IBinder, ProviderClientRecord> mLocalProviders = new ArrayMap<IBinder, ProviderClientRecord>(); final ArrayMap<ComponentName, ProviderClientRecord> mLocalProvidersByName = new ArrayMap<ComponentName, ProviderClientRecord>(); final ArrayMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners = new ArrayMap<Activity, ArrayList<OnActivityPausedListener>>(); final GcIdler mGcIdler = new GcIdler(); boolean mGcIdlerScheduled = false; Loading Loading @@ -3702,12 +3701,13 @@ public final class ActivityThread { = new ArrayList<ComponentCallbacks2>(); synchronized (mResourcesManager) { final int N = mAllApplications.size(); for (int i=0; i<N; i++) { final int NAPP = mAllApplications.size(); for (int i=0; i<NAPP; i++) { callbacks.add(mAllApplications.get(i)); } if (mActivities.size() > 0) { for (ActivityClientRecord ar : mActivities.values()) { final int NACT = mActivities.size(); for (int i=0; i<NACT; i++) { ActivityClientRecord ar = mActivities.valueAt(i); Activity a = ar.activity; if (a != null) { Configuration thisConfig = applyConfigCompatMainThread( Loading @@ -3731,18 +3731,15 @@ public final class ActivityThread { } } } } if (mServices.size() > 0) { for (Service service : mServices.values()) { callbacks.add(service); } final int NSVC = mServices.size(); for (int i=0; i<NSVC; i++) { callbacks.add(mServices.valueAt(i)); } } synchronized (mProviderMap) { if (mLocalProviders.size() > 0) { for (ProviderClientRecord providerClientRecord : mLocalProviders.values()) { callbacks.add(providerClientRecord.mLocalProvider); } final int NPRV = mLocalProviders.size(); for (int i=0; i<NPRV; i++) { callbacks.add(mLocalProviders.valueAt(i).mLocalProvider); } } Loading Loading @@ -4575,12 +4572,11 @@ public final class ActivityThread { mProviderRefCountMap.remove(jBinder); } Iterator<ProviderClientRecord> iter = mProviderMap.values().iterator(); while (iter.hasNext()) { ProviderClientRecord pr = iter.next(); for (int i=mProviderMap.size()-1; i>=0; i--) { ProviderClientRecord pr = mProviderMap.valueAt(i); IBinder myBinder = pr.mProvider.asBinder(); if (myBinder == jBinder) { iter.remove(); mProviderMap.removeAt(i); } } } Loading core/java/android/app/ApplicationLoaders.java +2 −4 Original line number Diff line number Diff line Loading @@ -17,11 +17,9 @@ package android.app; import android.os.Trace; import android.util.ArrayMap; import dalvik.system.PathClassLoader; import java.util.HashMap; import java.util.Map; class ApplicationLoaders { public static ApplicationLoaders getDefault() Loading Loading @@ -71,7 +69,7 @@ class ApplicationLoaders } } private final Map<String, ClassLoader> mLoaders = new HashMap<String, ClassLoader>(); private final ArrayMap<String, ClassLoader> mLoaders = new ArrayMap<String, ClassLoader>(); private static final ApplicationLoaders gApplicationLoaders = new ApplicationLoaders(); Loading core/java/android/app/ApplicationPackageManager.java +17 −22 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ import android.net.Uri; import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; import android.util.ArrayMap; import android.util.Log; import android.view.Display; Loading Loading @@ -859,30 +860,24 @@ final class ApplicationPackageManager extends PackageManager { boolean needCleanup = false; for (String ssp : pkgList) { synchronized (sSync) { if (sIconCache.size() > 0) { Iterator<ResourceName> it = sIconCache.keySet().iterator(); while (it.hasNext()) { ResourceName nm = it.next(); for (int i=sIconCache.size()-1; i>=0; i--) { ResourceName nm = sIconCache.keyAt(i); if (nm.packageName.equals(ssp)) { //Log.i(TAG, "Removing cached drawable for " + nm); it.remove(); sIconCache.removeAt(i); needCleanup = true; } } } if (sStringCache.size() > 0) { Iterator<ResourceName> it = sStringCache.keySet().iterator(); while (it.hasNext()) { ResourceName nm = it.next(); for (int i=sStringCache.size()-1; i>=0; i--) { ResourceName nm = sStringCache.keyAt(i); if (nm.packageName.equals(ssp)) { //Log.i(TAG, "Removing cached string for " + nm); it.remove(); sStringCache.removeAt(i); needCleanup = true; } } } } } if (needCleanup || hasPkgInfo) { if (immediateGc) { // Schedule an immediate gc. Loading Loading @@ -1335,8 +1330,8 @@ final class ApplicationPackageManager extends PackageManager { private final IPackageManager mPM; private static final Object sSync = new Object(); private static HashMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache = new HashMap<ResourceName, WeakReference<Drawable.ConstantState>>(); private static HashMap<ResourceName, WeakReference<CharSequence>> sStringCache = new HashMap<ResourceName, WeakReference<CharSequence>>(); private static ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache = new ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>>(); private static ArrayMap<ResourceName, WeakReference<CharSequence>> sStringCache = new ArrayMap<ResourceName, WeakReference<CharSequence>>(); } core/java/android/app/LoadedApk.java +32 −36 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.app; import android.util.ArrayMap; import com.android.internal.util.ArrayUtils; import android.content.BroadcastReceiver; Loading Loading @@ -49,8 +50,6 @@ import java.io.InputStream; import java.lang.ref.WeakReference; import java.net.URL; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; final class IntentReceiverLeaked extends AndroidRuntimeException { public IntentReceiverLeaked(String msg) { Loading Loading @@ -89,14 +88,14 @@ public final class LoadedApk { private ClassLoader mClassLoader; private Application mApplication; private final HashMap<Context, HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>> mReceivers = new HashMap<Context, HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>>(); private final HashMap<Context, HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>> mUnregisteredReceivers = new HashMap<Context, HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>>(); private final HashMap<Context, HashMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices = new HashMap<Context, HashMap<ServiceConnection, LoadedApk.ServiceDispatcher>>(); private final HashMap<Context, HashMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mUnboundServices = new HashMap<Context, HashMap<ServiceConnection, LoadedApk.ServiceDispatcher>>(); private final ArrayMap<Context, ArrayMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers = new ArrayMap<Context, ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>>(); private final ArrayMap<Context, ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>> mUnregisteredReceivers = new ArrayMap<Context, ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>>(); private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices = new ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>>(); private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mUnboundServices = new ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>>(); int mClientCount = 0; Loading Loading @@ -540,12 +539,11 @@ public final class LoadedApk { public void removeContextRegistrations(Context context, String who, String what) { final boolean reportRegistrationLeaks = StrictMode.vmRegistrationLeaksEnabled(); HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> rmap = ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> rmap = mReceivers.remove(context); if (rmap != null) { Iterator<LoadedApk.ReceiverDispatcher> it = rmap.values().iterator(); while (it.hasNext()) { LoadedApk.ReceiverDispatcher rd = it.next(); for (int i=0; i<rmap.size(); i++) { LoadedApk.ReceiverDispatcher rd = rmap.valueAt(i); IntentReceiverLeaked leak = new IntentReceiverLeaked( what + " " + who + " has leaked IntentReceiver " + rd.getIntentReceiver() + " that was " + Loading @@ -566,12 +564,11 @@ public final class LoadedApk { } mUnregisteredReceivers.remove(context); //Slog.i(TAG, "Receiver registrations: " + mReceivers); HashMap<ServiceConnection, LoadedApk.ServiceDispatcher> smap = ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> smap = mServices.remove(context); if (smap != null) { Iterator<LoadedApk.ServiceDispatcher> it = smap.values().iterator(); while (it.hasNext()) { LoadedApk.ServiceDispatcher sd = it.next(); for (int i=0; i<smap.size(); i++) { LoadedApk.ServiceDispatcher sd = smap.valueAt(i); ServiceConnectionLeaked leak = new ServiceConnectionLeaked( what + " " + who + " has leaked ServiceConnection " + sd.getServiceConnection() + " that was originally bound here"); Loading @@ -598,7 +595,7 @@ public final class LoadedApk { Instrumentation instrumentation, boolean registered) { synchronized (mReceivers) { LoadedApk.ReceiverDispatcher rd = null; HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null; ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null; if (registered) { map = mReceivers.get(context); if (map != null) { Loading @@ -610,7 +607,7 @@ public final class LoadedApk { instrumentation, registered); if (registered) { if (map == null) { map = new HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>(); map = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>(); mReceivers.put(context, map); } map.put(r, rd); Loading @@ -626,7 +623,7 @@ public final class LoadedApk { public IIntentReceiver forgetReceiverDispatcher(Context context, BroadcastReceiver r) { synchronized (mReceivers) { HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = mReceivers.get(context); ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = mReceivers.get(context); LoadedApk.ReceiverDispatcher rd = null; if (map != null) { rd = map.get(r); Loading @@ -636,10 +633,10 @@ public final class LoadedApk { mReceivers.remove(context); } if (r.getDebugUnregister()) { HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> holder ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> holder = mUnregisteredReceivers.get(context); if (holder == null) { holder = new HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>(); holder = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>(); mUnregisteredReceivers.put(context, holder); } RuntimeException ex = new IllegalArgumentException( Loading @@ -652,7 +649,7 @@ public final class LoadedApk { return rd.getIIntentReceiver(); } } HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> holder ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> holder = mUnregisteredReceivers.get(context); if (holder != null) { rd = holder.get(r); Loading Loading @@ -868,14 +865,14 @@ public final class LoadedApk { Context context, Handler handler, int flags) { synchronized (mServices) { LoadedApk.ServiceDispatcher sd = null; HashMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context); ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context); if (map != null) { sd = map.get(c); } if (sd == null) { sd = new ServiceDispatcher(c, context, handler, flags); if (map == null) { map = new HashMap<ServiceConnection, LoadedApk.ServiceDispatcher>(); map = new ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>(); mServices.put(context, map); } map.put(c, sd); Loading @@ -889,7 +886,7 @@ public final class LoadedApk { public final IServiceConnection forgetServiceDispatcher(Context context, ServiceConnection c) { synchronized (mServices) { HashMap<ServiceConnection, LoadedApk.ServiceDispatcher> map ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context); LoadedApk.ServiceDispatcher sd = null; if (map != null) { Loading @@ -901,10 +898,10 @@ public final class LoadedApk { mServices.remove(context); } if ((sd.getFlags()&Context.BIND_DEBUG_UNBIND) != 0) { HashMap<ServiceConnection, LoadedApk.ServiceDispatcher> holder ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> holder = mUnboundServices.get(context); if (holder == null) { holder = new HashMap<ServiceConnection, LoadedApk.ServiceDispatcher>(); holder = new ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>(); mUnboundServices.put(context, holder); } RuntimeException ex = new IllegalArgumentException( Loading @@ -916,7 +913,7 @@ public final class LoadedApk { return sd.getIServiceConnection(); } } HashMap<ServiceConnection, LoadedApk.ServiceDispatcher> holder ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> holder = mUnboundServices.get(context); if (holder != null) { sd = holder.get(c); Loading Loading @@ -969,8 +966,8 @@ public final class LoadedApk { } } private final HashMap<ComponentName, ServiceDispatcher.ConnectionInfo> mActiveConnections = new HashMap<ComponentName, ServiceDispatcher.ConnectionInfo>(); private final ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo> mActiveConnections = new ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo>(); ServiceDispatcher(ServiceConnection conn, Context context, Handler activityThread, int flags) { Loading Loading @@ -1000,9 +997,8 @@ public final class LoadedApk { void doForget() { synchronized(this) { Iterator<ServiceDispatcher.ConnectionInfo> it = mActiveConnections.values().iterator(); while (it.hasNext()) { ServiceDispatcher.ConnectionInfo ci = it.next(); for (int i=0; i<mActiveConnections.size(); i++) { ServiceDispatcher.ConnectionInfo ci = mActiveConnections.valueAt(i); ci.binder.unlinkToDeath(ci.deathMonitor, 0); } mActiveConnections.clear(); Loading core/java/android/app/ResourcesManager.java +9 −16 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package android.app; import static android.app.ActivityThread.DEBUG_CONFIGURATION; import android.app.ApplicationPackageManager; import android.content.pm.ActivityInfo; import android.content.res.AssetManager; import android.content.res.CompatibilityInfo; Loading @@ -34,10 +33,7 @@ import android.view.Display; import android.view.DisplayAdjustments; import java.lang.ref.WeakReference; import java.util.HashMap; import java.util.Iterator; import java.util.Locale; import java.util.Map; /** @hide */ public class ResourcesManager { Loading @@ -46,8 +42,8 @@ public class ResourcesManager { static final boolean DEBUG_STATS = true; private static ResourcesManager sResourcesManager; final HashMap<ResourcesKey, WeakReference<Resources> > mActiveResources = new HashMap<ResourcesKey, WeakReference<Resources> >(); final ArrayMap<ResourcesKey, WeakReference<Resources> > mActiveResources = new ArrayMap<ResourcesKey, WeakReference<Resources> >(); final ArrayMap<DisplayAdjustments, DisplayMetrics> mDefaultDisplayMetrics = new ArrayMap<DisplayAdjustments, DisplayMetrics>(); Loading Loading @@ -257,19 +253,16 @@ public class ResourcesManager { Configuration tmpConfig = null; Iterator<Map.Entry<ResourcesKey, WeakReference<Resources>>> it = mActiveResources.entrySet().iterator(); while (it.hasNext()) { Map.Entry<ResourcesKey, WeakReference<Resources>> entry = it.next(); Resources r = entry.getValue().get(); for (int i=mActiveResources.size()-1; i>=0; i--) { ResourcesKey key = mActiveResources.keyAt(i); Resources r = mActiveResources.valueAt(i).get(); if (r != null) { if (DEBUG_CONFIGURATION) Slog.v(TAG, "Changing resources " + r + " config to: " + config); int displayId = entry.getKey().mDisplayId; int displayId = key.mDisplayId; boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY); DisplayMetrics dm = defaultDisplayMetrics; ResourcesKey resourcesKey = entry.getKey(); final boolean hasOverrideConfiguration = resourcesKey.hasOverrideConfiguration(); final boolean hasOverrideConfiguration = key.hasOverrideConfiguration(); if (!isDefaultDisplay || hasOverrideConfiguration) { if (tmpConfig == null) { tmpConfig = new Configuration(); Loading @@ -280,7 +273,7 @@ public class ResourcesManager { applyNonDefaultDisplayMetricsToConfigurationLocked(dm, tmpConfig); } if (hasOverrideConfiguration) { tmpConfig.updateFrom(resourcesKey.mOverrideConfiguration); tmpConfig.updateFrom(key.mOverrideConfiguration); } r.updateConfiguration(tmpConfig, dm, compat); } else { Loading @@ -290,7 +283,7 @@ public class ResourcesManager { // + " " + r + ": " + r.getConfiguration()); } else { //Slog.i(TAG, "Removing old resources " + v.getKey()); it.remove(); mActiveResources.removeAt(i); } } Loading Loading
core/java/android/app/ActivityThread.java +54 −58 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ import android.os.SystemProperties; import android.os.Trace; import android.os.UserHandle; import android.util.AndroidRuntimeException; import android.util.ArrayMap; import android.util.DisplayMetrics; import android.util.EventLog; import android.util.Log; Loading Loading @@ -103,8 +104,6 @@ import java.lang.ref.WeakReference; import java.net.InetAddress; import java.security.Security; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; Loading Loading @@ -164,15 +163,15 @@ public final class ActivityThread { final ApplicationThread mAppThread = new ApplicationThread(); final Looper mLooper = Looper.myLooper(); final H mH = new H(); final HashMap<IBinder, ActivityClientRecord> mActivities = new HashMap<IBinder, ActivityClientRecord>(); final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<IBinder, ActivityClientRecord>(); // List of new activities (via ActivityRecord.nextIdle) that should // be reported when next we idle. ActivityClientRecord mNewActivities = null; // Number of activities that are currently visible on-screen. int mNumVisibleActivities = 0; final HashMap<IBinder, Service> mServices = new HashMap<IBinder, Service>(); final ArrayMap<IBinder, Service> mServices = new ArrayMap<IBinder, Service>(); AppBindData mBoundApplication; Profiler mProfiler; int mCurDefaultDisplayDpi; Loading @@ -183,7 +182,7 @@ public final class ActivityThread { final ArrayList<Application> mAllApplications = new ArrayList<Application>(); // set of instantiated backup agents, keyed by package name final HashMap<String, BackupAgent> mBackupAgents = new HashMap<String, BackupAgent>(); final ArrayMap<String, BackupAgent> mBackupAgents = new ArrayMap<String, BackupAgent>(); /** Reference to singleton {@link ActivityThread} */ private static ActivityThread sCurrentActivityThread; Instrumentation mInstrumentation; Loading @@ -203,10 +202,10 @@ public final class ActivityThread { // which means this lock gets held while the activity and window managers // holds their own lock. Thus you MUST NEVER call back into the activity manager // or window manager or anything that depends on them while holding this lock. final HashMap<String, WeakReference<LoadedApk>> mPackages = new HashMap<String, WeakReference<LoadedApk>>(); final HashMap<String, WeakReference<LoadedApk>> mResourcePackages = new HashMap<String, WeakReference<LoadedApk>>(); final ArrayMap<String, WeakReference<LoadedApk>> mPackages = new ArrayMap<String, WeakReference<LoadedApk>>(); final ArrayMap<String, WeakReference<LoadedApk>> mResourcePackages = new ArrayMap<String, WeakReference<LoadedApk>>(); final ArrayList<ActivityClientRecord> mRelaunchingActivities = new ArrayList<ActivityClientRecord>(); Configuration mPendingConfiguration = null; Loading Loading @@ -238,17 +237,17 @@ public final class ActivityThread { } // The lock of mProviderMap protects the following variables. final HashMap<ProviderKey, ProviderClientRecord> mProviderMap = new HashMap<ProviderKey, ProviderClientRecord>(); final HashMap<IBinder, ProviderRefCount> mProviderRefCountMap = new HashMap<IBinder, ProviderRefCount>(); final HashMap<IBinder, ProviderClientRecord> mLocalProviders = new HashMap<IBinder, ProviderClientRecord>(); final HashMap<ComponentName, ProviderClientRecord> mLocalProvidersByName = new HashMap<ComponentName, ProviderClientRecord>(); final HashMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners = new HashMap<Activity, ArrayList<OnActivityPausedListener>>(); final ArrayMap<ProviderKey, ProviderClientRecord> mProviderMap = new ArrayMap<ProviderKey, ProviderClientRecord>(); final ArrayMap<IBinder, ProviderRefCount> mProviderRefCountMap = new ArrayMap<IBinder, ProviderRefCount>(); final ArrayMap<IBinder, ProviderClientRecord> mLocalProviders = new ArrayMap<IBinder, ProviderClientRecord>(); final ArrayMap<ComponentName, ProviderClientRecord> mLocalProvidersByName = new ArrayMap<ComponentName, ProviderClientRecord>(); final ArrayMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners = new ArrayMap<Activity, ArrayList<OnActivityPausedListener>>(); final GcIdler mGcIdler = new GcIdler(); boolean mGcIdlerScheduled = false; Loading Loading @@ -3702,12 +3701,13 @@ public final class ActivityThread { = new ArrayList<ComponentCallbacks2>(); synchronized (mResourcesManager) { final int N = mAllApplications.size(); for (int i=0; i<N; i++) { final int NAPP = mAllApplications.size(); for (int i=0; i<NAPP; i++) { callbacks.add(mAllApplications.get(i)); } if (mActivities.size() > 0) { for (ActivityClientRecord ar : mActivities.values()) { final int NACT = mActivities.size(); for (int i=0; i<NACT; i++) { ActivityClientRecord ar = mActivities.valueAt(i); Activity a = ar.activity; if (a != null) { Configuration thisConfig = applyConfigCompatMainThread( Loading @@ -3731,18 +3731,15 @@ public final class ActivityThread { } } } } if (mServices.size() > 0) { for (Service service : mServices.values()) { callbacks.add(service); } final int NSVC = mServices.size(); for (int i=0; i<NSVC; i++) { callbacks.add(mServices.valueAt(i)); } } synchronized (mProviderMap) { if (mLocalProviders.size() > 0) { for (ProviderClientRecord providerClientRecord : mLocalProviders.values()) { callbacks.add(providerClientRecord.mLocalProvider); } final int NPRV = mLocalProviders.size(); for (int i=0; i<NPRV; i++) { callbacks.add(mLocalProviders.valueAt(i).mLocalProvider); } } Loading Loading @@ -4575,12 +4572,11 @@ public final class ActivityThread { mProviderRefCountMap.remove(jBinder); } Iterator<ProviderClientRecord> iter = mProviderMap.values().iterator(); while (iter.hasNext()) { ProviderClientRecord pr = iter.next(); for (int i=mProviderMap.size()-1; i>=0; i--) { ProviderClientRecord pr = mProviderMap.valueAt(i); IBinder myBinder = pr.mProvider.asBinder(); if (myBinder == jBinder) { iter.remove(); mProviderMap.removeAt(i); } } } Loading
core/java/android/app/ApplicationLoaders.java +2 −4 Original line number Diff line number Diff line Loading @@ -17,11 +17,9 @@ package android.app; import android.os.Trace; import android.util.ArrayMap; import dalvik.system.PathClassLoader; import java.util.HashMap; import java.util.Map; class ApplicationLoaders { public static ApplicationLoaders getDefault() Loading Loading @@ -71,7 +69,7 @@ class ApplicationLoaders } } private final Map<String, ClassLoader> mLoaders = new HashMap<String, ClassLoader>(); private final ArrayMap<String, ClassLoader> mLoaders = new ArrayMap<String, ClassLoader>(); private static final ApplicationLoaders gApplicationLoaders = new ApplicationLoaders(); Loading
core/java/android/app/ApplicationPackageManager.java +17 −22 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ import android.net.Uri; import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; import android.util.ArrayMap; import android.util.Log; import android.view.Display; Loading Loading @@ -859,30 +860,24 @@ final class ApplicationPackageManager extends PackageManager { boolean needCleanup = false; for (String ssp : pkgList) { synchronized (sSync) { if (sIconCache.size() > 0) { Iterator<ResourceName> it = sIconCache.keySet().iterator(); while (it.hasNext()) { ResourceName nm = it.next(); for (int i=sIconCache.size()-1; i>=0; i--) { ResourceName nm = sIconCache.keyAt(i); if (nm.packageName.equals(ssp)) { //Log.i(TAG, "Removing cached drawable for " + nm); it.remove(); sIconCache.removeAt(i); needCleanup = true; } } } if (sStringCache.size() > 0) { Iterator<ResourceName> it = sStringCache.keySet().iterator(); while (it.hasNext()) { ResourceName nm = it.next(); for (int i=sStringCache.size()-1; i>=0; i--) { ResourceName nm = sStringCache.keyAt(i); if (nm.packageName.equals(ssp)) { //Log.i(TAG, "Removing cached string for " + nm); it.remove(); sStringCache.removeAt(i); needCleanup = true; } } } } } if (needCleanup || hasPkgInfo) { if (immediateGc) { // Schedule an immediate gc. Loading Loading @@ -1335,8 +1330,8 @@ final class ApplicationPackageManager extends PackageManager { private final IPackageManager mPM; private static final Object sSync = new Object(); private static HashMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache = new HashMap<ResourceName, WeakReference<Drawable.ConstantState>>(); private static HashMap<ResourceName, WeakReference<CharSequence>> sStringCache = new HashMap<ResourceName, WeakReference<CharSequence>>(); private static ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache = new ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>>(); private static ArrayMap<ResourceName, WeakReference<CharSequence>> sStringCache = new ArrayMap<ResourceName, WeakReference<CharSequence>>(); }
core/java/android/app/LoadedApk.java +32 −36 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.app; import android.util.ArrayMap; import com.android.internal.util.ArrayUtils; import android.content.BroadcastReceiver; Loading Loading @@ -49,8 +50,6 @@ import java.io.InputStream; import java.lang.ref.WeakReference; import java.net.URL; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; final class IntentReceiverLeaked extends AndroidRuntimeException { public IntentReceiverLeaked(String msg) { Loading Loading @@ -89,14 +88,14 @@ public final class LoadedApk { private ClassLoader mClassLoader; private Application mApplication; private final HashMap<Context, HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>> mReceivers = new HashMap<Context, HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>>(); private final HashMap<Context, HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>> mUnregisteredReceivers = new HashMap<Context, HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>>(); private final HashMap<Context, HashMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices = new HashMap<Context, HashMap<ServiceConnection, LoadedApk.ServiceDispatcher>>(); private final HashMap<Context, HashMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mUnboundServices = new HashMap<Context, HashMap<ServiceConnection, LoadedApk.ServiceDispatcher>>(); private final ArrayMap<Context, ArrayMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers = new ArrayMap<Context, ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>>(); private final ArrayMap<Context, ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>> mUnregisteredReceivers = new ArrayMap<Context, ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>>(); private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices = new ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>>(); private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mUnboundServices = new ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>>(); int mClientCount = 0; Loading Loading @@ -540,12 +539,11 @@ public final class LoadedApk { public void removeContextRegistrations(Context context, String who, String what) { final boolean reportRegistrationLeaks = StrictMode.vmRegistrationLeaksEnabled(); HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> rmap = ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> rmap = mReceivers.remove(context); if (rmap != null) { Iterator<LoadedApk.ReceiverDispatcher> it = rmap.values().iterator(); while (it.hasNext()) { LoadedApk.ReceiverDispatcher rd = it.next(); for (int i=0; i<rmap.size(); i++) { LoadedApk.ReceiverDispatcher rd = rmap.valueAt(i); IntentReceiverLeaked leak = new IntentReceiverLeaked( what + " " + who + " has leaked IntentReceiver " + rd.getIntentReceiver() + " that was " + Loading @@ -566,12 +564,11 @@ public final class LoadedApk { } mUnregisteredReceivers.remove(context); //Slog.i(TAG, "Receiver registrations: " + mReceivers); HashMap<ServiceConnection, LoadedApk.ServiceDispatcher> smap = ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> smap = mServices.remove(context); if (smap != null) { Iterator<LoadedApk.ServiceDispatcher> it = smap.values().iterator(); while (it.hasNext()) { LoadedApk.ServiceDispatcher sd = it.next(); for (int i=0; i<smap.size(); i++) { LoadedApk.ServiceDispatcher sd = smap.valueAt(i); ServiceConnectionLeaked leak = new ServiceConnectionLeaked( what + " " + who + " has leaked ServiceConnection " + sd.getServiceConnection() + " that was originally bound here"); Loading @@ -598,7 +595,7 @@ public final class LoadedApk { Instrumentation instrumentation, boolean registered) { synchronized (mReceivers) { LoadedApk.ReceiverDispatcher rd = null; HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null; ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null; if (registered) { map = mReceivers.get(context); if (map != null) { Loading @@ -610,7 +607,7 @@ public final class LoadedApk { instrumentation, registered); if (registered) { if (map == null) { map = new HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>(); map = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>(); mReceivers.put(context, map); } map.put(r, rd); Loading @@ -626,7 +623,7 @@ public final class LoadedApk { public IIntentReceiver forgetReceiverDispatcher(Context context, BroadcastReceiver r) { synchronized (mReceivers) { HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = mReceivers.get(context); ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = mReceivers.get(context); LoadedApk.ReceiverDispatcher rd = null; if (map != null) { rd = map.get(r); Loading @@ -636,10 +633,10 @@ public final class LoadedApk { mReceivers.remove(context); } if (r.getDebugUnregister()) { HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> holder ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> holder = mUnregisteredReceivers.get(context); if (holder == null) { holder = new HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>(); holder = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>(); mUnregisteredReceivers.put(context, holder); } RuntimeException ex = new IllegalArgumentException( Loading @@ -652,7 +649,7 @@ public final class LoadedApk { return rd.getIIntentReceiver(); } } HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> holder ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> holder = mUnregisteredReceivers.get(context); if (holder != null) { rd = holder.get(r); Loading Loading @@ -868,14 +865,14 @@ public final class LoadedApk { Context context, Handler handler, int flags) { synchronized (mServices) { LoadedApk.ServiceDispatcher sd = null; HashMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context); ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context); if (map != null) { sd = map.get(c); } if (sd == null) { sd = new ServiceDispatcher(c, context, handler, flags); if (map == null) { map = new HashMap<ServiceConnection, LoadedApk.ServiceDispatcher>(); map = new ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>(); mServices.put(context, map); } map.put(c, sd); Loading @@ -889,7 +886,7 @@ public final class LoadedApk { public final IServiceConnection forgetServiceDispatcher(Context context, ServiceConnection c) { synchronized (mServices) { HashMap<ServiceConnection, LoadedApk.ServiceDispatcher> map ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context); LoadedApk.ServiceDispatcher sd = null; if (map != null) { Loading @@ -901,10 +898,10 @@ public final class LoadedApk { mServices.remove(context); } if ((sd.getFlags()&Context.BIND_DEBUG_UNBIND) != 0) { HashMap<ServiceConnection, LoadedApk.ServiceDispatcher> holder ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> holder = mUnboundServices.get(context); if (holder == null) { holder = new HashMap<ServiceConnection, LoadedApk.ServiceDispatcher>(); holder = new ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>(); mUnboundServices.put(context, holder); } RuntimeException ex = new IllegalArgumentException( Loading @@ -916,7 +913,7 @@ public final class LoadedApk { return sd.getIServiceConnection(); } } HashMap<ServiceConnection, LoadedApk.ServiceDispatcher> holder ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> holder = mUnboundServices.get(context); if (holder != null) { sd = holder.get(c); Loading Loading @@ -969,8 +966,8 @@ public final class LoadedApk { } } private final HashMap<ComponentName, ServiceDispatcher.ConnectionInfo> mActiveConnections = new HashMap<ComponentName, ServiceDispatcher.ConnectionInfo>(); private final ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo> mActiveConnections = new ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo>(); ServiceDispatcher(ServiceConnection conn, Context context, Handler activityThread, int flags) { Loading Loading @@ -1000,9 +997,8 @@ public final class LoadedApk { void doForget() { synchronized(this) { Iterator<ServiceDispatcher.ConnectionInfo> it = mActiveConnections.values().iterator(); while (it.hasNext()) { ServiceDispatcher.ConnectionInfo ci = it.next(); for (int i=0; i<mActiveConnections.size(); i++) { ServiceDispatcher.ConnectionInfo ci = mActiveConnections.valueAt(i); ci.binder.unlinkToDeath(ci.deathMonitor, 0); } mActiveConnections.clear(); Loading
core/java/android/app/ResourcesManager.java +9 −16 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package android.app; import static android.app.ActivityThread.DEBUG_CONFIGURATION; import android.app.ApplicationPackageManager; import android.content.pm.ActivityInfo; import android.content.res.AssetManager; import android.content.res.CompatibilityInfo; Loading @@ -34,10 +33,7 @@ import android.view.Display; import android.view.DisplayAdjustments; import java.lang.ref.WeakReference; import java.util.HashMap; import java.util.Iterator; import java.util.Locale; import java.util.Map; /** @hide */ public class ResourcesManager { Loading @@ -46,8 +42,8 @@ public class ResourcesManager { static final boolean DEBUG_STATS = true; private static ResourcesManager sResourcesManager; final HashMap<ResourcesKey, WeakReference<Resources> > mActiveResources = new HashMap<ResourcesKey, WeakReference<Resources> >(); final ArrayMap<ResourcesKey, WeakReference<Resources> > mActiveResources = new ArrayMap<ResourcesKey, WeakReference<Resources> >(); final ArrayMap<DisplayAdjustments, DisplayMetrics> mDefaultDisplayMetrics = new ArrayMap<DisplayAdjustments, DisplayMetrics>(); Loading Loading @@ -257,19 +253,16 @@ public class ResourcesManager { Configuration tmpConfig = null; Iterator<Map.Entry<ResourcesKey, WeakReference<Resources>>> it = mActiveResources.entrySet().iterator(); while (it.hasNext()) { Map.Entry<ResourcesKey, WeakReference<Resources>> entry = it.next(); Resources r = entry.getValue().get(); for (int i=mActiveResources.size()-1; i>=0; i--) { ResourcesKey key = mActiveResources.keyAt(i); Resources r = mActiveResources.valueAt(i).get(); if (r != null) { if (DEBUG_CONFIGURATION) Slog.v(TAG, "Changing resources " + r + " config to: " + config); int displayId = entry.getKey().mDisplayId; int displayId = key.mDisplayId; boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY); DisplayMetrics dm = defaultDisplayMetrics; ResourcesKey resourcesKey = entry.getKey(); final boolean hasOverrideConfiguration = resourcesKey.hasOverrideConfiguration(); final boolean hasOverrideConfiguration = key.hasOverrideConfiguration(); if (!isDefaultDisplay || hasOverrideConfiguration) { if (tmpConfig == null) { tmpConfig = new Configuration(); Loading @@ -280,7 +273,7 @@ public class ResourcesManager { applyNonDefaultDisplayMetricsToConfigurationLocked(dm, tmpConfig); } if (hasOverrideConfiguration) { tmpConfig.updateFrom(resourcesKey.mOverrideConfiguration); tmpConfig.updateFrom(key.mOverrideConfiguration); } r.updateConfiguration(tmpConfig, dm, compat); } else { Loading @@ -290,7 +283,7 @@ public class ResourcesManager { // + " " + r + ": " + r.getConfiguration()); } else { //Slog.i(TAG, "Removing old resources " + v.getKey()); it.remove(); mActiveResources.removeAt(i); } } Loading