Skip to content

Commit 65b2561

Browse files
Dianne HackbornAndroid (Google) Code Review
authored andcommitted
Merge "Fix issue #2643754: Launcher is caching widget layouts for too long" into froyo
2 parents c9dc109 + 4416c3d commit 65b2561

File tree

5 files changed

+106
-85
lines changed

5 files changed

+106
-85
lines changed

core/java/android/app/ActivityThread.java

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ Resources getTopLevelResources(String resDir, CompatibilityInfo compInfo) {
194194
}
195195
WeakReference<Resources> wr = mActiveResources.get(key);
196196
r = wr != null ? wr.get() : null;
197+
//if (r != null) Slog.i(TAG, "isUpToDate " + resDir + ": " + r.getAssets().isUpToDate());
197198
if (r != null && r.getAssets().isUpToDate()) {
198199
if (false) {
199200
Slog.w(TAG, "Returning cached resources " + r + " " + resDir
@@ -1752,6 +1753,10 @@ public void getMemoryInfo(Debug.MemoryInfo outInfo) {
17521753
Debug.getMemoryInfo(outInfo);
17531754
}
17541755

1756+
public void dispatchPackageBroadcast(int cmd, String[] packages) {
1757+
queueOrSendMessage(H.DISPATCH_PACKAGE_BROADCAST, packages, cmd);
1758+
}
1759+
17551760
@Override
17561761
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
17571762
long nativeMax = Debug.getNativeHeapSize() / 1024;
@@ -1976,6 +1981,7 @@ private H() {
19761981
public static final int SUICIDE = 130;
19771982
public static final int REMOVE_PROVIDER = 131;
19781983
public static final int ENABLE_JIT = 132;
1984+
public static final int DISPATCH_PACKAGE_BROADCAST = 133;
19791985
String codeToString(int code) {
19801986
if (localLOGV) {
19811987
switch (code) {
@@ -2012,6 +2018,7 @@ String codeToString(int code) {
20122018
case SUICIDE: return "SUICIDE";
20132019
case REMOVE_PROVIDER: return "REMOVE_PROVIDER";
20142020
case ENABLE_JIT: return "ENABLE_JIT";
2021+
case DISPATCH_PACKAGE_BROADCAST: return "DISPATCH_PACKAGE_BROADCAST";
20152022
}
20162023
}
20172024
return "(unknown)";
@@ -2132,6 +2139,9 @@ public void handleMessage(Message msg) {
21322139
case ENABLE_JIT:
21332140
ensureJitEnabled();
21342141
break;
2142+
case DISPATCH_PACKAGE_BROADCAST:
2143+
handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj);
2144+
break;
21352145
}
21362146
}
21372147

@@ -2239,16 +2249,16 @@ public boolean equals(Object obj) {
22392249
// XXX For now we keep around information about all packages we have
22402250
// seen, not removing entries from this map.
22412251
final HashMap<String, WeakReference<PackageInfo>> mPackages
2242-
= new HashMap<String, WeakReference<PackageInfo>>();
2252+
= new HashMap<String, WeakReference<PackageInfo>>();
22432253
final HashMap<String, WeakReference<PackageInfo>> mResourcePackages
2244-
= new HashMap<String, WeakReference<PackageInfo>>();
2254+
= new HashMap<String, WeakReference<PackageInfo>>();
22452255
Display mDisplay = null;
22462256
DisplayMetrics mDisplayMetrics = null;
2247-
HashMap<ResourcesKey, WeakReference<Resources> > mActiveResources
2248-
= new HashMap<ResourcesKey, WeakReference<Resources> >();
2257+
final HashMap<ResourcesKey, WeakReference<Resources> > mActiveResources
2258+
= new HashMap<ResourcesKey, WeakReference<Resources> >();
22492259
final ArrayList<ActivityRecord> mRelaunchingActivities
22502260
= new ArrayList<ActivityRecord>();
2251-
Configuration mPendingConfiguration = null;
2261+
Configuration mPendingConfiguration = null;
22522262

22532263
// The lock of mProviderMap protects the following variables.
22542264
final HashMap<String, ProviderRecord> mProviderMap
@@ -2271,6 +2281,8 @@ public final PackageInfo getPackageInfo(String packageName, int flags) {
22712281
}
22722282
PackageInfo packageInfo = ref != null ? ref.get() : null;
22732283
//Slog.i(TAG, "getPackageInfo " + packageName + ": " + packageInfo);
2284+
//if (packageInfo != null) Slog.i(TAG, "isUptoDate " + packageInfo.mResDir
2285+
// + ": " + packageInfo.mResources.getAssets().isUpToDate());
22742286
if (packageInfo != null && (packageInfo.mResources == null
22752287
|| packageInfo.mResources.getAssets().isUpToDate())) {
22762288
if (packageInfo.isSecurityViolation()
@@ -2358,21 +2370,6 @@ private final PackageInfo getPackageInfo(ApplicationInfo aInfo,
23582370
}
23592371
}
23602372

2361-
public final boolean hasPackageInfo(String packageName) {
2362-
synchronized (mPackages) {
2363-
WeakReference<PackageInfo> ref;
2364-
ref = mPackages.get(packageName);
2365-
if (ref != null && ref.get() != null) {
2366-
return true;
2367-
}
2368-
ref = mResourcePackages.get(packageName);
2369-
if (ref != null && ref.get() != null) {
2370-
return true;
2371-
}
2372-
return false;
2373-
}
2374-
}
2375-
23762373
ActivityThread() {
23772374
}
23782375

@@ -4054,6 +4051,31 @@ final void handleProfilerControl(boolean start, ProfilerControlData pcd) {
40544051
}
40554052
}
40564053

4054+
final void handleDispatchPackageBroadcast(int cmd, String[] packages) {
4055+
boolean hasPkgInfo = false;
4056+
if (packages != null) {
4057+
for (int i=packages.length-1; i>=0; i--) {
4058+
//Slog.i(TAG, "Cleaning old package: " + packages[i]);
4059+
if (!hasPkgInfo) {
4060+
WeakReference<PackageInfo> ref;
4061+
ref = mPackages.get(packages[i]);
4062+
if (ref != null && ref.get() != null) {
4063+
hasPkgInfo = true;
4064+
} else {
4065+
ref = mResourcePackages.get(packages[i]);
4066+
if (ref != null && ref.get() != null) {
4067+
hasPkgInfo = true;
4068+
}
4069+
}
4070+
}
4071+
mPackages.remove(packages[i]);
4072+
mResourcePackages.remove(packages[i]);
4073+
}
4074+
}
4075+
ContextImpl.ApplicationPackageManager.handlePackageBroadcast(cmd, packages,
4076+
hasPkgInfo);
4077+
}
4078+
40574079
final void handleLowMemory() {
40584080
ArrayList<ComponentCallbacks> callbacks
40594081
= new ArrayList<ComponentCallbacks>();

core/java/android/app/ApplicationThreadNative.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,15 @@ public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
393393
mi.writeToParcel(reply, 0);
394394
return true;
395395
}
396+
397+
case DISPATCH_PACKAGE_BROADCAST_TRANSACTION:
398+
{
399+
data.enforceInterface(IApplicationThread.descriptor);
400+
int cmd = data.readInt();
401+
String[] packages = data.readStringArray();
402+
dispatchPackageBroadcast(cmd, packages);
403+
return true;
404+
}
396405
}
397406

398407
return super.onTransact(code, data, reply, flags);
@@ -806,5 +815,16 @@ public void getMemoryInfo(Debug.MemoryInfo outInfo) throws RemoteException {
806815
data.recycle();
807816
reply.recycle();
808817
}
818+
819+
public void dispatchPackageBroadcast(int cmd, String[] packages) throws RemoteException {
820+
Parcel data = Parcel.obtain();
821+
data.writeInterfaceToken(IApplicationThread.descriptor);
822+
data.writeInt(cmd);
823+
data.writeStringArray(packages);
824+
mRemote.transact(DISPATCH_PACKAGE_BROADCAST_TRANSACTION, data, null,
825+
IBinder.FLAG_ONEWAY);
826+
data.recycle();
827+
828+
}
809829
}
810830

core/java/android/app/ContextImpl.java

Lines changed: 22 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -2244,63 +2244,25 @@ private Drawable getCachedIcon(ResourceName name) {
22442244
return null;
22452245
}
22462246

2247-
private void establishPackageRemovedReceiver() {
2248-
// mContext.registerReceiverInternal() winds up acquiring the
2249-
// main ActivityManagerService.this lock. If we hold our usual
2250-
// sSync global lock at the same time, we impose a required ordering
2251-
// on those two locks, which is not good for deadlock prevention.
2252-
// Use a dedicated lock around initialization of
2253-
// sPackageRemovedReceiver to avoid this.
2254-
synchronized (sPackageRemovedSync) {
2255-
if (sPackageRemovedReceiver == null) {
2256-
sPackageRemovedReceiver = new PackageRemovedReceiver();
2257-
IntentFilter filter = new IntentFilter(
2258-
Intent.ACTION_PACKAGE_REMOVED);
2259-
filter.addDataScheme("package");
2260-
mContext.registerReceiverInternal(sPackageRemovedReceiver,
2261-
filter, null, null, null);
2262-
// Register for events related to sdcard installation.
2263-
IntentFilter sdFilter = new IntentFilter();
2264-
sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
2265-
mContext.registerReceiverInternal(sPackageRemovedReceiver,
2266-
sdFilter, null, null, null);
2267-
}
2268-
}
2269-
}
2270-
22712247
private void putCachedIcon(ResourceName name, Drawable dr) {
2272-
establishPackageRemovedReceiver();
2273-
22742248
synchronized (sSync) {
22752249
sIconCache.put(name, new WeakReference<Drawable>(dr));
22762250
if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable for "
22772251
+ name + ": " + dr);
22782252
}
22792253
}
22802254

2281-
private static final class PackageRemovedReceiver extends BroadcastReceiver {
2282-
@Override
2283-
public void onReceive(Context context, Intent intent) {
2284-
String pkgList[] = null;
2285-
String action = intent.getAction();
2286-
boolean immediateGc = false;
2287-
if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
2288-
pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
2289-
immediateGc = true;
2290-
} else {
2291-
Uri data = intent.getData();
2292-
if (data != null) {
2293-
String ssp = data.getSchemeSpecificPart();
2294-
if (ssp != null) {
2295-
pkgList = new String[] { ssp };
2296-
}
2297-
}
2298-
}
2299-
if (pkgList != null && (pkgList.length > 0)) {
2300-
boolean needCleanup = false;
2301-
boolean hasPkgInfo = false;
2302-
for (String ssp : pkgList) {
2303-
synchronized (sSync) {
2255+
static final void handlePackageBroadcast(int cmd, String[] pkgList,
2256+
boolean hasPkgInfo) {
2257+
boolean immediateGc = false;
2258+
if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) {
2259+
immediateGc = true;
2260+
}
2261+
if (pkgList != null && (pkgList.length > 0)) {
2262+
boolean needCleanup = false;
2263+
for (String ssp : pkgList) {
2264+
synchronized (sSync) {
2265+
if (sIconCache.size() > 0) {
23042266
Iterator<ResourceName> it = sIconCache.keySet().iterator();
23052267
while (it.hasNext()) {
23062268
ResourceName nm = it.next();
@@ -2310,7 +2272,9 @@ public void onReceive(Context context, Intent intent) {
23102272
needCleanup = true;
23112273
}
23122274
}
2313-
it = sStringCache.keySet().iterator();
2275+
}
2276+
if (sStringCache.size() > 0) {
2277+
Iterator<ResourceName> it = sStringCache.keySet().iterator();
23142278
while (it.hasNext()) {
23152279
ResourceName nm = it.next();
23162280
if (nm.packageName.equals(ssp)) {
@@ -2320,22 +2284,19 @@ public void onReceive(Context context, Intent intent) {
23202284
}
23212285
}
23222286
}
2323-
if (!hasPkgInfo) {
2324-
hasPkgInfo = ActivityThread.currentActivityThread().hasPackageInfo(ssp);
2325-
}
23262287
}
2327-
if (needCleanup || hasPkgInfo) {
2328-
if (immediateGc) {
2329-
// Schedule an immediate gc.
2330-
Runtime.getRuntime().gc();
2331-
} else {
2332-
ActivityThread.currentActivityThread().scheduleGcIdler();
2333-
}
2288+
}
2289+
if (needCleanup || hasPkgInfo) {
2290+
if (immediateGc) {
2291+
// Schedule an immediate gc.
2292+
Runtime.getRuntime().gc();
2293+
} else {
2294+
ActivityThread.currentActivityThread().scheduleGcIdler();
23342295
}
23352296
}
23362297
}
23372298
}
2338-
2299+
23392300
private static final class ResourceName {
23402301
final String packageName;
23412302
final int iconId;
@@ -2400,8 +2361,6 @@ private CharSequence getCachedString(ResourceName name) {
24002361
}
24012362

24022363
private void putCachedString(ResourceName name, CharSequence cs) {
2403-
establishPackageRemovedReceiver();
2404-
24052364
synchronized (sSync) {
24062365
sStringCache.put(name, new WeakReference<CharSequence>(cs));
24072366
}
@@ -2665,8 +2624,6 @@ public int getApplicationEnabledSetting(String packageName) {
26652624
private final IPackageManager mPM;
26662625

26672626
private static final Object sSync = new Object();
2668-
private static final Object sPackageRemovedSync = new Object();
2669-
private static BroadcastReceiver sPackageRemovedReceiver;
26702627
private static HashMap<ResourceName, WeakReference<Drawable> > sIconCache
26712628
= new HashMap<ResourceName, WeakReference<Drawable> >();
26722629
private static HashMap<ResourceName, WeakReference<CharSequence> > sStringCache

core/java/android/app/IApplicationThread.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ void profilerControl(boolean start, String path, ParcelFileDescriptor fd)
100100
throws RemoteException;
101101
void setSchedulingGroup(int group) throws RemoteException;
102102
void getMemoryInfo(Debug.MemoryInfo outInfo) throws RemoteException;
103+
static final int PACKAGE_REMOVED = 0;
104+
static final int EXTERNAL_STORAGE_UNAVAILABLE = 1;
105+
void dispatchPackageBroadcast(int cmd, String[] packages) throws RemoteException;
103106

104107
String descriptor = "android.app.IApplicationThread";
105108

@@ -135,4 +138,5 @@ void profilerControl(boolean start, String path, ParcelFileDescriptor fd)
135138
int SCHEDULE_DESTROY_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+30;
136139
int GET_MEMORY_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+31;
137140
int SCHEDULE_SUICIDE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+32;
141+
int DISPATCH_PACKAGE_BROADCAST_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+33;
138142
}

services/java/com/android/server/am/ActivityManagerService.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12269,6 +12269,18 @@ void removeReceiverLocked(ReceiverList rl) {
1226912269
}
1227012270
}
1227112271

12272+
private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
12273+
for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12274+
ProcessRecord r = mLruProcesses.get(i);
12275+
if (r.thread != null) {
12276+
try {
12277+
r.thread.dispatchPackageBroadcast(cmd, packages);
12278+
} catch (RemoteException ex) {
12279+
}
12280+
}
12281+
}
12282+
}
12283+
1227212284
private final int broadcastIntentLocked(ProcessRecord callerApp,
1227312285
String callerPackage, Intent intent, String resolvedType,
1227412286
IIntentReceiver resultTo, int resultCode, String resultData,
@@ -12315,6 +12327,8 @@ private final int broadcastIntentLocked(ProcessRecord callerApp,
1231512327
for (String pkg : list) {
1231612328
forceStopPackageLocked(pkg, -1, false, true, true);
1231712329
}
12330+
sendPackageBroadcastLocked(
12331+
IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
1231812332
}
1231912333
} else {
1232012334
Uri data = intent.getData();
@@ -12324,6 +12338,10 @@ private final int broadcastIntentLocked(ProcessRecord callerApp,
1232412338
forceStopPackageLocked(ssp,
1232512339
intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true);
1232612340
}
12341+
if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
12342+
sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
12343+
new String[] {ssp});
12344+
}
1232712345
}
1232812346
}
1232912347
}

0 commit comments

Comments
 (0)